Annotation of 43BSD/contrib/mh/uip/burst.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.