Annotation of 43BSDReno/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: 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: }

unix.superglobalmegacorp.com

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