|
|
1.1 ! root 1: /* burst.c - explode digests into individual messages */ ! 2: ! 3: #include "../h/mh.h" ! 4: #include <stdio.h> ! 5: #include <sys/types.h> ! 6: #include <sys/stat.h> ! 7: ! 8: static void burst(), cpybrst(); ! 9: ! 10: /* */ ! 11: ! 12: static struct swit switches[] = { ! 13: #define INPLSW 0 ! 14: "inplace", 0, ! 15: #define NINPLSW 1 ! 16: "noinplace", 0, ! 17: ! 18: #define QIETSW 2 ! 19: "quiet", 0, ! 20: #define NQIETSW 3 ! 21: "noquiet", 0, ! 22: ! 23: #define VERBSW 4 ! 24: "verbose", 0, ! 25: #define NVERBSW 5 ! 26: "noverbose", 0, ! 27: ! 28: #define HELPSW 6 ! 29: "help", 4, ! 30: ! 31: NULL, NULL ! 32: }; ! 33: ! 34: /* */ ! 35: ! 36: static char delim3[] = "-------"; ! 37: ! 38: ! 39: static struct msgs *mp; ! 40: ! 41: struct smsg { ! 42: long s_start; ! 43: long s_stop; ! 44: }; ! 45: ! 46: /* */ ! 47: ! 48: /* ARGSUSED */ ! 49: ! 50: main(argc, argv) ! 51: int argc; ! 52: char **argv; ! 53: { ! 54: int inplace = 0, ! 55: quietsw = 0, ! 56: verbosw = 0, ! 57: msgp = 0, ! 58: hi, ! 59: msgnum; ! 60: char *cp, ! 61: *maildir, ! 62: *folder = NULL, ! 63: buf[100], ! 64: **ap, ! 65: **argp, ! 66: *arguments[MAXARGS], ! 67: *msgs[MAXARGS]; ! 68: struct smsg *smsgs; ! 69: ! 70: invo_name = r1bindex (argv[0], '/'); ! 71: if ((cp = m_find (invo_name)) != NULL) { ! 72: ap = brkstring (cp = getcpy (cp), " ", "\n"); ! 73: ap = copyip (ap, arguments); ! 74: } ! 75: else ! 76: ap = arguments; ! 77: (void) copyip (argv + 1, ap); ! 78: argp = arguments; ! 79: ! 80: /* */ ! 81: ! 82: while (cp = *argp++) { ! 83: if (*cp == '-') ! 84: switch (smatch (++cp, switches)) { ! 85: case AMBIGSW: ! 86: ambigsw (cp, switches); ! 87: done (1); ! 88: case UNKWNSW: ! 89: adios (NULLCP, "-%s unknown\n", cp); ! 90: case HELPSW: ! 91: (void) sprintf (buf, "%s [+folder] [msgs] [switches]", ! 92: invo_name); ! 93: help (buf, switches); ! 94: done (1); ! 95: ! 96: case INPLSW: ! 97: inplace++; ! 98: continue; ! 99: case NINPLSW: ! 100: inplace = 0; ! 101: continue; ! 102: ! 103: case QIETSW: ! 104: quietsw++; ! 105: continue; ! 106: case NQIETSW: ! 107: quietsw = 0; ! 108: continue; ! 109: ! 110: case VERBSW: ! 111: verbosw++; ! 112: continue; ! 113: case NVERBSW: ! 114: verbosw = 0; ! 115: continue; ! 116: } ! 117: if (*cp == '+' || *cp == '@') { ! 118: if (folder) ! 119: adios (NULLCP, "only one folder at a time!"); ! 120: else ! 121: folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF); ! 122: } ! 123: else ! 124: msgs[msgp++] = cp; ! 125: } ! 126: ! 127: /* */ ! 128: ! 129: if (!m_find ("path")) ! 130: free (path ("./", TFOLDER)); ! 131: if (!msgp) ! 132: msgs[msgp++] = "cur"; ! 133: if (!folder) ! 134: folder = m_getfolder (); ! 135: maildir = m_maildir (folder); ! 136: ! 137: if (chdir (maildir) == NOTOK) ! 138: adios (maildir, "unable to change directory to"); ! 139: if (!(mp = m_gmsg (folder))) ! 140: adios (NULLCP, "unable to read folder %s", folder); ! 141: if (mp -> hghmsg == 0) ! 142: adios (NULLCP, "no messages in %s", folder); ! 143: ! 144: for (msgnum = 0; msgnum < msgp; msgnum++) ! 145: if (!m_convert (mp, msgs[msgnum])) ! 146: done (1); ! 147: m_setseq (mp); ! 148: ! 149: smsgs = (struct smsg *) ! 150: calloc ((unsigned) (MAXFOLDER + 2), sizeof *smsgs); ! 151: if (smsgs == NULL) ! 152: adios (NULLCP, "unable to allocate burst storage"); ! 153: ! 154: hi = mp -> hghmsg + 1; ! 155: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 156: if (mp -> msgstats[msgnum] & SELECTED) ! 157: burst (smsgs, msgnum, inplace, quietsw, verbosw); ! 158: ! 159: free ((char *) smsgs); ! 160: ! 161: m_replace (pfolder, folder); ! 162: if (inplace) { ! 163: if (mp -> lowsel != mp -> curmsg) ! 164: m_setcur (mp, mp -> lowsel); ! 165: } ! 166: else ! 167: if (hi <= mp -> hghmsg) ! 168: m_setcur (mp, hi); ! 169: m_sync (mp); ! 170: m_update (); ! 171: ! 172: done (0); ! 173: } ! 174: ! 175: /* */ ! 176: ! 177: static void ! 178: burst(smsgs, msgnum, inplace, quietsw, verbosw) ! 179: register struct smsg *smsgs; ! 180: int msgnum, inplace, quietsw, verbosw; ! 181: { ! 182: int i, ! 183: j, ! 184: ld3, ! 185: wasdlm, ! 186: mode, ! 187: msgp; ! 188: register long pos; ! 189: register char c, ! 190: *msgnam; ! 191: char buffer[BUFSIZ], ! 192: f1[BUFSIZ], ! 193: f2[BUFSIZ], ! 194: f3[BUFSIZ]; ! 195: struct stat st; ! 196: register FILE *in, ! 197: *out; ! 198: ! 199: ld3 = strlen (delim3); ! 200: ! 201: if ((in = fopen (msgnam = m_name (msgnum), "r")) == NULL) ! 202: adios (msgnam, "unable to read message"); ! 203: ! 204: mode = fstat (fileno (in), &st) != NOTOK ? (st.st_mode & 0777) ! 205: : m_gmprot (); ! 206: for (msgp = 1, pos = 0L; msgp <= MAXFOLDER;) { ! 207: while (fgets (buffer, sizeof buffer, in) != NULL ! 208: && buffer[0] == '\n') ! 209: pos += (long) strlen (buffer); ! 210: if (feof (in)) ! 211: break; ! 212: (void) fseek (in, pos, 0); ! 213: smsgs[msgp].s_start = pos; ! 214: ! 215: for (c = NULL; ! 216: fgets (buffer, sizeof buffer, in) != NULL; ! 217: c = buffer[0]) ! 218: if (strncmp (buffer, delim3, ld3) == 0 ! 219: && peekc (in) == '\n' ! 220: && (msgp == 1 || c == '\n')) ! 221: break; ! 222: else ! 223: pos += (long) strlen (buffer); ! 224: ! 225: wasdlm = strncmp (buffer, delim3, ld3) == 0; ! 226: if (smsgs[msgp].s_start != pos) ! 227: smsgs[msgp++].s_stop = c == '\n' && wasdlm ? pos - 1 : pos; ! 228: if (feof (in)) { ! 229: if (wasdlm) { ! 230: smsgs[msgp - 1].s_stop -= ((long) strlen (buffer) + 1); ! 231: msgp++; /* fake "End of XXX Digest" */ ! 232: } ! 233: break; ! 234: } ! 235: pos += (long) strlen (buffer); ! 236: } ! 237: ! 238: /* */ ! 239: ! 240: switch (--msgp) { /* toss "End of XXX Digest" */ ! 241: case 0: ! 242: adios (NULLCP, "burst() botch -- you lose big"); ! 243: ! 244: case 1: ! 245: if (!quietsw) ! 246: admonish (NULLCP, "message %d not in digest format", msgnum); ! 247: (void) fclose (in); ! 248: return; ! 249: ! 250: default: ! 251: if (verbosw) ! 252: printf ("%d message%s exploded from digest %d\n", ! 253: msgp - 1, msgp - 1 != 1 ? "s" : "", msgnum); ! 254: if (msgp == 2) /* XXX */ ! 255: msgp++; ! 256: break; ! 257: } ! 258: ! 259: if ((mp = m_remsg (mp, 0, mp -> hghmsg + msgp)) == NULL) ! 260: adios (NULLCP, "unable to allocate folder storage"); ! 261: ! 262: /* */ ! 263: ! 264: msgp--; ! 265: j = mp -> hghmsg; ! 266: mp -> hghmsg += msgp - 1; ! 267: mp -> nummsg += msgp - 1; ! 268: if (mp -> hghsel > msgnum) ! 269: mp -> hghsel += msgp - 1; ! 270: ! 271: if (inplace && msgp > 1) ! 272: for (i = mp -> hghmsg; j > msgnum; i--, j--) { ! 273: (void) strcpy (f1, m_name (i)); ! 274: (void) strcpy (f2, m_name (j)); ! 275: if (mp -> msgstats[j] & EXISTS) { ! 276: if (verbosw) ! 277: printf ("message %d becomes message %d\n", j, i); ! 278: ! 279: if (rename (f2, f1) == NOTOK) ! 280: admonish (f1, "unable to rename %s to", f2); ! 281: mp -> msgstats[i] = mp -> msgstats[j]; ! 282: mp -> msgstats[j] = NULL; ! 283: mp -> msgflags |= SEQMOD; ! 284: } ! 285: } ! 286: ! 287: mp -> msgstats[msgnum] &= ~SELECTED; ! 288: i = inplace ? msgnum + msgp - 1 : mp -> hghmsg; ! 289: for (j = msgp; j >= (inplace ? 1 : 2); i--, j--) { ! 290: (void) strcpy (f1, m_name (i)); ! 291: (void) strcpy (f2, m_scratch ("", invo_name)); ! 292: if (verbosw && i != msgnum) ! 293: printf ("message %d of digest %d becomes message %d\n", ! 294: j, msgnum, i); ! 295: ! 296: if ((out = fopen (f2, "w")) == NULL) ! 297: adios (f2, "unable to write message"); ! 298: (void) chmod (f2, mode); ! 299: (void) fseek (in, pos = smsgs[j].s_start, 0); ! 300: cpybrst (in, out, msgnam, f2, ! 301: (int) (smsgs[j].s_stop - smsgs[j].s_start)); ! 302: (void) fclose (out); ! 303: ! 304: if (i == msgnum) { ! 305: (void) strcpy (f3, m_backup (f1)); ! 306: if (rename (f1, f3) == NOTOK) ! 307: admonish (f3, "unable to rename %s to", f1); ! 308: } ! 309: if (rename (f2, f1) == NOTOK) ! 310: admonish (f1, "unable to rename %s to", f2); ! 311: mp -> msgstats[i] = mp -> msgstats[msgnum]; ! 312: mp -> msgflags |= SEQMOD; ! 313: } ! 314: ! 315: (void) fclose (in); ! 316: } ! 317: ! 318: ! 319: /* */ ! 320: ! 321: #define S1 0 ! 322: #define S2 1 ! 323: #define S3 2 ! 324: ! 325: static void ! 326: cpybrst(in, out, ifile, ofile, len) ! 327: register FILE *in, *out; ! 328: register char *ifile, *ofile; ! 329: register int len; ! 330: { ! 331: register int c, ! 332: state; ! 333: ! 334: for (state = S1; (c = fgetc (in)) != EOF && len > 0; len--) { ! 335: if (c == NULL) ! 336: continue; ! 337: switch (state) { ! 338: case S1: ! 339: switch (c) { ! 340: case '-': ! 341: state = S3; ! 342: break; ! 343: ! 344: default: ! 345: state = S2; ! 346: case '\n': ! 347: (void) fputc (c, out); ! 348: break; ! 349: } ! 350: break; ! 351: ! 352: case S2: ! 353: switch (c) { ! 354: case '\n': ! 355: state = S1; ! 356: default: ! 357: (void) fputc (c, out); ! 358: break; ! 359: } ! 360: break; ! 361: ! 362: case S3: ! 363: switch (c) { ! 364: case ' ': ! 365: state = S2; ! 366: break; ! 367: ! 368: default: ! 369: state = c == '\n' ? S1 : S2; ! 370: (void) fputc ('-', out); ! 371: (void) fputc (c, out); ! 372: break; ! 373: } ! 374: break; ! 375: } ! 376: } ! 377: ! 378: if (ferror (in)) ! 379: adios (ifile, "error reading"); ! 380: if (ferror (out)) ! 381: adios (ofile, "error writing"); ! 382: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.