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: }

Defined functions

burst defined in line 175; used 1 times
cpybrst defined in line 325; used 1 times
main defined in line 48; never used

Defined variables

delim3 defined in line 34; used 3 times
mp defined in line 37; used 34 times
switches defined in line 10; used 3 times

Defined struct's

smsg defined in line 39; used 6 times

Defined macros

HELPSW defined in line 26; never used
INPLSW defined in line 11; never used
NINPLSW defined in line 13; never used
NQIETSW defined in line 18; never used
NVERBSW defined in line 23; never used
QIETSW defined in line 16; never used
S1 defined in line 321; used 3 times
S2 defined in line 322; used 3 times
S3 defined in line 323; used 1 times
VERBSW defined in line 21; never used
Last modified: 1986-04-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1574
Valid CSS Valid XHTML 1.0 Strict