Annotation of 43BSDReno/contrib/mh/uip/mshcmds.c, revision 1.1.1.1

1.1       root        1: /* mshcmds.c - command handlers in msh */
                      2: 
                      3: #include "../h/mh.h"
                      4: #include "../h/dropsbr.h"
                      5: #include "../h/formatsbr.h"
                      6: #include "../h/scansbr.h"
                      7: #include "../zotnet/tws.h"
                      8: #include <stdio.h>
                      9: #include "../zotnet/mts.h"
                     10: #include <ctype.h>
                     11: #include <errno.h>
                     12: #include <setjmp.h>
                     13: #include <signal.h>
                     14: #include "../h/mshsbr.h"
                     15: #include <sys/types.h>
                     16: #include <sys/stat.h>
                     17: 
                     18: /*  */
                     19: 
                     20: extern int errno;
                     21: 
                     22:                                /* BURST */
                     23: static char delim3[] = "-------";/* from burst.c */
                     24: 
                     25: 
                     26:                                /* SHOW */
                     27: static int  mhlnum;
                     28: static FILE *mhlfp;
                     29: 
                     30: void clear_screen ();
                     31: 
                     32: static void forw(), rmm(), show(), copy_message(), copy_digest();
                     33: static int burst(), eom_action(), ask(), msgsort(), process();
                     34: static FP mhl_action();
                     35: static struct tws *getws();
                     36: 
                     37: /*  */
                     38: 
                     39: forkcmd (args, pgm)
                     40: char  **args,
                     41:        *pgm;
                     42: {
                     43:     int     child_id;
                     44:     char   *vec[MAXARGS];
                     45: 
                     46:     vec[0] = r1bindex (pgm, '/');
                     47:     (void) copyip (args, vec + 1);
                     48: 
                     49:     if (fmsh) {
                     50:        (void) m_delete (pfolder);
                     51:        m_replace (pfolder, fmsh);
                     52:        m_sync (mp);
                     53:        m_update ();
                     54:     }
                     55:     (void) fflush (stdout);
                     56:     switch (child_id = fork ()) {
                     57:        case NOTOK:
                     58:            advise ("fork", "unable to");
                     59:            return;
                     60: 
                     61:        case OK:
                     62:            closefds (3);
                     63:            (void) signal (SIGINT, istat);
                     64:            (void) signal (SIGQUIT, qstat);
                     65: 
                     66:            execvp (pgm, vec);
                     67:            fprintf (stderr, "unable to exec ");
                     68:            perror (cmd_name);
                     69:            _exit (1);
                     70: 
                     71:        default:
                     72:            (void) pidXwait (child_id, NULLCP);
                     73:            break;
                     74:     }
                     75:     if (fmsh) {                        /* assume the worst case */
                     76:        mp -> msgflags |= MODIFIED;
                     77:        modified++;
                     78:     }
                     79: }
                     80: 
                     81: /*  */
                     82: 
                     83: static struct swit distswit[] = {
                     84: #define        DIANSW  0
                     85:     "annotate", 0,
                     86: #define        DINANSW 1
                     87:     "noannotate", 0,
                     88: #define        DIDFSW  2
                     89:     "draftfolder +folder", 0,
                     90: #define        DIDMSW  3
                     91:     "draftmessage msg", 0,
                     92: #define        DINDFSW 4
                     93:     "nodraftfolder", 0,
                     94: #define        DIEDTSW 5
                     95:     "editor editor", 0,
                     96: #define        DINEDSW 6
                     97:     "noedit", 0,
                     98: #define        DIFRMSW 7
                     99:     "form formfile", 0,
                    100: #define        DIINSW  8
                    101:     "inplace", 0,
                    102: #define        DININSW 9
                    103:     "noinplace", 0,
                    104: #define        DIWHTSW 10
                    105:     "whatnowproc program", 0,
                    106: #define        DINWTSW 11
                    107:     "nowhatnowproc", 0,
                    108: #define        DIHELP  12
                    109:     "help", 4,
                    110: 
                    111:     NULL, NULL
                    112: };
                    113: 
                    114: /*  */
                    115: 
                    116: distcmd (args)
                    117: char  **args;
                    118: {
                    119:     int     vecp = 1;
                    120:     char   *cp,
                    121:            *msg = NULL,
                    122:             buf[BUFSIZ],
                    123:            *vec[MAXARGS];
                    124: 
                    125:     if (fmsh) {
                    126:        forkcmd (args, cmd_name);
                    127:        return;
                    128:     }
                    129: 
                    130:     while (cp = *args++) {
                    131:        if (*cp == '-')
                    132:            switch (smatch (++cp, distswit)) {
                    133:                case AMBIGSW:
                    134:                    ambigsw (cp, distswit);
                    135:                    return;
                    136:                case UNKWNSW:
                    137:                    fprintf (stderr, "-%s unknown\n", cp);
                    138:                    return;
                    139:                case DIHELP:
                    140:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                    141:                    help (buf, distswit);
                    142:                    return;
                    143: 
                    144:                case DIANSW:    /* not implemented */
                    145:                case DINANSW:
                    146:                case DIINSW:
                    147:                case DININSW:
                    148:                    continue;
                    149: 
                    150:                case DINDFSW:
                    151:                case DINEDSW:
                    152:                case DINWTSW:
                    153:                    vec[vecp++] = --cp;
                    154:                    continue;
                    155: 
                    156:                case DIEDTSW:
                    157:                case DIFRMSW:
                    158:                case DIDFSW:
                    159:                case DIDMSW:
                    160:                case DIWHTSW:
                    161:                    vec[vecp++] = --cp;
                    162:                    if (!(cp = *args++) || *cp == '-') {
                    163:                        advise (NULLCP, "missing argument to %s", args[-2]);
                    164:                        return;
                    165:                    }
                    166:                    vec[vecp++] = cp;
                    167:                    continue;
                    168:            }
                    169:        if (*cp == '+' || *cp == '@') {
                    170:            advise (NULLCP, "sorry, no folders allowed!");
                    171:            return;
                    172:        }
                    173:        else
                    174:            if (msg) {
                    175:                advise (NULLCP, "only one message at a time!");
                    176:                return;
                    177:            }
                    178:            else
                    179:                msg = cp;
                    180:     }
                    181: 
                    182:     vec[0] = cmd_name;
                    183:     vec[vecp++] = "-file";
                    184:     vec[vecp] = NULL;
                    185:     if (!msg)
                    186:        msg = "cur";
                    187:     if (!m_convert (mp, msg))
                    188:        return;
                    189:     m_setseq (mp);
                    190: 
                    191:     if (mp -> numsel > 1) {
                    192:        advise (NULLCP, "only one message at a time!");
                    193:        return;
                    194:     }
                    195:     (void) process (mp -> hghsel, cmd_name, vecp, vec);
                    196:     m_setcur (mp, mp -> hghsel);
                    197: }
                    198: 
                    199: /*  */
                    200: 
                    201: static struct swit explswit[] = {
                    202: #define        EXINSW  0
                    203:     "inplace", 0,
                    204: #define        EXNINSW 1
                    205:     "noinplace", 0,
                    206: #define        EXQISW  2
                    207:     "quiet", 0,
                    208: #define        EXNQISW 3
                    209:     "noquiet", 0,
                    210: #define        EXVBSW  4
                    211:     "verbose", 0,
                    212: #define        EXNVBSW 5
                    213:     "noverbose", 0,
                    214: #define        EXHELP  6
                    215:     "help", 4,
                    216: 
                    217:     NULL, NULL
                    218: };
                    219: 
                    220: /*  */
                    221: 
                    222: explcmd (args)
                    223: char  **args;
                    224: {
                    225:     int     inplace = 0,
                    226:             quietsw = 0,
                    227:             verbosw = 0,
                    228:             msgp = 0,
                    229:             hi,
                    230:             msgnum;
                    231:     char   *cp,
                    232:             buf[BUFSIZ],
                    233:            *msgs[MAXARGS];
                    234:     struct Msg *smsgs;
                    235: 
                    236:     if (fmsh) {
                    237:        forkcmd (args, cmd_name);
                    238:        return;
                    239:     }
                    240: 
                    241:     while (cp = *args++) {
                    242:        if (*cp == '-')
                    243:            switch (smatch (++cp, explswit)) {
                    244:                case AMBIGSW:
                    245:                    ambigsw (cp, explswit);
                    246:                    return;
                    247:                case UNKWNSW:
                    248:                    fprintf (stderr, "-%s unknown\n", cp);
                    249:                    return;
                    250:                case EXHELP:
                    251:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                    252:                    help (buf, explswit);
                    253:                    return;
                    254: 
                    255:                case EXINSW:
                    256:                    inplace++;
                    257:                    continue;
                    258:                case EXNINSW:
                    259:                    inplace = 0;
                    260:                    continue;
                    261:                case EXQISW:
                    262:                    quietsw++;
                    263:                    continue;
                    264:                case EXNQISW:
                    265:                    quietsw = 0;
                    266:                    continue;
                    267:                case EXVBSW:
                    268:                    verbosw++;
                    269:                    continue;
                    270:                case EXNVBSW:
                    271:                    verbosw = 0;
                    272:                    continue;
                    273:            }
                    274:        if (*cp == '+' || *cp == '@') {
                    275:            advise (NULLCP, "sorry, no folders allowed!");
                    276:            return;
                    277:        }
                    278:        else
                    279:            msgs[msgp++] = cp;
                    280:     }
                    281: 
                    282:     if (!msgp)
                    283:        msgs[msgp++] = "cur";
                    284:     for (msgnum = 0; msgnum < msgp; msgnum++)
                    285:        if (!m_convert (mp, msgs[msgnum]))
                    286:            return;
                    287:     m_setseq (mp);
                    288: 
                    289:     smsgs = (struct Msg *)
                    290:                calloc ((unsigned) (MAXFOLDER + 2), sizeof *smsgs);
                    291:     if (smsgs == NULL)
                    292:        adios (NULLCP, "unable to allocate folder storage");
                    293: 
                    294:     hi = mp -> hghmsg + 1;
                    295:     interrupted = 0;
                    296:     for (msgnum = mp -> lowsel;
                    297:            msgnum <= mp -> hghsel && !interrupted;
                    298:            msgnum++)
                    299:        if (mp -> msgstats[msgnum] & SELECTED)
                    300:            if (burst (smsgs, msgnum, inplace, quietsw, verbosw) != OK)
                    301:                break;
                    302: 
                    303:     free ((char *) smsgs);
                    304: 
                    305:     if (inplace)
                    306:        m_setcur (mp, mp -> lowsel);
                    307:     else
                    308:        if (hi <= mp -> hghmsg)
                    309:            m_setcur (mp, hi);
                    310: 
                    311:     mp -> msgflags |= MODIFIED;
                    312:     modified++;
                    313: }
                    314: 
                    315: /*  */
                    316: 
                    317: static int burst (smsgs, msgnum, inplace, quietsw, verbosw)
                    318: struct Msg *smsgs;
                    319: int     msgnum,
                    320:         inplace,
                    321:         quietsw,
                    322:         verbosw;
                    323: {
                    324:     int     i,
                    325:             j,
                    326:             ld3,
                    327:            wasdlm,
                    328:             msgp;
                    329:     long    pos;
                    330:     char    c,
                    331:             buffer[BUFSIZ];
                    332:     register FILE *zp;
                    333: 
                    334:     ld3 = strlen (delim3);
                    335: 
                    336:     if (Msgs[msgnum].m_scanl) {
                    337:        free (Msgs[msgnum].m_scanl);
                    338:        Msgs[msgnum].m_scanl = NULL;
                    339:     }
                    340: 
                    341:     pos = ftell (zp = msh_ready (msgnum, 1));
                    342:     for (msgp = 1; msgp <= MAXFOLDER;) {
                    343:        while (fgets (buffer, sizeof buffer, zp) != NULL
                    344:                && buffer[0] == '\n'
                    345:                && pos < Msgs[msgnum].m_stop)
                    346:            pos += (long) strlen (buffer);
                    347:        if (feof (zp) || pos >= Msgs[msgnum].m_stop)
                    348:            break;
                    349:        (void) fseek (zp, pos, 0);
                    350:        smsgs[msgp].m_start = pos;
                    351: 
                    352:        for (c = NULL;
                    353:                fgets (buffer, sizeof buffer, zp) != NULL
                    354:                && pos < Msgs[msgnum].m_stop;
                    355:                c = buffer[0])
                    356:            if (strncmp (buffer, delim3, ld3) == 0
                    357:                    && peekc (zp) == '\n'
                    358:                    && (msgp == 1 || c == '\n'))
                    359:                break;
                    360:            else
                    361:                pos += (long) strlen (buffer);
                    362: 
                    363:        wasdlm = strncmp (buffer, delim3, ld3) == 0;
                    364:        if (smsgs[msgp].m_start != pos)
                    365:            smsgs[msgp++].m_stop = c == '\n' && wasdlm ? pos - 1 : pos;
                    366:        if (feof (zp) || pos >= Msgs[msgnum].m_stop) {
                    367:            if (wasdlm) {
                    368:                smsgs[msgp - 1].m_stop -= ((long) strlen (buffer) + 1);
                    369:                msgp++;         /* fake "End of XXX Digest" */
                    370:            }
                    371:            break;
                    372:        }
                    373:        pos += (long) strlen (buffer);
                    374:     }
                    375: 
                    376:     switch (--msgp) {          /* toss "End of XXX Digest" */
                    377:        case 0:
                    378:            adios (NULLCP, "burst() botch -- you lose big");
                    379: 
                    380:        case 1:
                    381:            if (!quietsw)
                    382:                printf ("message %d not in digest format\n", msgnum);
                    383:            return OK;
                    384: 
                    385:        default:
                    386:            if (verbosw)
                    387:                printf ("%d message%s exploded from digest %d\n",
                    388:                        msgp - 1, msgp - 1 != 1 ? "s" : "", msgnum);
                    389:            if (msgp == 2)
                    390:                msgp++;
                    391:            break;
                    392:     }
                    393: 
                    394:     msgp--;
                    395:     if ((i = msgp + mp -> hghmsg) > MAXFOLDER) {
                    396:        advise (NULLCP, "more than %d messages", MAXFOLDER);
                    397:        return NOTOK;
                    398:     }
                    399:     if ((mp = m_remsg (mp, 0, i)) == NULL)
                    400:        adios (NULLCP, "unable to allocate folder storage");
                    401: 
                    402:     j = mp -> hghmsg;
                    403:     mp -> hghmsg += msgp - 1;
                    404:     mp -> nummsg += msgp - 1;
                    405:     if (mp -> hghsel > msgnum)
                    406:        mp -> hghsel += msgp - 1;
                    407: 
                    408:     if (inplace && msgp > 1)
                    409:        for (i = mp -> hghmsg; j > msgnum; i--, j--) {
                    410:            if (verbosw)
                    411:                printf ("message %d becomes message %d\n", j, i);
                    412: 
                    413:            Msgs[i].m_bboard_id = Msgs[j].m_bboard_id;
                    414:            Msgs[i].m_top = Msgs[j].m_top;
                    415:            Msgs[i].m_start = Msgs[j].m_start;
                    416:            Msgs[i].m_stop = Msgs[j].m_stop;
                    417:            Msgs[i].m_scanl = NULL;
                    418:            if (Msgs[j].m_scanl) {
                    419:                free (Msgs[j].m_scanl);
                    420:                Msgs[j].m_scanl = NULL;
                    421:            }
                    422:            mp -> msgstats[i] = mp -> msgstats[j];
                    423:        }
                    424: 
                    425:     if (Msgs[msgnum].m_bboard_id == 0)
                    426:        (void) readid (msgnum);
                    427: 
                    428:     mp -> msgstats[msgnum] &= ~SELECTED;
                    429:     i = inplace ? msgnum + msgp - 1 : mp -> hghmsg;
                    430:     for (j = msgp; j >= (inplace ? 1 : 2); i--, j--) {
                    431:        if (verbosw && i != msgnum)
                    432:            printf ("message %d of digest %d becomes message %d\n",
                    433:                    j, msgnum, i);
                    434: 
                    435:        Msgs[i].m_bboard_id = Msgs[msgnum].m_bboard_id;
                    436:        Msgs[i].m_top = Msgs[j].m_top;
                    437:        Msgs[i].m_start = smsgs[j].m_start;
                    438:        Msgs[i].m_stop = smsgs[j].m_stop;
                    439:        Msgs[i].m_scanl = NULL;
                    440:        mp -> msgstats[i] = mp -> msgstats[msgnum];
                    441:     }
                    442: 
                    443:     return OK;
                    444: }
                    445: 
                    446: /*  */
                    447: 
                    448: static struct swit fileswit[] = {
                    449: #define        FIDRFT  0
                    450:     "draft", 0,
                    451: #define        FILINK  1
                    452:     "link", 0,
                    453: #define        FINLINK 2
                    454:     "nolink", 0,
                    455: #define        FIPRES  3
                    456:     "preserve", 0,
                    457: #define FINPRES        4
                    458:     "nopreserve", 0,
                    459: #define        FISRC   5
                    460:     "src +folder", 0,
                    461: #define        FIFILE  6
                    462:     "file file", 0,
                    463: #define        FIHELP  7
                    464:     "help", 4,
                    465: 
                    466:     NULL, NULL
                    467: };
                    468: 
                    469: /*  */
                    470: 
                    471: filecmd (args)
                    472: char  **args;
                    473: {
                    474:     int            linksw = 0,
                    475:            msgp = 0,
                    476:             vecp = 1,
                    477:            i,
                    478:             msgnum;
                    479:     char   *cp,
                    480:             buf[BUFSIZ],
                    481:            *msgs[MAXARGS],
                    482:            *vec[MAXARGS];
                    483: 
                    484:     if (fmsh) {
                    485:        forkcmd (args, cmd_name);
                    486:        return;
                    487:     }
                    488: 
                    489:     while (cp = *args++) {
                    490:        if (*cp == '-')
                    491:            switch (i = smatch (++cp, fileswit)) {
                    492:                case AMBIGSW:
                    493:                    ambigsw (cp, fileswit);
                    494:                    return;
                    495:                case UNKWNSW:
                    496:                    fprintf (stderr, "-%s unknown\n", cp);
                    497:                    return;
                    498:                case FIHELP:
                    499:                    (void) sprintf (buf, "%s +folder... [msgs] [switches]",
                    500:                            cmd_name);
                    501:                    help (buf, fileswit);
                    502:                    return;
                    503: 
                    504:                case FILINK:
                    505:                    linksw++;
                    506:                    continue;
                    507:                case FINLINK:
                    508:                    linksw = 0;
                    509:                    continue;
                    510: 
                    511:                case FIPRES:
                    512:                case FINPRES:
                    513:                    continue;
                    514: 
                    515:                case FISRC:
                    516:                case FIDRFT:
                    517:                case FIFILE:
                    518:                    advise (NULLCP, "sorry, -%s not allowed!", fileswit[i].sw);
                    519:                    return;
                    520:            }
                    521:        if (*cp == '+' || *cp == '@')
                    522:            vec[vecp++] = cp;
                    523:        else
                    524:            msgs[msgp++] = cp;
                    525:     }
                    526: 
                    527:     vec[0] = cmd_name;
                    528:     vec[vecp++] = "-file";
                    529:     vec[vecp] = NULL;
                    530:     if (!msgp)
                    531:        msgs[msgp++] = "cur";
                    532:     for (msgnum = 0; msgnum < msgp; msgnum++)
                    533:        if (!m_convert (mp, msgs[msgnum]))
                    534:            return;
                    535:     m_setseq (mp);
                    536: 
                    537:     interrupted = 0;
                    538:     for (msgnum = mp -> lowsel;
                    539:            msgnum <= mp -> hghsel && !interrupted;
                    540:            msgnum++)
                    541:        if (mp -> msgstats[msgnum] & SELECTED)
                    542:            if (process (msgnum, fileproc, vecp, vec)) {
                    543:                mp -> msgstats[msgnum] &= ~SELECTED;
                    544:                mp -> numsel--;
                    545:            }
                    546: 
                    547:     if (mp -> numsel != mp -> nummsg || linksw)
                    548:        m_setcur (mp, mp -> hghsel);
                    549:     if (!linksw)
                    550:        rmm ();
                    551: }
                    552: 
                    553: /*  */
                    554: 
                    555: int    filehak (args)
                    556: char  **args;
                    557: {
                    558:     int            result,
                    559:            vecp = 0;
                    560:     char   *cp,
                    561:           *cwd,
                    562:            *vec[MAXARGS];
                    563: 
                    564:     while (cp = *args++) {
                    565:        if (*cp == '-')
                    566:            switch (smatch (++cp, fileswit)) {
                    567:                case AMBIGSW:
                    568:                case UNKWNSW:
                    569:                case FIHELP:
                    570:                    return NOTOK;
                    571: 
                    572:                case FILINK:
                    573:                case FINLINK:
                    574:                case FIPRES:
                    575:                case FINPRES:
                    576:                    continue;
                    577: 
                    578:                case FISRC:
                    579:                case FIDRFT:
                    580:                case FIFILE:
                    581:                    return NOTOK;
                    582:            }
                    583:        if (*cp == '+' || *cp == '@')
                    584:            vec[vecp++] = cp;
                    585:     }
                    586:     vec[vecp] = NULL;
                    587: 
                    588:     result = NOTOK;
                    589:     cwd = NULL;
                    590:     for (vecp = 0; (cp = vec[vecp]) && result == NOTOK; vecp++) {
                    591:        if (cwd == NULL)
                    592:            cwd = getcpy (pwd ());
                    593:        (void) chdir (m_maildir (""));
                    594:        cp = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
                    595:        if (access (m_maildir (cp), 0) == NOTOK)
                    596:            result = OK;
                    597:        free (cp);
                    598:     }
                    599:     if (cwd)
                    600:        (void) chdir (cwd);
                    601: 
                    602:     return result;
                    603: }
                    604: 
                    605: /*  */
                    606: 
                    607: static struct swit foldswit[] = {
                    608: #define        FLALSW  0
                    609:     "all", 0,
                    610: #define        FLFASW  1
                    611:     "fast", 0,
                    612: #define        FLNFASW 2
                    613:     "nofast", 0,
                    614: #define        FLHDSW  3
                    615:     "header", 0,
                    616: #define        FLNHDSW 4
                    617:     "noheader", 0,
                    618: #define        FLPKSW  5
                    619:     "pack", 0,
                    620: #define        FLNPKSW 6
                    621:     "nopack", 0,
                    622: #define        FLRCSW  7
                    623:     "recurse", 0,
                    624: #define        FLNRCSW 8
                    625:     "norecurse", 0,
                    626: #define        FLTLSW  9
                    627:     "total", 0,
                    628: #define        FLNTLSW 10
                    629:     "nototal", 0,
                    630: #define        FLPRSW  11
                    631:     "print", 0,
                    632: #define        FLPUSW  12
                    633:     "push", 0,
                    634: #define        FLPOSW  13
                    635:     "pop", 0,
                    636: #define        FLLISW  14
                    637:     "list", 0,
                    638: #define        FLHELP  15
                    639:     "help", 4,
                    640: 
                    641:     NULL, NULL
                    642: };
                    643: 
                    644: /*  */
                    645: 
                    646: foldcmd (args)
                    647: char  **args;
                    648: {
                    649:     int     fastsw = 0,
                    650:             headersw = 0,
                    651:            packsw = 0,
                    652:            hole,
                    653:            msgnum;
                    654:     char   *cp,
                    655:            *folder = NULL,
                    656:            *msg = NULL,
                    657:             buf[BUFSIZ],
                    658:          **vec = args;
                    659: 
                    660:     if (args == NULL)
                    661:        goto fast;
                    662: 
                    663:     while (cp = *args++) {
                    664:        if (*cp == '-')
                    665:            switch (smatch (++cp, foldswit)) {
                    666:                case AMBIGSW:
                    667:                    ambigsw (cp, foldswit);
                    668:                    return;
                    669:                case UNKWNSW:
                    670:                    fprintf (stderr, "-%s unknown\n", cp);
                    671:                    return;
                    672:                case FLHELP:
                    673:                    (void) sprintf (buf, "%s [+folder] [msg] [switches]",
                    674:                            cmd_name);
                    675:                    help (buf, foldswit);
                    676:                    return;
                    677: 
                    678:                case FLALSW:    /* not implemented */
                    679:                case FLRCSW:
                    680:                case FLNRCSW:
                    681:                case FLTLSW:
                    682:                case FLNTLSW:
                    683:                case FLPRSW:
                    684:                case FLPUSW:
                    685:                case FLPOSW:
                    686:                case FLLISW:
                    687:                    continue;
                    688: 
                    689:                case FLFASW:
                    690:                    fastsw++;
                    691:                    continue;
                    692:                case FLNFASW:
                    693:                    fastsw = 0;
                    694:                    continue;
                    695:                case FLHDSW:
                    696:                    headersw++;
                    697:                    continue;
                    698:                case FLNHDSW:
                    699:                    headersw = 0;
                    700:                    continue;
                    701:                case FLPKSW:
                    702:                    packsw++;
                    703:                    continue;
                    704:                case FLNPKSW:
                    705:                    packsw = 0;
                    706:                    continue;
                    707:            }
                    708:        if (*cp == '+' || *cp == '@')
                    709:            if (folder) {
                    710:                advise (NULLCP, "only one folder at a time!\n");
                    711:                return;
                    712:            }
                    713:            else
                    714:                folder = fmsh ? path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF)
                    715:                            : cp + 1;
                    716:        else
                    717:            if (msg) {
                    718:                advise (NULLCP, "only one message at a time!\n");
                    719:                return;
                    720:            }
                    721:            else
                    722:                msg = cp;
                    723:     }
                    724: 
                    725:     if (folder) {
                    726:        if (*folder == NULL) {
                    727:            advise (NULLCP, "null folder names are not permitted");
                    728:            return;
                    729:        }
                    730:        if (fmsh) {
                    731:            if (access (m_maildir (folder), 04) == NOTOK) {
                    732:                advise (folder, "unable to read");
                    733:                return;
                    734:            }
                    735:        }
                    736:        else {
                    737:            (void) strcpy (buf, folder);
                    738:            if (expand (buf) == NOTOK)
                    739:                return;
                    740:            folder = buf;
                    741:            if (access (folder, 04) == NOTOK) {
                    742:                advise (folder, "unable to read");
                    743:                return;
                    744:            }
                    745:        }
                    746:        m_reset ();
                    747: 
                    748:        if (fmsh)
                    749:            fsetup (folder);
                    750:        else
                    751:            setup (folder);
                    752:        readids (0);
                    753:        display_info (0);
                    754:     }
                    755: 
                    756:     if (msg) {
                    757:        if (!m_convert (mp, msg))
                    758:            return;
                    759:        m_setseq (mp);
                    760: 
                    761:        if (mp -> numsel > 1) {
                    762:            advise (NULLCP, "only one message at a time!");
                    763:            return;
                    764:        }
                    765:        m_setcur (mp, mp -> hghsel);
                    766:     }
                    767: 
                    768:     if (packsw) {
                    769:        if (fmsh) {
                    770:            forkcmd (vec, cmd_name);
                    771:            return;
                    772:        }
                    773: 
                    774:        if (mp -> lowmsg > 1 && (mp = m_remsg (mp, 1, mp -> hghmsg)) == NULL)
                    775:            adios (NULLCP, "unable to allocate folder storage");
                    776:        for (msgnum = mp -> lowmsg, hole = 1; msgnum <= mp -> hghmsg; msgnum++)
                    777:            if (mp -> msgstats[msgnum] & EXISTS) {
                    778:                if (msgnum != hole) {
                    779:                    Msgs[hole].m_bboard_id = Msgs[msgnum].m_bboard_id;
                    780:                    Msgs[hole].m_top = Msgs[msgnum].m_top;
                    781:                    Msgs[hole].m_start = Msgs[msgnum].m_start;
                    782:                    Msgs[hole].m_stop = Msgs[msgnum].m_stop;
                    783:                    Msgs[hole].m_scanl = NULL;
                    784:                    if (Msgs[msgnum].m_scanl) {
                    785:                        free (Msgs[msgnum].m_scanl);
                    786:                        Msgs[msgnum].m_scanl = NULL;
                    787:                    }
                    788:                    mp -> msgstats[hole] = mp -> msgstats[msgnum];
                    789:                    if (mp -> curmsg == msgnum)
                    790:                        m_setcur (mp, hole);
                    791:                }
                    792:                hole++;
                    793:            }
                    794:        if (mp -> nummsg > 0) {
                    795:            mp -> lowmsg = 1;
                    796:            mp -> hghmsg = hole - 1;
                    797:        }
                    798:        mp -> msgflags |= MODIFIED;
                    799:        modified++;
                    800:     }
                    801: 
                    802: fast: ;
                    803:     if (fastsw)
                    804:        printf ("%s\n", fmsh ? fmsh : mp -> foldpath);
                    805:     else {
                    806:        if (headersw)
                    807:            printf ("\t\tFolder  %*s# of messages (%*srange%*s); cur%*smsg\n",
                    808:                DMAXFOLDER, "", DMAXFOLDER - 2, "", DMAXFOLDER - 2, "",
                    809:                DMAXFOLDER - 2, "");
                    810:        printf (args ? "%22s  " : "%s ", fmsh ? fmsh : mp -> foldpath);
                    811:        if (mp -> hghmsg == 0)
                    812:            printf ("has   no messages%*s",
                    813:                    mp -> msgflags & OTHERS ? DMAXFOLDER * 2 + 4 : 0, "");
                    814:        else {
                    815:            printf ("has %*d message%s (%*d-%*d)",
                    816:                    DMAXFOLDER, mp -> nummsg, mp -> nummsg != 1 ? "s" : "",
                    817:                    DMAXFOLDER, mp -> lowmsg, DMAXFOLDER, mp -> hghmsg);
                    818:            if (mp -> curmsg >= mp -> lowmsg
                    819:                    && mp -> curmsg <= mp -> hghmsg)
                    820:                printf ("; cur=%*d", DMAXFOLDER, mp -> curmsg);
                    821:        }
                    822:        printf (".\n");
                    823:     }
                    824: }
                    825: 
                    826: /*  */
                    827: 
                    828: static struct swit forwswit[] = {
                    829: #define        FOANSW  0
                    830:     "annotate", 0,
                    831: #define        FONANSW 1
                    832:     "noannotate", 0,
                    833: #define        FODFSW  2
                    834:     "draftfolder +folder", 0,
                    835: #define        FODMSW  3
                    836:     "draftmessage msg", 0,
                    837: #define        FONDFSW 4
                    838:     "nodraftfolder", 0,
                    839: #define        FOEDTSW 5
                    840:     "editor editor", 0,
                    841: #define        FONEDSW 6
                    842:     "noedit", 0,
                    843: #define        FOFTRSW 7
                    844:     "filter filterfile", 0,
                    845: #define        FOFRMSW 8
                    846:     "form formfile", 0,
                    847: #define        FOFTSW  9
                    848:     "format", 5,
                    849: #define        FONFTSW 10
                    850:     "noformat", 7,
                    851: #define        FOINSW  11
                    852:     "inplace", 0,
                    853: #define        FONINSW 12
                    854:     "noinplace", 0,
                    855: #define        FOWHTSW 13
                    856:     "whatnowproc program", 0,
                    857: #define        FONWTSW 14
                    858:     "nowhatnow", 0,
                    859: #define        FOHELP  15
                    860:     "help", 4,
                    861: 
                    862:     NULL, NULL
                    863: };
                    864: 
                    865: /*  */
                    866: 
                    867: forwcmd (args)
                    868: char  **args;
                    869: {
                    870:     int            msgp = 0,
                    871:             vecp = 1,
                    872:             msgnum;
                    873:     char   *cp,
                    874:            *filter = NULL,
                    875:             buf[BUFSIZ],
                    876:            *msgs[MAXARGS],
                    877:            *vec[MAXARGS];
                    878: 
                    879:     if (fmsh) {
                    880:        forkcmd (args, cmd_name);
                    881:        return;
                    882:     }
                    883: 
                    884:     while (cp = *args++) {
                    885:        if (*cp == '-')
                    886:            switch (smatch (++cp, forwswit)) {
                    887:                case AMBIGSW:
                    888:                    ambigsw (cp, forwswit);
                    889:                    return;
                    890:                case UNKWNSW:
                    891:                    fprintf (stderr, "-%s unknown\n", cp);
                    892:                    return;
                    893:                case FOHELP:
                    894:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                    895:                    help (buf, forwswit);
                    896:                    return;
                    897: 
                    898:                case FOANSW:    /* not implemented */
                    899:                case FONANSW:
                    900:                case FOINSW:
                    901:                case FONINSW:
                    902:                    continue;
                    903: 
                    904:                case FONDFSW:
                    905:                case FONEDSW:
                    906:                case FONWTSW:
                    907:                    vec[vecp++] = --cp;
                    908:                    continue;
                    909: 
                    910:                case FOEDTSW:
                    911:                case FOFRMSW:
                    912:                case FODFSW:
                    913:                case FODMSW:
                    914:                case FOWHTSW:
                    915:                    vec[vecp++] = --cp;
                    916:                    if (!(cp = *args++) || *cp == '-') {
                    917:                        advise (NULLCP, "missing argument to %s", args[-2]);
                    918:                        return;
                    919:                    }
                    920:                    vec[vecp++] = cp;
                    921:                    continue;
                    922:                case FOFTRSW:
                    923:                    if (!(filter = *args++) || *filter == '-') {
                    924:                        advise (NULLCP, "missing argument to %s", args[-2]);
                    925:                        return;
                    926:                    }
                    927:                    continue;
                    928:                case FOFTSW:
                    929:                    if (access (filter = myfilter, 04) == NOTOK) {
                    930:                        advise (filter, "unable to read default filter file");
                    931:                        return;
                    932:                    }
                    933:                    continue;
                    934:                case FONFTSW:
                    935:                    filter = NULL;
                    936:                    continue;
                    937:            }
                    938:        if (*cp == '+' || *cp == '@') {
                    939:            advise (NULLCP, "sorry, no folders allowed!");
                    940:            return;
                    941:        }
                    942:        else
                    943:            msgs[msgp++] = cp;
                    944:     }
                    945: 
                    946:                                        /* foil search of .mh_profile */
                    947:     (void) sprintf (buf, "%sXXXXXX", invo_name);
                    948:     vec[0] = mktemp (buf);
                    949:     vec[vecp++] = "-file";
                    950:     vec[vecp] = NULL;
                    951:     if (!msgp)
                    952:        msgs[msgp++] = "cur";
                    953:     for (msgnum = 0; msgnum < msgp; msgnum++)
                    954:        if (!m_convert (mp, msgs[msgnum]))
                    955:            return;
                    956:     m_setseq (mp);
                    957: 
                    958:     if (filter) {
                    959:        (void) strcpy (buf, filter);
                    960:        if (expand (buf) == NOTOK)
                    961:            return;
                    962:        if (access (filter = getcpy (libpath (buf)), 04) == NOTOK) {
                    963:            advise (filter, "unable to read");
                    964:            free (filter);
                    965:            return;
                    966:        }
                    967:     }
                    968:     forw (cmd_name, filter, vecp, vec);
                    969:     m_setcur (mp, mp -> hghsel);
                    970:     if (filter)
                    971:        free (filter);
                    972: }
                    973: 
                    974: /*  */
                    975: 
                    976: static void forw (proc, filter, vecp, vec)
                    977: int     vecp;
                    978: char   *proc,
                    979:        *filter,
                    980:       **vec;
                    981: {
                    982:     int     i,
                    983:             child_id,
                    984:             msgnum,
                    985:             msgcnt;
                    986:     char    tmpfil[80],
                    987:            *args[MAXARGS];
                    988:     FILE   *out;
                    989: 
                    990:     (void) strcpy (tmpfil, m_tmpfil (invo_name));
                    991:     interrupted = 0;
                    992:     if (filter)
                    993:        switch (child_id = fork ()) {
                    994:            case NOTOK:
                    995:                advise ("fork", "unable to");
                    996:                return;
                    997: 
                    998:            case OK:            /* "trust me" */
                    999:                if (freopen (tmpfil, "w", stdout) == NULL) {
                   1000:                    fprintf (stderr, "unable to create ");
                   1001:                    perror (tmpfil);
                   1002:                    _exit (1);
                   1003:                }
                   1004:                args[0] = r1bindex (mhlproc, '/');
                   1005:                i = 1;
                   1006:                args[i++] = "-forwall";
                   1007:                args[i++] = "-form";
                   1008:                args[i++] = filter;
                   1009:                for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                   1010:                    if (mp -> msgstats[msgnum] & SELECTED)
                   1011:                        args[i++] = getcpy (m_name (msgnum));
                   1012:                args[i] = NULL;
                   1013:                (void) mhlsbr (i, args, mhl_action);
                   1014:                m_eomsbr ((int (*) ()) 0);
                   1015:                (void) fclose (stdout);
                   1016:                _exit (0);
                   1017: 
                   1018:            default:
                   1019:                if (pidXwait (child_id, NULLCP))
                   1020:                    interrupted++;
                   1021:                break;
                   1022:        }
                   1023:     else {
                   1024:        if ((out = fopen (tmpfil, "w")) == NULL) {
                   1025:            advise (tmpfil, "unable to create temporary file");
                   1026:            return;
                   1027:        }
                   1028: 
                   1029:        msgcnt = 1;
                   1030:        for (msgnum = mp -> lowsel;
                   1031:                msgnum <= mp -> hghsel && !interrupted;
                   1032:                msgnum++)
                   1033:            if (mp -> msgstats[msgnum] & SELECTED) {
                   1034:                fprintf (out, "\n\n-------");
                   1035:                if (msgnum == mp -> lowsel)
                   1036:                    fprintf (out, " Forwarded Message%s",
                   1037:                            mp -> numsel > 1 ? "s" : "");
                   1038:                else
                   1039:                    fprintf (out, " Message %d", msgcnt);
                   1040:                fprintf (out, "\n\n");
                   1041:                copy_digest (msgnum, out);
                   1042:                msgcnt++;
                   1043:            }
                   1044: 
                   1045:        fprintf (out, "\n\n------- End of Forwarded Message%s\n",
                   1046:                mp -> numsel > 1 ? "s" : "");
                   1047:        (void) fclose (out);
                   1048:     }
                   1049: 
                   1050:     (void) fflush (stdout);
                   1051:     if (!interrupted)
                   1052:        switch (child_id = fork ()) {
                   1053:            case NOTOK:
                   1054:                advise ("fork", "unable to");
                   1055:                break;
                   1056: 
                   1057:            case OK:
                   1058:                closefds (3);
                   1059:                (void) signal (SIGINT, istat);
                   1060:                (void) signal (SIGQUIT, qstat);
                   1061: 
                   1062:                vec[vecp++] = tmpfil;
                   1063:                vec[vecp] = NULL;
                   1064: 
                   1065:                execvp (proc, vec);
                   1066:                fprintf (stderr, "unable to exec ");
                   1067:                perror (proc);
                   1068:                _exit (1);
                   1069: 
                   1070:            default:
                   1071:                (void) pidXwait (child_id, NULLCP);
                   1072:                break;
                   1073:        }
                   1074: 
                   1075:     (void) unlink (tmpfil);
                   1076: }
                   1077: 
                   1078: /*  */
                   1079: 
                   1080: static char *hlpmsg[] = {
                   1081:     "The %s program emulates many of the commands found in the Rand MH",
                   1082:     "system.  Instead of operating on MH folders, commands to %s concern",
                   1083:     "a single file.",
                   1084:     "",
                   1085:     "To see the list of commands available, just type a ``?'' followed by",
                   1086:     "the RETURN key.  To find out what switches each command takes, type",
                   1087:     "the name of the command followed by ``-help''.  To leave %s, use the",
                   1088:     "``quit'' command.",
                   1089:     "",
                   1090:     "Although a lot of MH commands are found in %s, not all are fully",
                   1091:     "implemented.  %s will always recognize all legal switches for a",
                   1092:     "given command though, and will let you know when you ask for an",
                   1093:     "option that it is unable to perform.",
                   1094:     "",
                   1095:     "Running %s is fun, but using MH from your shell is far superior.",
                   1096:     "After you have familiarized yourself with the MH style by using %s,",
                   1097:     "you should try using MH from the shell.  You can still use %s for",
                   1098:     "message files that aren't in MH format, such as BBoard files.",
                   1099:     NULL
                   1100: };
                   1101: 
                   1102: 
                   1103: /* ARGSUSED */
                   1104: 
                   1105: helpcmd (args)
                   1106: char  **args;
                   1107: {
                   1108:     int     i;
                   1109: 
                   1110:     for (i = 0; hlpmsg[i]; i++) {
                   1111:        printf (hlpmsg[i], invo_name);
                   1112:        (void) putchar ('\n');
                   1113:     }
                   1114: }
                   1115: 
                   1116: /*  */
                   1117: 
                   1118: static struct swit markswit[] = {
                   1119: #define        MADDSW  0
                   1120:     "add", 0,
                   1121: #define        MDELSW  1
                   1122:     "delete", 0,
                   1123: #define        MLSTSW  2
                   1124:     "list", 0,
                   1125: #define        MSEQSW  3
                   1126:     "sequence name", 0,
                   1127: #define        MPUBSW  4
                   1128:     "public", 0,
                   1129: #define        MNPUBSW 5
                   1130:     "nopublic", 0,
                   1131: #define        MZERSW  6
                   1132:     "zero", 0,
                   1133: #define        MNZERSW 7
                   1134:     "nozero", 0,
                   1135: #define        MHELP   8
                   1136:     "help", 4,
                   1137: #define        MDBUGSW 9
                   1138:     "debug", -5,
                   1139: 
                   1140:     NULL, NULL
                   1141: };
                   1142: 
                   1143: /*  */
                   1144: 
                   1145: markcmd (args)
                   1146: char  **args;
                   1147: {
                   1148:     int     addsw = 0,
                   1149:             deletesw = 0,
                   1150:             debugsw = 0,
                   1151:             listsw = 0,
                   1152:             zerosw = 0,
                   1153:             seqp = 0,
                   1154:             msgp = 0,
                   1155:             i,
                   1156:             msgnum;
                   1157:     char   *cp,
                   1158:             buf[BUFSIZ],
                   1159:            *seqs[NATTRS + 1],
                   1160:            *msgs[MAXARGS];
                   1161: 
                   1162:     while (cp = *args++) {
                   1163:        if (*cp == '-')
                   1164:            switch (smatch (++cp, markswit)) {
                   1165:                case AMBIGSW:
                   1166:                    ambigsw (cp, markswit);
                   1167:                    return;
                   1168:                case UNKWNSW:
                   1169:                    fprintf (stderr, "-%s unknown\n", cp);
                   1170:                    return;
                   1171:                case MHELP:
                   1172:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                   1173:                    help (buf, markswit);
                   1174:                    return;
                   1175: 
                   1176:                case MADDSW:
                   1177:                    addsw++;
                   1178:                    deletesw = listsw = 0;
                   1179:                    continue;
                   1180:                case MDELSW:
                   1181:                    deletesw++;
                   1182:                    addsw = listsw = 0;
                   1183:                    continue;
                   1184:                case MLSTSW:
                   1185:                    listsw++;
                   1186:                    addsw = deletesw = 0;
                   1187:                    continue;
                   1188: 
                   1189:                case MSEQSW:
                   1190:                    if (!(cp = *args++) || *cp == '-') {
                   1191:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   1192:                        return;
                   1193:                    }
                   1194:                    if (seqp < NATTRS)
                   1195:                        seqs[seqp++] = cp;
                   1196:                    else {
                   1197:                        advise (NULLCP, "only %d sequences allowed!", NATTRS);
                   1198:                        return;
                   1199:                    }
                   1200:                    continue;
                   1201: 
                   1202:                case MPUBSW:    /* not implemented */
                   1203:                case MNPUBSW:
                   1204:                    continue;
                   1205: 
                   1206:                case MDBUGSW:
                   1207:                    debugsw++;
                   1208:                    continue;
                   1209: 
                   1210:                case MZERSW:
                   1211:                    zerosw++;
                   1212:                    continue;
                   1213:                case MNZERSW:
                   1214:                    zerosw = 0;
                   1215:                    continue;
                   1216:            }
                   1217:        if (*cp == '+' || *cp == '@') {
                   1218:            advise (NULLCP, "sorry, no folders allowed!");
                   1219:            return;
                   1220:        }
                   1221:        else
                   1222:            msgs[msgp++] = cp;
                   1223:     }
                   1224: 
                   1225:     if (!addsw && !deletesw && !listsw)
                   1226:        if (seqp)
                   1227:            addsw++;
                   1228:        else
                   1229:            if (debugsw)
                   1230:                listsw++;
                   1231:            else {
                   1232:                seqs[seqp++] = "unseen";
                   1233:                deletesw++;
                   1234:                zerosw = 0;
                   1235:                if (!msgp)
                   1236:                    msgs[msgp++] = "all";
                   1237:            }
                   1238: 
                   1239:     if (!msgp)
                   1240:        msgs[msgp++] = listsw ? "all" :"cur";
                   1241:     for (msgnum = 0; msgnum < msgp; msgnum++)
                   1242:        if (!m_convert (mp, msgs[msgnum]))
                   1243:            return;
                   1244: 
                   1245:     if (debugsw) {
                   1246:        printf ("invo_name=%s mypath=%s defpath=%s\n",
                   1247:                invo_name, mypath, defpath);
                   1248:        printf ("ctxpath=%s context flags=%s\n",
                   1249:                ctxpath, sprintb (buf, (unsigned) ctxflags, DBITS));
                   1250:        printf ("foldpath=%s flags=%s\n",
                   1251:                mp -> foldpath,
                   1252:                sprintb (buf, (unsigned) mp -> msgflags, FBITS));
                   1253:        printf ("hghmsg=%d lowmsg=%d nummsg=%d curmsg=%d\n",
                   1254:                mp -> hghmsg, mp -> lowmsg, mp -> nummsg, mp -> curmsg);
                   1255:        printf ("lowsel=%d hghsel=%d numsel=%d\n",
                   1256:                mp -> lowsel, mp -> hghsel, mp -> numsel);
                   1257: #ifndef        MTR
                   1258:        printf ("lowoff=%d hghoff=%d\n",
                   1259:                mp -> lowoff, mp -> hghoff);
                   1260: #else  MTR
                   1261:        printf ("lowoff=%d hghoff=%d msgbase=0x%x msgstats=0x%x\n",
                   1262:                mp -> lowoff, mp -> hghoff, mp -> msgbase, mp -> msgstats);
                   1263: #endif MTR
                   1264:     }
                   1265: 
                   1266:     if (seqp == 0 && (addsw || deletesw)) {
                   1267:        advise (NULLCP, "-%s requires at least one -sequence argument",
                   1268:                addsw ? "add" : "delete");
                   1269:        return;
                   1270:     }
                   1271:     seqs[seqp] = NULL;
                   1272: 
                   1273:     if (addsw)
                   1274:        for (seqp = 0; seqs[seqp]; seqp++) {
                   1275:            if (zerosw && !m_seqnew (mp, seqs[seqp], 0))
                   1276:                return;
                   1277:            for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                   1278:                if (mp -> msgstats[msgnum] & SELECTED)
                   1279:                    if (!m_seqadd (mp, seqs[seqp], msgnum, 0))
                   1280:                        return;
                   1281:        }
                   1282: 
                   1283:     if (deletesw)
                   1284:        for (seqp = 0; seqs[seqp]; seqp++) {
                   1285:            if (zerosw)
                   1286:                for (msgnum = mp -> lowmsg; msgnum <= mp -> hghmsg; msgnum++)
                   1287:                    if (mp -> msgstats[msgnum] & EXISTS)
                   1288:                        if (!m_seqadd (mp, seqs[seqp], msgnum, 0))
                   1289:                            return;
                   1290:            for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                   1291:                if (mp -> msgstats[msgnum] & SELECTED)
                   1292:                    if (!m_seqdel (mp, seqs[seqp], msgnum))
                   1293:                        return;
                   1294:        }
                   1295: 
                   1296:     if (listsw) {
                   1297:        int     bits = FFATTRSLOT;
                   1298: 
                   1299:        if (seqp == 0)
                   1300:            for (i = 0; mp -> msgattrs[i]; i++)
                   1301:                printf ("%s%s: %s\n", mp -> msgattrs[i],
                   1302:                        mp -> attrstats & (1 << (bits + i))
                   1303:                        ? " (private)" : "",
                   1304:                        m_seq (mp, mp -> msgattrs[i]));
                   1305:        else
                   1306:            for (seqp = 0; seqs[seqp]; seqp++)
                   1307:                printf ("%s%s: %s\n", seqs[seqp], m_seq (mp, seqs[seqp]));
                   1308: 
                   1309:        interrupted = 0;
                   1310:        if (debugsw)
                   1311:            for (msgnum = mp -> lowsel;
                   1312:                    msgnum <= mp -> hghsel && !interrupted;
                   1313:                    msgnum++)
                   1314:                if (mp -> msgstats[msgnum] & SELECTED) {
                   1315:                    printf ("%*d: id=%d top=%d start=%ld stop=%ld %s\n",
                   1316:                            DMAXFOLDER, msgnum,
                   1317:                            Msgs[msgnum].m_bboard_id, Msgs[msgnum].m_top,
                   1318:                            Msgs[msgnum].m_start, Msgs[msgnum].m_stop,
                   1319:                            sprintb (buf, (unsigned) mp -> msgstats[msgnum],
                   1320:                                m_seqbits (mp)));
                   1321:                    if (Msgs[msgnum].m_scanl)
                   1322:                        printf ("%s", Msgs[msgnum].m_scanl);
                   1323:                }
                   1324:     }
                   1325: }
                   1326: 
                   1327: /*  */
                   1328: 
                   1329: static struct swit packswit[] = {
                   1330: #define        PAFISW  0
                   1331:     "file name", 0,
                   1332: 
                   1333: #define        PAHELP  1
                   1334:     "help", 4,
                   1335: 
                   1336:     NULL, NULL
                   1337: };
                   1338: 
                   1339: /*  */
                   1340: 
                   1341: packcmd (args)
                   1342: char  **args;
                   1343: {
                   1344:     int     msgp = 0,
                   1345:             md,
                   1346:             msgnum;
                   1347:     char   *cp,
                   1348:            *file = NULL,
                   1349:             buf[BUFSIZ],
                   1350:            *msgs[MAXARGS];
                   1351:     struct stat st;
                   1352: 
                   1353:     if (fmsh) {
                   1354:        forkcmd (args, cmd_name);
                   1355:        return;
                   1356:     }
                   1357: 
                   1358:     while (cp = *args++) {
                   1359:        if (*cp == '-')
                   1360:            switch (smatch (++cp, packswit)) {
                   1361:                case AMBIGSW:
                   1362:                    ambigsw (cp, packswit);
                   1363:                    return;
                   1364:                case UNKWNSW:
                   1365:                    fprintf (stderr, "-%s unknown\n", cp);
                   1366:                    return;
                   1367:                case PAHELP:
                   1368:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                   1369:                    help (buf, packswit);
                   1370:                    return;
                   1371: 
                   1372:                case PAFISW:
                   1373:                    if (!(file = *args++) || *file == '-') {
                   1374:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   1375:                        return;
                   1376:                    }
                   1377:                    continue;
                   1378:            }
                   1379:        if (*cp == '+' || *cp == '@') {
                   1380:            advise (NULLCP, "sorry, no folders allowed!");
                   1381:            return;
                   1382:        }
                   1383:        else
                   1384:            msgs[msgp++] = cp;
                   1385:     }
                   1386: 
                   1387:     if (!file)
                   1388:        file = "./msgbox";
                   1389:     file = path (file, TFILE);
                   1390:     if (stat (file, &st) == NOTOK) {
                   1391:        if (errno != ENOENT) {
                   1392:            advise (file, "error on file");
                   1393:            goto done_pack;
                   1394:        }
                   1395:        md = getanswer (cp = concat ("Create file \"", file, "\"? ", NULLCP));
                   1396:        free (cp);
                   1397:        if (!md)
                   1398:            goto done_pack;
                   1399:     }
                   1400: 
                   1401:     if (!msgp)
                   1402:        msgs[msgp++] = "all";
                   1403:     for (msgnum = 0; msgnum < msgp; msgnum++)
                   1404:        if (!m_convert (mp, msgs[msgnum]))
                   1405:            goto done_pack;
                   1406:     m_setseq (mp);
                   1407: 
                   1408:     if ((md = mbx_open (file, getuid (), getgid (), m_gmprot ())) == NOTOK) {
                   1409:        advise (file, "unable to open");
                   1410:        goto done_pack;
                   1411:     }
                   1412:     for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                   1413:        if (mp -> msgstats[msgnum] & SELECTED)
                   1414:            if (pack (file, md, msgnum) == NOTOK)
                   1415:                break;
                   1416:     (void) mbx_close (file, md);
                   1417: 
                   1418:     if (mp -> hghsel != mp -> curmsg)
                   1419:        m_setcur (mp, mp -> lowsel);
                   1420: 
                   1421: done_pack: ;
                   1422:     free (file);
                   1423: }
                   1424: 
                   1425: /*  */
                   1426: 
                   1427: int    pack (mailbox, md, msgnum)
                   1428: char   *mailbox;
                   1429: int     md,
                   1430:         msgnum;
                   1431: {
                   1432:     register FILE *zp;
                   1433: 
                   1434:     if (Msgs[msgnum].m_bboard_id == 0)
                   1435:        (void) readid (msgnum);
                   1436: 
                   1437:     zp = msh_ready (msgnum, 1);
                   1438:     return mbx_write (mailbox, md, zp, Msgs[msgnum].m_bboard_id,
                   1439:            ftell (zp), Msgs[msgnum].m_stop, 1, 1);
                   1440: }
                   1441: 
                   1442: /*  */
                   1443: 
                   1444: int    packhak (args)
                   1445: char  **args;
                   1446: {
                   1447:     int            result;
                   1448:     char   *cp,
                   1449:           *file = NULL;
                   1450: 
                   1451:     while (cp = *args++) {
                   1452:        if (*cp == '-')
                   1453:            switch (smatch (++cp, packswit)) {
                   1454:                case AMBIGSW:
                   1455:                case UNKWNSW:
                   1456:                case PAHELP:
                   1457:                    return NOTOK;
                   1458: 
                   1459:                case PAFISW:
                   1460:                    if (!(file = *args++) || *file == '-')
                   1461:                        return NOTOK;
                   1462:                    continue;
                   1463:            }
                   1464:        if (*cp == '+' || *cp == '@')
                   1465:            return NOTOK;
                   1466:     }
                   1467: 
                   1468:     file = path (file ? file : "./msgbox", TFILE);
                   1469:     result = access (file, 0) == NOTOK ? OK : NOTOK;
                   1470:     free (file);
                   1471: 
                   1472:     return result;
                   1473: }
                   1474: 
                   1475: /*  */
                   1476: 
                   1477: static struct swit pickswit[] = {
                   1478: #define        PIANSW  0
                   1479:     "and", 0,
                   1480: #define        PIORSW  1
                   1481:     "or", 0,
                   1482: #define        PINTSW  2
                   1483:     "not", 0,
                   1484: #define        PILBSW  3
                   1485:     "lbrace", 0,
                   1486: #define        PIRBSW  4
                   1487:     "rbrace", 0,
                   1488: 
                   1489: #define        PICCSW  5
                   1490:     "cc  pattern", 0,
                   1491: #define        PIDASW  6
                   1492:     "date  pattern", 0,
                   1493: #define        PIFRSW  7
                   1494:     "from  pattern", 0,
                   1495: #define        PISESW  8
                   1496:     "search  pattern", 0,
                   1497: #define        PISUSW  9
                   1498:     "subject  pattern", 0,
                   1499: #define        PITOSW  10
                   1500:     "to  pattern", 0,
                   1501: #define        PIOTSW  11
                   1502:     "-othercomponent  pattern", 15,
                   1503: #define        PIAFSW  12
                   1504:     "after date", 0,
                   1505: #define        PIBFSW  13
                   1506:     "before date", 0,
                   1507: #define        PIDFSW  14
                   1508:     "datefield field", 5,
                   1509: #define        PISQSW  15
                   1510:     "sequence name", 0,
                   1511: #define        PIPUSW  16
                   1512:     "public", 0,
                   1513: #define        PINPUSW 17
                   1514:     "nopublic", 0,
                   1515: #define        PIZRSW  18
                   1516:     "zero", 0,
                   1517: #define        PINZRSW 19
                   1518:     "nozero", 0,
                   1519: #define        PILISW  20
                   1520:     "list", 0,
                   1521: #define        PINLISW 21
                   1522:     "nolist", 0,
                   1523: #define        PIHELP  22
                   1524:     "help", 4,
                   1525: 
                   1526:     NULL, NULL
                   1527: };
                   1528: 
                   1529: /*  */
                   1530: 
                   1531: pickcmd (args)
                   1532: char  **args;
                   1533: {
                   1534:     int     zerosw = 1,
                   1535:             msgp = 0,
                   1536:             seqp = 0,
                   1537:             vecp = 0,
                   1538:             hi,
                   1539:             lo,
                   1540:             msgnum;
                   1541:     char   *cp,
                   1542:             buf[BUFSIZ],
                   1543:            *msgs[MAXARGS],
                   1544:            *seqs[NATTRS],
                   1545:            *vec[MAXARGS];
                   1546:     register FILE *zp;
                   1547: 
                   1548:     while (cp = *args++) {
                   1549:        if (*cp == '-') {
                   1550:            if (*++cp == '-') {
                   1551:                vec[vecp++] = --cp;
                   1552:                goto pattern;
                   1553:            }
                   1554:            switch (smatch (cp, pickswit)) {
                   1555:                case AMBIGSW:
                   1556:                    ambigsw (cp, pickswit);
                   1557:                    return;
                   1558:                case UNKWNSW:
                   1559:                    fprintf (stderr, "-%s unknown\n", cp);
                   1560:                    return;
                   1561:                case PIHELP:
                   1562:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                   1563:                    help (buf, pickswit);
                   1564:                    return;
                   1565: 
                   1566:                case PICCSW:
                   1567:                case PIDASW:
                   1568:                case PIFRSW:
                   1569:                case PISUSW:
                   1570:                case PITOSW:
                   1571:                case PIDFSW:
                   1572:                case PIAFSW:
                   1573:                case PIBFSW:
                   1574:                case PISESW:
                   1575:                    vec[vecp++] = --cp;
                   1576: pattern: ;
                   1577:                    if (!(cp = *args++)) {/* allow -xyz arguments */
                   1578:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   1579:                        return;
                   1580:                    }
                   1581:                    vec[vecp++] = cp;
                   1582:                    continue;
                   1583:                case PIOTSW:
                   1584:                    advise (NULLCP, "internal error!");
                   1585:                    return;
                   1586:                case PIANSW:
                   1587:                case PIORSW:
                   1588:                case PINTSW:
                   1589:                case PILBSW:
                   1590:                case PIRBSW:
                   1591:                    vec[vecp++] = --cp;
                   1592:                    continue;
                   1593: 
                   1594:                case PISQSW:
                   1595:                    if (!(cp = *args++) || *cp == '-') {
                   1596:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   1597:                        return;
                   1598:                    }
                   1599:                    if (seqp < NATTRS)
                   1600:                        seqs[seqp++] = cp;
                   1601:                    else {
                   1602:                        advise (NULLCP, "only %d sequences allowed!", NATTRS);
                   1603:                        return;
                   1604:                    }
                   1605:                    continue;
                   1606:                case PIZRSW:
                   1607:                    zerosw++;
                   1608:                    continue;
                   1609:                case PINZRSW:
                   1610:                    zerosw = 0;
                   1611:                    continue;
                   1612: 
                   1613:                case PIPUSW:    /* not implemented */
                   1614:                case PINPUSW:
                   1615:                case PILISW:
                   1616:                case PINLISW:
                   1617:                    continue;
                   1618:            }
                   1619:        }
                   1620:        if (*cp == '+' || *cp == '@') {
                   1621:            advise (NULLCP, "sorry, no folders allowed!");
                   1622:            return;
                   1623:        }
                   1624:        else
                   1625:            msgs[msgp++] = cp;
                   1626:     }
                   1627:     vec[vecp] = NULL;
                   1628: 
                   1629:     if (!msgp)
                   1630:        msgs[msgp++] = "all";
                   1631:     for (msgnum = 0; msgnum < msgp; msgnum++)
                   1632:        if (!m_convert (mp, msgs[msgnum]))
                   1633:            return;
                   1634:     m_setseq (mp);
                   1635: 
                   1636:     interrupted = 0;
                   1637:     if (!pcompile (vec, NULLCP))
                   1638:        return;
                   1639: 
                   1640:     lo = mp -> lowsel;
                   1641:     hi = mp -> hghsel;
                   1642: 
                   1643:     for (msgnum = mp -> lowsel;
                   1644:            msgnum <= mp -> hghsel && !interrupted;
                   1645:            msgnum++)
                   1646:        if (mp -> msgstats[msgnum] & SELECTED) {
                   1647:            zp = msh_ready (msgnum, 1);
                   1648:            if (pmatches (zp, msgnum, fmsh ? 0L : Msgs[msgnum].m_start,
                   1649:                        fmsh ? 0L : Msgs[msgnum].m_stop)) {
                   1650:                if (msgnum < lo)
                   1651:                    lo = msgnum;
                   1652:                if (msgnum > hi)
                   1653:                    hi = msgnum;
                   1654:            }
                   1655:            else {
                   1656:                mp -> msgstats[msgnum] &= ~SELECTED;
                   1657:                mp -> numsel--;
                   1658:            }
                   1659:        }
                   1660: 
                   1661:     if (interrupted)
                   1662:        return;
                   1663: 
                   1664:     mp -> lowsel = lo;
                   1665:     mp -> hghsel = hi;
                   1666: 
                   1667:     if (mp -> numsel <= 0) {
                   1668:        advise (NULLCP, "no messages match specification");
                   1669:        return;
                   1670:     }
                   1671: 
                   1672:     seqs[seqp] = NULL;
                   1673:     for (seqp = 0; seqs[seqp]; seqp++) {
                   1674:        if (zerosw && !m_seqnew (mp, seqs[seqp], 0))
                   1675:            return;
                   1676:        for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                   1677:            if (mp -> msgstats[msgnum] & SELECTED)
                   1678:                if (!m_seqadd (mp, seqs[seqp], msgnum, 0))
                   1679:                    return;
                   1680:     }
                   1681: 
                   1682:     printf ("%d hit%s\n", mp -> numsel, mp -> numsel == 1 ? "" : "s");
                   1683: }
                   1684: 
                   1685: /*  */
                   1686: 
                   1687: static struct swit replswit[] = {
                   1688: #define        REANSW  0
                   1689:     "annotate", 0,
                   1690: #define        RENANSW 1
                   1691:     "noannotate", 0,
                   1692: #define        RECCSW  2
                   1693:     "cc type", 0,
                   1694: #define        RENCCSW 3
                   1695:     "nocc type", 0,
                   1696: #define        REDFSW  4
                   1697:     "draftfolder +folder", 0,
                   1698: #define        REDMSW  5
                   1699:     "draftmessage msg", 0,
                   1700: #define        RENDFSW 6
                   1701:     "nodraftfolder", 0,
                   1702: #define        REEDTSW 7
                   1703:     "editor editor", 0,
                   1704: #define        RENEDSW 8
                   1705:     "noedit", 0,
                   1706: #define        REFCCSW 9
                   1707:     "fcc +folder", 0,
                   1708: #define        REFLTSW 10
                   1709:     "filter filterfile", 0,
                   1710: #define        REFRMSW 11
                   1711:     "form formfile", 0,
                   1712: #define        REFRSW  12
                   1713:     "format", 5,
                   1714: #define        RENFRSW 13
                   1715:     "noformat", 7,
                   1716: #define        REINSW  14
                   1717:     "inplace", 0,
                   1718: #define        RENINSW 15
                   1719:     "noinplace", 0,
                   1720: #define        REQUSW  16
                   1721:     "query", 0,
                   1722: #define        RENQUSW 17
                   1723:     "noquery", 0,
                   1724: #define        REWHTSW 18
                   1725:     "whatnowproc program", 0,
                   1726: #define        RENWTSW 19
                   1727:     "nowhatnow", 0,
                   1728: #define        REWIDSW 20
                   1729:     "width columns", 0,
                   1730: #define        REHELP  21
                   1731:     "help", 4,
                   1732: 
                   1733:     NULL, NULL
                   1734: };
                   1735: 
                   1736: /*  */
                   1737: 
                   1738: replcmd (args)
                   1739: char  **args;
                   1740: {
                   1741:     int     vecp = 1;
                   1742:     char   *cp,
                   1743:            *msg = NULL,
                   1744:             buf[BUFSIZ],
                   1745:            *vec[MAXARGS];
                   1746: 
                   1747:     if (fmsh) {
                   1748:        forkcmd (args, cmd_name);
                   1749:        return;
                   1750:     }
                   1751: 
                   1752:     while (cp = *args++) {
                   1753:        if (*cp == '-')
                   1754:            switch (smatch (++cp, replswit)) {
                   1755:                case AMBIGSW:
                   1756:                    ambigsw (cp, replswit);
                   1757:                    return;
                   1758:                case UNKWNSW:
                   1759:                    fprintf (stderr, "-%s unknown\n", cp);
                   1760:                    return;
                   1761:                case REHELP:
                   1762:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                   1763:                    help (buf, replswit);
                   1764:                    return;
                   1765: 
                   1766:                case REANSW:    /* not implemented */
                   1767:                case RENANSW:
                   1768:                case REINSW:
                   1769:                case RENINSW:
                   1770:                    continue;
                   1771: 
                   1772:                case REFRSW:
                   1773:                case RENFRSW:
                   1774:                case REQUSW:
                   1775:                case RENQUSW:
                   1776:                case RENDFSW:
                   1777:                case RENEDSW:
                   1778:                case RENWTSW:
                   1779:                    vec[vecp++] = --cp;
                   1780:                    continue;
                   1781: 
                   1782:                case RECCSW:
                   1783:                case RENCCSW:
                   1784:                case REEDTSW:
                   1785:                case REFCCSW:
                   1786:                case REFLTSW:
                   1787:                case REFRMSW:
                   1788:                case REWIDSW:
                   1789:                case REDFSW:
                   1790:                case REDMSW:
                   1791:                case REWHTSW:
                   1792:                    vec[vecp++] = --cp;
                   1793:                    if (!(cp = *args++) || *cp == '-') {
                   1794:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   1795:                        return;
                   1796:                    }
                   1797:                    vec[vecp++] = cp;
                   1798:                    continue;
                   1799:            }
                   1800:        if (*cp == '+' || *cp == '@') {
                   1801:            advise (NULLCP, "sorry, no folders allowed!");
                   1802:            return;
                   1803:        }
                   1804:        else
                   1805:            if (msg) {
                   1806:                advise (NULLCP, "only one message at a time!");
                   1807:                return;
                   1808:            }
                   1809:            else
                   1810:                msg = cp;
                   1811:     }
                   1812: 
                   1813:     vec[0] = cmd_name;
                   1814:     vec[vecp++] = "-file";
                   1815:     vec[vecp] = NULL;
                   1816:     if (!msg)
                   1817:        msg = "cur";
                   1818:     if (!m_convert (mp, msg))
                   1819:        return;
                   1820:     m_setseq (mp);
                   1821: 
                   1822:     if (mp -> numsel > 1) {
                   1823:        advise (NULLCP, "only one message at a time!");
                   1824:        return;
                   1825:     }
                   1826:     (void) process (mp -> hghsel, cmd_name, vecp, vec);
                   1827:     m_setcur (mp, mp -> hghsel);
                   1828: }
                   1829: 
                   1830: /*  */
                   1831: 
                   1832: static struct swit rmmswit[] = {
                   1833: #define        RMHELP  0
                   1834:     "help", 4,
                   1835: 
                   1836:     NULL, NULL
                   1837: };
                   1838: 
                   1839: /*  */
                   1840: 
                   1841: rmmcmd (args)
                   1842: char  **args;
                   1843: {
                   1844:     int            msgp = 0,
                   1845:             msgnum;
                   1846:     char   *cp,
                   1847:             buf[BUFSIZ],
                   1848:            *msgs[MAXARGS];
                   1849: 
                   1850:     while (cp = *args++) {
                   1851:        if (*cp == '-')
                   1852:            switch (smatch (++cp, rmmswit)) {
                   1853:                case AMBIGSW:
                   1854:                    ambigsw (cp, rmmswit);
                   1855:                    return;
                   1856:                case UNKWNSW:
                   1857:                    fprintf (stderr, "-%s unknown\n", cp);
                   1858:                    return;
                   1859:                case RMHELP:
                   1860:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                   1861:                    help (buf, rmmswit);
                   1862:                    return;
                   1863:            }
                   1864:        if (*cp == '+' || *cp == '@') {
                   1865:            advise (NULLCP, "sorry, no folders allowed!");
                   1866:            return;
                   1867:        }
                   1868:        else
                   1869:            msgs[msgp++] = cp;
                   1870:     }
                   1871: 
                   1872:     if (!msgp)
                   1873:        msgs[msgp++] = "cur";
                   1874:     for (msgnum = 0; msgnum < msgp; msgnum++)
                   1875:        if (!m_convert (mp, msgs[msgnum]))
                   1876:            return;
                   1877:     m_setseq (mp);
                   1878: 
                   1879:     rmm ();
                   1880: }
                   1881: 
                   1882: /*  */
                   1883: 
                   1884: static void rmm ()
                   1885: {
                   1886:     register int    msgnum,
                   1887:                     vecp;
                   1888:     register char  *cp;
                   1889:     char    buffer[BUFSIZ],
                   1890:           *vec[MAXARGS];
                   1891: 
                   1892:     if (fmsh) {
                   1893:        if (rmmproc) {
                   1894:            if (mp -> numsel > MAXARGS - 1) {
                   1895:                advise (NULLCP, "more than %d messages for %s exec",
                   1896:                        MAXARGS - 1, rmmproc);
                   1897:                return;
                   1898:            }
                   1899:            vecp = 0;
                   1900:            for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                   1901:                if (mp -> msgstats[msgnum] & SELECTED)
                   1902:                    vec[vecp++] = getcpy (m_name (msgnum));
                   1903:            vec[vecp] = NULL;
                   1904:            forkcmd (vec, rmmproc);
                   1905:            for (vecp = 0; vec[vecp]; vecp++)
                   1906:                free (vec[vecp]);
                   1907:        }
                   1908:        else
                   1909:            for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                   1910:                if (mp -> msgstats[msgnum] & SELECTED) {
                   1911:                    (void) strcpy (buffer, m_backup (cp = m_name (msgnum)));
                   1912:                    if (rename (cp, buffer) == NOTOK)
                   1913:                        admonish (buffer, "unable to rename %s to", cp);
                   1914:                }
                   1915:     }
                   1916: 
                   1917:     for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                   1918:        if (mp -> msgstats[msgnum] & SELECTED) {
                   1919:            mp -> msgstats[msgnum] |= DELETED;
                   1920:            mp -> msgstats[msgnum] &= ~EXISTS;
                   1921:        }
                   1922: 
                   1923:     if ((mp -> nummsg -= mp -> numsel) <= 0) {
                   1924:        if (fmsh)
                   1925:            admonish (NULLCP, "no messages remaining in +%s", fmsh);
                   1926:        else
                   1927:            admonish (NULLCP, "no messages remaining in %s", mp -> foldpath);
                   1928:        mp -> lowmsg = mp -> hghmsg = mp -> nummsg = 0;
                   1929:     }
                   1930:     if (mp -> lowsel == mp -> lowmsg) {
                   1931:        for (msgnum = mp -> lowmsg + 1; msgnum <= mp -> hghmsg; msgnum++)
                   1932:            if (mp -> msgstats[msgnum] & EXISTS)
                   1933:                break;
                   1934:        mp -> lowmsg = msgnum;
                   1935:     }
                   1936:     if (mp -> hghsel == mp -> hghmsg) {
                   1937:        for (msgnum = mp -> hghmsg - 1; msgnum >= mp -> lowmsg; msgnum--)
                   1938:            if (mp -> msgstats[msgnum] & EXISTS)
                   1939:                break;
                   1940:        mp -> hghmsg = msgnum;
                   1941:     }
                   1942: 
                   1943:     mp -> msgflags |= MODIFIED;
                   1944:     modified++;
                   1945: }
                   1946: 
                   1947: /*  */
                   1948: 
                   1949: static struct swit scanswit[] = {
                   1950: #define        SCCLR   0
                   1951:     "clear", 0,
                   1952: #define        SCNCLR  1
                   1953:     "noclear", 0,
                   1954: #define        SCFORM  2
                   1955:     "form formatfile", 0,
                   1956: #define        SCFMT   3
                   1957:     "format string", 5,
                   1958: #define        SCHEAD  4
                   1959:     "header", 0,
                   1960: #define SCNHEAD        5
                   1961:     "noheader", 0,
                   1962: #define        SCWID   6
                   1963:     "width columns", 0,
                   1964: #define        SCHELP  7
                   1965:     "help", 4,
                   1966: 
                   1967:     NULL, NULL
                   1968: };
                   1969: 
                   1970: /*  */
                   1971: 
                   1972: scancmd (args)
                   1973: char  **args;
                   1974: {
                   1975: #define        equiv(a,b)      (a ? b && !strcmp (a, b) : !b)
                   1976: 
                   1977:     int     clearsw = 0,
                   1978:             headersw = 0,
                   1979:            width = 0,
                   1980:             msgp = 0,
                   1981:             msgnum,
                   1982:            optim,
                   1983:            state;
                   1984:     char   *cp,
                   1985:           *form = NULL,
                   1986:           *format = NULL,
                   1987:             buf[BUFSIZ],
                   1988:           *nfs,
                   1989:            *msgs[MAXARGS];
                   1990:     register FILE *zp;
                   1991:     static int s_optim = 0;
                   1992:     static char *s_form = NULL,
                   1993:                *s_format = NULL;
                   1994: 
                   1995:     while (cp = *args++) {
                   1996:        if (*cp == '-')
                   1997:            switch (smatch (++cp, scanswit)) {
                   1998:                case AMBIGSW:
                   1999:                    ambigsw (cp, scanswit);
                   2000:                    return;
                   2001:                case UNKWNSW:
                   2002:                    fprintf (stderr, "-%s unknown\n", cp);
                   2003:                    return;
                   2004:                case SCHELP:
                   2005:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                   2006:                    help (buf, scanswit);
                   2007:                    return;
                   2008: 
                   2009:                case SCCLR:
                   2010:                    clearsw++;
                   2011:                    continue;
                   2012:                case SCNCLR:
                   2013:                    clearsw = 0;
                   2014:                    continue;
                   2015:                case SCHEAD:
                   2016:                    headersw++;
                   2017:                    continue;
                   2018:                case SCNHEAD:
                   2019:                    headersw = 0;
                   2020:                    continue;
                   2021:                case SCFORM:
                   2022:                    if (!(form = *args++) || *form == '-') {
                   2023:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   2024:                        return;
                   2025:                    }
                   2026:                    format = NULL;
                   2027:                    continue;
                   2028:                case SCFMT:
                   2029:                    if (!(format = *args++) || *format == '-') {
                   2030:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   2031:                        return;
                   2032:                    }
                   2033:                    form = NULL;
                   2034:                    continue;
                   2035:                case SCWID:
                   2036:                    if (!(cp = *args++) || *cp == '-') {
                   2037:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   2038:                        return;
                   2039:                    }
                   2040:                    width = atoi (cp);
                   2041:                    continue;
                   2042:            }
                   2043:        if (*cp == '+' || *cp == '@') {
                   2044:            advise (NULLCP, "sorry, no folders allowed!");
                   2045:            return;
                   2046:        }
                   2047:        else
                   2048:            msgs[msgp++] = cp;
                   2049:     }
                   2050: 
                   2051:     if (!msgp)
                   2052:        msgs[msgp++] = "all";
                   2053:     for (msgnum = 0; msgnum < msgp; msgnum++)
                   2054:        if (!m_convert (mp, msgs[msgnum]))
                   2055:            return;
                   2056:     m_setseq (mp);
                   2057: 
                   2058:     nfs = new_fs (form, format, FORMAT);
                   2059:     if (scanl) {               /* force scansbr to (re)compile format */
                   2060:        (void) free (scanl);
                   2061:        scanl = NULL;
                   2062:     }
                   2063: 
                   2064:     if (s_optim == 0) {
                   2065:        s_optim = optim = 1;
                   2066:        s_form = form ? getcpy (form) : NULL;
                   2067:        s_format = format ? getcpy (format) : NULL;
                   2068:     }
                   2069:     else
                   2070:        optim = equiv (s_form, form) && equiv (s_format, format);
                   2071: 
                   2072:     interrupted = 0;
                   2073:     for (msgnum = mp -> lowsel;
                   2074:            msgnum <= mp -> hghsel && !interrupted;
                   2075:            msgnum++)
                   2076:        if (mp -> msgstats[msgnum] & SELECTED) {
                   2077:            if (optim && Msgs[msgnum].m_scanl)
                   2078:                printf ("%s", Msgs[msgnum].m_scanl);
                   2079:            else {
                   2080:                zp = msh_ready (msgnum, 0);
                   2081:                switch (state = scan(zp, msgnum, 0, nfs, width,
                   2082:                    msgnum == mp -> curmsg, headersw, fmsh ? 0L :
                   2083:                    (long) (Msgs[msgnum].m_stop - Msgs[msgnum].m_start),
                   2084:                    1, 0)) {
                   2085:                    case SCNMSG:
                   2086:                    case SCNENC:
                   2087:                    case SCNERR:
                   2088:                        if (optim)
                   2089:                            Msgs[msgnum].m_scanl = getcpy (scanl);
                   2090:                        break;
                   2091: 
                   2092:                    default:
                   2093:                        advise (NULLCP, "scan() botch (%d)", state);
                   2094:                        return;
                   2095: 
                   2096:                    case SCNEOF:
                   2097:                        printf ("%*d  empty\n", DMAXFOLDER, msgnum);
                   2098:                        break;
                   2099:                    }
                   2100:            }
                   2101:            headersw = 0;
                   2102:        }
                   2103: 
                   2104:     if (clearsw)
                   2105:        clear_screen ();
                   2106: }
                   2107: 
                   2108: /*  */
                   2109: 
                   2110: static struct swit showswit[] = {
                   2111: #define        SHDRAFT 0
                   2112:     "draft", 5,
                   2113: #define        SHFORM  1
                   2114:     "form formfile", 4,
                   2115: #define        SHPROG  2
                   2116:     "moreproc program", 4,
                   2117: #define        SHNPROG 3
                   2118:     "nomoreproc", 3,
                   2119: #define        SHLEN   4
                   2120:     "length lines", 4,
                   2121: #define        SHWID   5
                   2122:     "width columns", 4,
                   2123: #define        SHSHOW  6
                   2124:     "showproc program", 4,
                   2125: #define        SHNSHOW 7
                   2126:     "noshowproc", 3,
                   2127: #define        SHHEAD  8
                   2128:     "header", 4,
                   2129: #define SHNHEAD        9
                   2130:     "noheader", 3,
                   2131: #define        SHHELP  10
                   2132:     "help", 4,
                   2133: 
                   2134:     NULL, NULL
                   2135: };
                   2136: 
                   2137: /*  */
                   2138: 
                   2139: showcmd (args)
                   2140: char  **args;
                   2141: {
                   2142:     int            headersw = 1,
                   2143:             nshow = 0,
                   2144:             msgp = 0,
                   2145:             vecp = 1,
                   2146:             mhl = 0,
                   2147:             seen = 0,
                   2148:             mode = 0,
                   2149:            i,
                   2150:             msgnum;
                   2151:     char   *cp,
                   2152:            *proc = showproc,
                   2153:             buf[BUFSIZ],
                   2154:            *msgs[MAXARGS],
                   2155:            *vec[MAXARGS];
                   2156: 
                   2157:     if (uleq (cmd_name, "next"))
                   2158:        mode = 1;
                   2159:     else
                   2160:        if (uleq (cmd_name, "prev"))
                   2161:            mode = -1;
                   2162:     while (cp = *args++) {
                   2163:        if (*cp == '-')
                   2164:            switch (i = smatch (++cp, showswit)) {
                   2165:                case AMBIGSW:
                   2166:                    ambigsw (cp, showswit);
                   2167:                    return;
                   2168:                case UNKWNSW:
                   2169:                case SHNPROG:
                   2170:                    vec[vecp++] = --cp;
                   2171:                    continue;
                   2172:                case SHHELP:
                   2173:                    (void) sprintf (buf,
                   2174:                            "%s %s[switches] [switches for showproc]",
                   2175:                            cmd_name, mode ? NULL : "[msgs] ");
                   2176:                    help (buf, showswit);
                   2177:                    return;
                   2178: 
                   2179:                case SHFORM:
                   2180:                case SHPROG:
                   2181:                case SHLEN:
                   2182:                case SHWID:
                   2183:                    vec[vecp++] = --cp;
                   2184:                    if (!(cp = *args++) || *cp == '-') {
                   2185:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   2186:                        return;
                   2187:                    }
                   2188:                    vec[vecp++] = cp;
                   2189:                    continue;
                   2190:                case SHHEAD:
                   2191:                    headersw++;
                   2192:                    continue;
                   2193:                case SHNHEAD:
                   2194:                    headersw = 0;
                   2195:                    continue;
                   2196:                case SHSHOW:
                   2197:                    if (!(proc = *args++) || *proc == '-') {
                   2198:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   2199:                        return;
                   2200:                    }
                   2201:                    nshow = 0;
                   2202:                    continue;
                   2203:                case SHNSHOW:
                   2204:                    nshow++;
                   2205:                    continue;
                   2206: 
                   2207:                case SHDRAFT:
                   2208:                    advise (NULLCP, "sorry, -%s not allowed!", showswit[i].sw);
                   2209:                    return;
                   2210:            }
                   2211:        if (*cp == '+' || *cp == '@') {
                   2212:            advise (NULLCP, "sorry, no folders allowed!");
                   2213:            return;
                   2214:        }
                   2215:        else
                   2216:            if (mode) {
                   2217:                fprintf (stderr,
                   2218:                        "usage: %s [switches] [switches for showproc]\n",
                   2219:                        cmd_name);
                   2220:                return;
                   2221:            }
                   2222:            else
                   2223:                msgs[msgp++] = cp;
                   2224:     }
                   2225:     vec[vecp] = NULL;
                   2226: 
                   2227:     if (!msgp)
                   2228:        msgs[msgp++] = mode > 0 ? "next" : mode < 0 ? "prev" : "cur";
                   2229:     for (msgnum = 0; msgnum < msgp; msgnum++)
                   2230:        if (!m_convert (mp, msgs[msgnum]))
                   2231:            return;
                   2232:     m_setseq (mp);
                   2233: 
                   2234:     if (nshow)
                   2235:        proc = "cat";
                   2236:     else
                   2237:        if (strcmp (showproc, "mhl") == 0) {
                   2238:            proc = mhlproc;
                   2239:            mhl++;
                   2240:        }
                   2241: 
                   2242:     seen = m_seqflag (mp, "unseen");
                   2243:     vec[0] = r1bindex (proc, '/');
                   2244:     if (mhl) {
                   2245:        msgp = vecp;
                   2246:        for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                   2247:            if (mp -> msgstats[msgnum] & SELECTED) {
                   2248:                vec[vecp++] = getcpy (m_name (msgnum));
                   2249:                if (seen)
                   2250:                    (void) m_seqdel (mp, "unseen", msgnum);
                   2251:            }
                   2252:        vec[vecp] = NULL;
                   2253:        if (mp -> numsel == 1 && headersw)
                   2254:            show (mp -> lowsel);
                   2255:        (void) mhlsbr (vecp, vec, mhl_action);
                   2256:        m_eomsbr ((int (*)()) 0);
                   2257:        while (msgp < vecp)
                   2258:            free (vec[msgp++]);
                   2259:     }
                   2260:     else {
                   2261:        interrupted = 0;
                   2262:        for (msgnum = mp -> lowsel;
                   2263:                msgnum <= mp -> hghsel && !interrupted;
                   2264:                msgnum++)
                   2265:            if (mp -> msgstats[msgnum] & SELECTED) {
                   2266:                switch (ask (msgnum)) {
                   2267:                    case NOTOK: /* QUIT */
                   2268:                        break;
                   2269: 
                   2270:                    case OK:    /* INTR */
                   2271:                        continue;
                   2272: 
                   2273:                    default:
                   2274:                        if (mp -> numsel == 1 && headersw)
                   2275:                            show (msgnum);
                   2276:                        if (nshow)
                   2277:                            copy_message (msgnum, stdout);
                   2278:                        else
                   2279:                            (void) process (msgnum, proc, vecp, vec);
                   2280: 
                   2281:                        if (seen)
                   2282:                            (void) m_seqdel (mp, "unseen", msgnum);
                   2283:                        continue;
                   2284:                }
                   2285:                break;
                   2286:            }
                   2287:     }
                   2288: 
                   2289:     m_setcur (mp, mp -> hghsel);
                   2290: }
                   2291: 
                   2292: /*  */
                   2293: 
                   2294: static void show (msgnum)
                   2295: int     msgnum;
                   2296: {
                   2297:     if (Msgs[msgnum].m_bboard_id == 0)
                   2298:        (void) readid (msgnum);
                   2299: 
                   2300:     printf ("(Message %d", msgnum);
                   2301:     if (Msgs[msgnum].m_bboard_id > 0)
                   2302:        printf (", %s: %d", BBoard_ID, Msgs[msgnum].m_bboard_id);
                   2303:     printf (")\n");
                   2304: }
                   2305: 
                   2306: 
                   2307: /* ARGSUSED */
                   2308: 
                   2309: static int eom_action (c)
                   2310: int     c;
                   2311: {
                   2312:     return (ftell (mhlfp) >= Msgs[mhlnum].m_stop);
                   2313: }
                   2314: 
                   2315: 
                   2316: static FP mhl_action (name)
                   2317: char   *name;
                   2318: {
                   2319:     int     msgnum;
                   2320: 
                   2321:     if ((msgnum = m_atoi (name)) < mp -> lowmsg
                   2322:            || msgnum > mp -> hghmsg
                   2323:            || !(mp -> msgstats[msgnum] & EXISTS))
                   2324:        return NULL;
                   2325:     mhlnum = msgnum;
                   2326: 
                   2327:     mhlfp = msh_ready (msgnum, 1);
                   2328:     if (!fmsh)
                   2329:        m_eomsbr (eom_action);
                   2330: 
                   2331:     return mhlfp;
                   2332: }
                   2333: 
                   2334: 
                   2335: /*  */
                   2336: 
                   2337: static int ask (msgnum)
                   2338: int     msgnum;
                   2339: {
                   2340:     char    buf[BUFSIZ];
                   2341: 
                   2342:     if (mp -> numsel == 1 || !interactive || redirected)
                   2343:        return DONE;
                   2344: 
                   2345:     if (SOprintf ("Press <return> to list \"%d\"...", msgnum)) {
                   2346:        if (mp -> lowsel != msgnum)
                   2347:            printf ("\n\n\n");
                   2348:        printf ("Press <return> to list \"%d\"...", msgnum);
                   2349:     }
                   2350:     (void) fflush (stdout);
                   2351:     buf[0] = NULL;
                   2352: #ifndef        BSD42
                   2353:     (void) read (fileno (stdout), buf, sizeof buf);
                   2354: #else  BSD42
                   2355:     switch (setjmp (sigenv)) {
                   2356:        case OK:
                   2357:            should_intr = 1;
                   2358:            (void) read (fileno (stdout), buf, sizeof buf);/* fall... */
                   2359: 
                   2360:        default:
                   2361:            should_intr = 0;
                   2362:            break;
                   2363:     }
                   2364: #endif BSD42
                   2365:     if (index (buf, '\n') == NULL)
                   2366:        (void) putchar ('\n');
                   2367: 
                   2368:     if (told_to_quit) {
                   2369:        told_to_quit = interrupted = 0;
                   2370:        return NOTOK;
                   2371:     }
                   2372:     if (interrupted) {
                   2373:        interrupted = 0;
                   2374:        return OK;
                   2375:     }
                   2376: 
                   2377:     return DONE;
                   2378: }
                   2379: 
                   2380: /*  */
                   2381: 
                   2382: static struct swit sortswit[] = {
                   2383: #define        SODATE  0
                   2384:     "datefield field", 0,
                   2385: #define        SOVERB  1
                   2386:     "verbose", 0,
                   2387: #define        SONVERB 2
                   2388:     "noverbose", 0,
                   2389: #define        SOHELP  3
                   2390:     "help", 4,
                   2391: 
                   2392:     NULL, NULL
                   2393: };
                   2394: 
                   2395: /*  */
                   2396: 
                   2397: sortcmd (args)
                   2398: char  **args;
                   2399: {
                   2400:     int     msgp = 0,
                   2401:             msgnum;
                   2402:     char   *cp,
                   2403:            *datesw = NULL,
                   2404:             buf[BUFSIZ],
                   2405:            *msgs[MAXARGS];
                   2406:     struct tws  tb,
                   2407:                *tw;
                   2408: 
                   2409:     if (fmsh) {
                   2410:        forkcmd (args, cmd_name);
                   2411:        return;
                   2412:     }
                   2413: 
                   2414:     while (cp = *args++) {
                   2415:        if (*cp == '-')
                   2416:            switch (smatch (++cp, sortswit)) {
                   2417:                case AMBIGSW:
                   2418:                    ambigsw (cp, sortswit);
                   2419:                    return;
                   2420:                case UNKWNSW:
                   2421:                    fprintf (stderr, "-%s unknown\n", cp);
                   2422:                    return;
                   2423:                case SOHELP:
                   2424:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                   2425:                    help (buf, sortswit);
                   2426:                    return;
                   2427: 
                   2428:                case SODATE:
                   2429:                    if (datesw) {
                   2430:                        advise (NULLCP, "only one date field at a time!");
                   2431:                        return;
                   2432:                    }
                   2433:                    if (!(datesw = *args++) || *datesw == '-') {
                   2434:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   2435:                        return;
                   2436:                    }
                   2437:                    continue;
                   2438: 
                   2439:                case SOVERB:            /* not implemented */
                   2440:                case SONVERB:
                   2441:                    continue;
                   2442:            }
                   2443:        if (*cp == '+' || *cp == '@') {
                   2444:            advise (NULLCP, "sorry, no folders allowed!");
                   2445:            return;
                   2446:        }
                   2447:        else
                   2448:            msgs[msgp++] = cp;
                   2449:     }
                   2450: 
                   2451:     if (!msgp)
                   2452:        msgs[msgp++] = "all";
                   2453:     if (!datesw)
                   2454:        datesw = "Date";
                   2455:     for (msgnum = 0; msgnum < msgp; msgnum++)
                   2456:        if (!m_convert (mp, msgs[msgnum]))
                   2457:            return;
                   2458:     m_setseq (mp);
                   2459: 
                   2460:     twscopy (&tb, dtwstime ());
                   2461: 
                   2462:     for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) {
                   2463:        if (Msgs[msgnum].m_scanl) {
                   2464:            free (Msgs[msgnum].m_scanl);
                   2465:            Msgs[msgnum].m_scanl = NULL;
                   2466:        }
                   2467:        if (mp -> msgstats[msgnum] & SELECTED) {
                   2468:            if ((tw = getws (datesw, msgnum)) == NULL)
                   2469:                tw = msgnum != mp -> lowsel ? &Msgs[msgnum - 1].m_tb : &tb;
                   2470:        }
                   2471:        else
                   2472:            tw = &tb;
                   2473:        twscopy (&Msgs[msgnum].m_tb, tw);
                   2474:        Msgs[msgnum].m_stats = mp -> msgstats[msgnum];
                   2475:        if (mp -> curmsg == msgnum)
                   2476:            Msgs[msgnum].m_stats |= CUR;
                   2477:     }
                   2478: 
                   2479:     qsort ((char *) &Msgs[mp -> lowsel], mp -> hghsel - mp -> lowsel + 1,
                   2480:            sizeof (struct Msg), msgsort);
                   2481: 
                   2482:     for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) {
                   2483:        mp -> msgstats[msgnum] = Msgs[msgnum].m_stats & ~CUR;
                   2484:        if (Msgs[msgnum].m_stats & CUR)
                   2485:            m_setcur (mp, msgnum);
                   2486:     }
                   2487: 
                   2488:     mp -> msgflags |= MODIFIED;
                   2489:     modified++;
                   2490: }
                   2491: 
                   2492: /*  */
                   2493: 
                   2494: static struct tws *getws (datesw, msgnum)
                   2495: char   *datesw;
                   2496: int     msgnum;
                   2497: {
                   2498:     int            state;
                   2499:     char   *bp,
                   2500:             buf[BUFSIZ],
                   2501:             name[NAMESZ];
                   2502:     struct tws *tw;
                   2503:     register FILE *zp;
                   2504: 
                   2505:     zp = msh_ready (msgnum, 0);
                   2506:     for (state = FLD;;)
                   2507:        switch (state = m_getfld (state, name, buf, sizeof buf, zp)) {
                   2508:            case FLD:
                   2509:            case FLDEOF:
                   2510:            case FLDPLUS:
                   2511:                if (uleq (name, datesw)) {
                   2512:                    bp = getcpy (buf);
                   2513:                    while (state == FLDPLUS) {
                   2514:                        state = m_getfld (state, name, buf, sizeof buf, zp);
                   2515:                        bp = add (buf, bp);
                   2516:                    }
                   2517:                    if ((tw = dparsetime (bp)) == NULL)
                   2518:                        admonish (NULLCP,
                   2519:                                "unable to parse %s field in message %d",
                   2520:                                datesw, msgnum);
                   2521:                    free (bp);
                   2522:                    return tw;
                   2523:                }
                   2524:                while (state == FLDPLUS)
                   2525:                    state = m_getfld (state, name, buf, sizeof buf, zp);
                   2526:                if (state != FLDEOF)
                   2527:                    continue;
                   2528: 
                   2529:            case BODY:
                   2530:            case BODYEOF:
                   2531:            case FILEEOF:
                   2532:                admonish (NULLCP, "no %s field in message %d", datesw, msgnum);
                   2533:                return NULL;
                   2534: 
                   2535:            case LENERR:
                   2536:            case FMTERR:
                   2537:                admonish (NULLCP, "format error in message %d", msgnum);
                   2538:                return NULL;
                   2539: 
                   2540:            default:
                   2541:                adios (NULLCP, "internal error -- you lose");
                   2542:        }
                   2543: }
                   2544: 
                   2545: 
                   2546: static int msgsort (a, b)
                   2547: struct Msg *a,
                   2548:            *b;
                   2549: {
                   2550:     return twsort (&a -> m_tb, &b -> m_tb);
                   2551: }
                   2552: 
                   2553: /*  */
                   2554: 
                   2555: static int process (msgnum, proc, vecp, vec)
                   2556: int     msgnum,
                   2557:         vecp;
                   2558: char   *proc,
                   2559:       **vec;
                   2560: {
                   2561:     int            child_id,
                   2562:            status;
                   2563:     char    tmpfil[80];
                   2564:     FILE   *out;
                   2565: 
                   2566:     if (fmsh) {
                   2567:        (void) strcpy (tmpfil, m_name (msgnum));
                   2568:        (void) m_delete (pfolder);
                   2569:        m_replace (pfolder, fmsh);
                   2570:        m_sync (mp);
                   2571:        m_update ();
                   2572:        goto ready;
                   2573:     }
                   2574: 
                   2575:     (void) strcpy (tmpfil, m_scratch ("", invo_name));
                   2576:     if ((out = fopen (tmpfil, "w")) == NULL) {
                   2577:        int     olderr;
                   2578:        extern int  errno;
                   2579:        char    newfil[80];
                   2580: 
                   2581:        olderr = errno;
                   2582:        (void) strcpy (newfil, m_tmpfil (invo_name));
                   2583:        if ((out = fopen (newfil, "w")) == NULL) {
                   2584:            errno = olderr;
                   2585:            advise (tmpfil, "unable to create temporary file");
                   2586:            return NOTOK;
                   2587:        }
                   2588:        else
                   2589:            (void) strcpy (tmpfil, newfil);
                   2590:     }
                   2591:     copy_message (msgnum, out);
                   2592:     (void) fclose (out);
                   2593: 
                   2594: ready: ;
                   2595:     (void) fflush (stdout);
                   2596:     switch (child_id = fork ()) {
                   2597:        case NOTOK:
                   2598:            advise ("fork", "unable to");
                   2599:            status = NOTOK;
                   2600:            break;
                   2601: 
                   2602:        case OK:
                   2603:            closefds (3);
                   2604:            (void) signal (SIGINT, istat);
                   2605:            (void) signal (SIGQUIT, qstat);
                   2606: 
                   2607:            vec[vecp++] = tmpfil;
                   2608:            vec[vecp] = NULL;
                   2609: 
                   2610:            execvp (proc, vec);
                   2611:            fprintf (stderr, "unable to exec ");
                   2612:            perror (proc);
                   2613:            _exit (1);
                   2614: 
                   2615:        default:
                   2616:            status = pidXwait (child_id, NULLCP);
                   2617:            break;
                   2618:     }
                   2619: 
                   2620:     if (!fmsh)
                   2621:        (void) unlink (tmpfil);
                   2622:     return status;
                   2623: }
                   2624: 
                   2625: /*  */
                   2626: 
                   2627: static void copy_message (msgnum, out)
                   2628: int     msgnum;
                   2629: FILE * out;
                   2630: {
                   2631:     long    pos;
                   2632:     static char buffer[BUFSIZ];
                   2633:     register    FILE * zp;
                   2634: 
                   2635:     zp = msh_ready (msgnum, 1);
                   2636:     if (fmsh) {
                   2637:        while (fgets (buffer, sizeof buffer, zp) != NULL) {
                   2638:            fputs (buffer, out);
                   2639:            if (interrupted && out == stdout)
                   2640:                break;
                   2641:        }
                   2642:     }
                   2643:     else {
                   2644:        pos = ftell (zp);
                   2645:        while (fgets (buffer, sizeof buffer, zp) != NULL
                   2646:                && pos < Msgs[msgnum].m_stop) {
                   2647:            fputs (buffer, out);
                   2648:            pos += (long) strlen (buffer);
                   2649:            if (interrupted && out == stdout)
                   2650:                break;
                   2651:        }
                   2652:     }
                   2653: }
                   2654: 
                   2655: 
                   2656: static void copy_digest (msgnum, out)
                   2657: int     msgnum;
                   2658: FILE * out;
                   2659: {
                   2660:     char    c;
                   2661:     long    pos;
                   2662:     static char buffer[BUFSIZ];
                   2663:     register FILE *zp;
                   2664: 
                   2665:     c = '\n';
                   2666:     zp = msh_ready (msgnum, 1);
                   2667:     if (!fmsh)
                   2668:        pos = ftell (zp);
                   2669:     while (fgets (buffer, sizeof buffer, zp) != NULL
                   2670:            && !fmsh && pos < Msgs[msgnum].m_stop) {
                   2671:        if (c == '\n' && *buffer == '-')
                   2672:            (void) fputc (' ', out);
                   2673:        fputs (buffer, out);
                   2674:        c = buffer[strlen (buffer) - 1];
                   2675:        if (!fmsh)
                   2676:            pos += (long) strlen (buffer);
                   2677:        if (interrupted && out == stdout)
                   2678:            break;
                   2679:     }
                   2680: }

unix.superglobalmegacorp.com

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