|
|
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: /* */ ! 9: ! 10: static struct swit switches[] = { ! 11: #define INPLSW 0 ! 12: "inplace", 0, ! 13: #define NINPLSW 1 ! 14: "noinplace", 0, ! 15: ! 16: #define QIETSW 2 ! 17: "quiet", 0, ! 18: #define NQIETSW 3 ! 19: "noquiet", 0, ! 20: ! 21: #define VERBSW 4 ! 22: "verbose", 0, ! 23: #define NVERBSW 5 ! 24: "noverbose", 0, ! 25: ! 26: #define HELPSW 6 ! 27: "help", 4, ! 28: ! 29: NULL, NULL ! 30: }; ! 31: ! 32: /* */ ! 33: ! 34: static char delim3[] = "-------"; ! 35: ! 36: ! 37: static struct msgs *mp; ! 38: ! 39: struct smsg { ! 40: long s_start; ! 41: long s_stop; ! 42: }; ! 43: ! 44: /* */ ! 45: ! 46: /* ARGSUSED */ ! 47: ! 48: main (argc, argv) ! 49: int argc; ! 50: char **argv; ! 51: { ! 52: int inplace = 0, ! 53: quietsw = 0, ! 54: verbosw = 0, ! 55: msgp = 0, ! 56: hi, ! 57: msgnum; ! 58: char *cp, ! 59: *maildir, ! 60: *folder = NULL, ! 61: buf[100], ! 62: **ap, ! 63: **argp, ! 64: *arguments[MAXARGS], ! 65: *msgs[MAXARGS]; ! 66: struct smsg *smsgs; ! 67: ! 68: invo_name = r1bindex (argv[0], '/'); ! 69: if ((cp = m_find (invo_name)) != NULL) { ! 70: ap = brkstring (cp = getcpy (cp), " ", "\n"); ! 71: ap = copyip (ap, arguments); ! 72: } ! 73: else ! 74: ap = arguments; ! 75: (void) copyip (argv + 1, ap); ! 76: argp = arguments; ! 77: ! 78: /* */ ! 79: ! 80: while (cp = *argp++) { ! 81: if (*cp == '-') ! 82: switch (smatch (++cp, switches)) { ! 83: case AMBIGSW: ! 84: ambigsw (cp, switches); ! 85: done (1); ! 86: case UNKWNSW: ! 87: adios (NULLCP, "-%s unknown\n", cp); ! 88: case HELPSW: ! 89: (void) sprintf (buf, "%s [+folder] [msgs] [switches]", ! 90: invo_name); ! 91: help (buf, switches); ! 92: done (1); ! 93: ! 94: case INPLSW: ! 95: inplace++; ! 96: continue; ! 97: case NINPLSW: ! 98: inplace = 0; ! 99: continue; ! 100: ! 101: case QIETSW: ! 102: quietsw++; ! 103: continue; ! 104: case NQIETSW: ! 105: quietsw = 0; ! 106: continue; ! 107: ! 108: case VERBSW: ! 109: verbosw++; ! 110: continue; ! 111: case NVERBSW: ! 112: verbosw = 0; ! 113: continue; ! 114: } ! 115: if (*cp == '+' || *cp == '@') { ! 116: if (folder) ! 117: adios (NULLCP, "only one folder at a time!"); ! 118: else ! 119: folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF); ! 120: } ! 121: else ! 122: msgs[msgp++] = cp; ! 123: } ! 124: ! 125: /* */ ! 126: ! 127: if (!m_find ("path")) ! 128: free (path ("./", TFOLDER)); ! 129: if (!msgp) ! 130: msgs[msgp++] = "cur"; ! 131: if (!folder) ! 132: folder = m_getfolder (); ! 133: maildir = m_maildir (folder); ! 134: ! 135: if (chdir (maildir) == NOTOK) ! 136: adios (maildir, "unable to change directory to"); ! 137: if (!(mp = m_gmsg (folder))) ! 138: adios (NULLCP, "unable to read folder %s", folder); ! 139: if (mp -> hghmsg == 0) ! 140: adios (NULLCP, "no messages in %s", folder); ! 141: ! 142: for (msgnum = 0; msgnum < msgp; msgnum++) ! 143: if (!m_convert (mp, msgs[msgnum])) ! 144: done (1); ! 145: m_setseq (mp); ! 146: ! 147: smsgs = (struct smsg *) ! 148: calloc ((unsigned) (MAXFOLDER + 2), sizeof *smsgs); ! 149: if (smsgs == NULL) ! 150: adios (NULLCP, "unable to allocate burst storage"); ! 151: ! 152: hi = mp -> hghmsg + 1; ! 153: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 154: if (mp -> msgstats[msgnum] & SELECTED) ! 155: burst (smsgs, msgnum, inplace, quietsw, verbosw); ! 156: ! 157: free ((char *) smsgs); ! 158: ! 159: m_replace (pfolder, folder); ! 160: if (inplace) { ! 161: if (mp -> lowsel != mp -> curmsg) ! 162: m_setcur (mp, mp -> lowsel); ! 163: } ! 164: else ! 165: if (hi <= mp -> hghmsg) ! 166: m_setcur (mp, hi); ! 167: m_sync (mp); ! 168: m_update (); ! 169: ! 170: done (0); ! 171: } ! 172: ! 173: /* */ ! 174: ! 175: static burst (smsgs, msgnum, inplace, quietsw, verbosw) ! 176: register struct smsg *smsgs; ! 177: int msgnum, ! 178: inplace, ! 179: quietsw, ! 180: 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 cpybrst (in, out, ifile, ofile, len) ! 326: register FILE *in, ! 327: *out; ! 328: register char *ifile, ! 329: *ofile; ! 330: register int len; ! 331: { ! 332: register int c, ! 333: state; ! 334: ! 335: for (state = S1; (c = fgetc (in)) != EOF && len > 0; len--) { ! 336: if (c == NULL) ! 337: continue; ! 338: switch (state) { ! 339: case S1: ! 340: switch (c) { ! 341: case '-': ! 342: state = S3; ! 343: break; ! 344: ! 345: default: ! 346: state = S2; ! 347: case '\n': ! 348: (void) fputc (c, out); ! 349: break; ! 350: } ! 351: break; ! 352: ! 353: case S2: ! 354: switch (c) { ! 355: case '\n': ! 356: state = S1; ! 357: default: ! 358: (void) fputc (c, out); ! 359: break; ! 360: } ! 361: break; ! 362: ! 363: case S3: ! 364: switch (c) { ! 365: case ' ': ! 366: state = S2; ! 367: break; ! 368: ! 369: default: ! 370: state = c == '\n' ? S1 : S2; ! 371: (void) fputc ('-', out); ! 372: (void) fputc (c, out); ! 373: break; ! 374: } ! 375: break; ! 376: } ! 377: } ! 378: ! 379: if (ferror (in)) ! 380: adios (ifile, "error reading"); ! 381: if (ferror (out)) ! 382: adios (ofile, "error writing"); ! 383: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.