Annotation of 43BSD/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: int     eom_action ();
                     32: FP     mhl_action ();
                     33: 
                     34: 
                     35:                                /* SORTM */
                     36: int    msgsort ();
                     37: struct tws *getws ();
                     38: 
                     39: /*  */
                     40: 
                     41: forkcmd (args, pgm)
                     42: char  **args,
                     43:        *pgm;
                     44: {
                     45:     int     child_id;
                     46:     char   *vec[MAXARGS];
                     47: 
                     48:     vec[0] = r1bindex (pgm, '/');
                     49:     (void) copyip (args, vec + 1);
                     50: 
                     51:     if (fmsh) {
                     52:        (void) m_delete (pfolder);
                     53:        m_replace (pfolder, fmsh);
                     54:        m_sync (mp);
                     55:        m_update ();
                     56:     }
                     57:     (void) fflush (stdout);
                     58:     switch (child_id = fork ()) {
                     59:        case NOTOK: 
                     60:            advise ("fork", "unable to");
                     61:            return;
                     62: 
                     63:        case OK: 
                     64:            closefds (3);
                     65:            (void) signal (SIGINT, istat);
                     66:            (void) signal (SIGQUIT, qstat);
                     67: 
                     68:            execvp (pgm, vec);
                     69:            fprintf (stderr, "unable to exec ");
                     70:            perror (cmd_name);
                     71:            _exit (1);
                     72: 
                     73:        default: 
                     74:            (void) pidXwait (child_id, NULLCP);
                     75:            break;
                     76:     }
                     77:     if (fmsh) {                        /* assume the worst case */
                     78:        mp -> msgflags |= MODIFIED;
                     79:        modified++;
                     80:     }
                     81: }
                     82: 
                     83: /*  */
                     84: 
                     85: static struct swit distswit[] = {
                     86: #define        DIANSW  0
                     87:     "annotate", 0,
                     88: #define        DINANSW 1
                     89:     "noannotate", 0,
                     90: #define        DIDFSW  2
                     91:     "draftfolder +folder", 0,
                     92: #define        DIDMSW  3
                     93:     "draftmessage msg", 0,
                     94: #define        DINDFSW 4
                     95:     "nodraftfolder", 0,
                     96: #define        DIEDTSW 5
                     97:     "editor editor", 0,
                     98: #define        DINEDSW 6
                     99:     "noedit", 0,
                    100: #define        DIFRMSW 7
                    101:     "form formfile", 0,
                    102: #define        DIINSW  8
                    103:     "inplace", 0,
                    104: #define        DININSW 9
                    105:     "noinplace", 0,
                    106: #define        DIWHTSW 10
                    107:     "whatnowproc program", 0,
                    108: #define        DINWTSW 11
                    109:     "nowhatnowproc", 0,
                    110: #define        DIHELP  12
                    111:     "help", 4,
                    112: 
                    113:     NULL, NULL
                    114: };
                    115: 
                    116: /*  */
                    117: 
                    118: distcmd (args)
                    119: char  **args;
                    120: {
                    121:     int     vecp = 1;
                    122:     char   *cp,
                    123:            *msg = NULL,
                    124:             buf[BUFSIZ],
                    125:            *vec[MAXARGS];
                    126: 
                    127:     if (fmsh) {
                    128:        forkcmd (args, cmd_name);
                    129:        return;
                    130:     }
                    131: 
                    132:     while (cp = *args++) {
                    133:        if (*cp == '-')
                    134:            switch (smatch (++cp, distswit)) {
                    135:                case AMBIGSW: 
                    136:                    ambigsw (cp, distswit);
                    137:                    return;
                    138:                case UNKWNSW: 
                    139:                    fprintf (stderr, "-%s unknown\n", cp);
                    140:                    return;
                    141:                case DIHELP: 
                    142:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                    143:                    help (buf, distswit);
                    144:                    return;
                    145: 
                    146:                case DIANSW:    /* not implemented */
                    147:                case DINANSW: 
                    148:                case DIINSW: 
                    149:                case DININSW: 
                    150:                    continue;
                    151: 
                    152:                case DINDFSW:
                    153:                case DINEDSW:
                    154:                case DINWTSW:
                    155:                    vec[vecp++] = --cp;
                    156:                    continue;
                    157: 
                    158:                case DIEDTSW: 
                    159:                case DIFRMSW: 
                    160:                case DIDFSW:
                    161:                case DIDMSW:
                    162:                case DIWHTSW:
                    163:                    vec[vecp++] = --cp;
                    164:                    if (!(cp = *args++) || *cp == '-') {
                    165:                        advise (NULLCP, "missing argument to %s", args[-2]);
                    166:                        return;
                    167:                    }
                    168:                    vec[vecp++] = cp;
                    169:                    continue;
                    170:            }
                    171:        if (*cp == '+' || *cp == '@') {
                    172:            advise (NULLCP, "sorry, no folders allowed!");
                    173:            return;
                    174:        }
                    175:        else
                    176:            if (msg) {
                    177:                advise (NULLCP, "only one message at a time!");
                    178:                return;
                    179:            }
                    180:            else
                    181:                msg = cp;
                    182:     }
                    183: 
                    184:     vec[0] = cmd_name;
                    185:     vec[vecp++] = "-file";
                    186:     vec[vecp] = NULL;
                    187:     if (!msg)
                    188:        msg = "cur";
                    189:     if (!m_convert (mp, msg))
                    190:        return;
                    191:     m_setseq (mp);
                    192: 
                    193:     if (mp -> numsel > 1) {
                    194:        advise (NULLCP, "only one message at a time!");
                    195:        return;
                    196:     }
                    197:     (void) process (mp -> hghsel, cmd_name, vecp, vec);
                    198:     m_setcur (mp, mp -> hghsel);
                    199: }
                    200: 
                    201: /*  */
                    202: 
                    203: static struct swit explswit[] = {
                    204: #define        EXINSW  0
                    205:     "inplace", 0,
                    206: #define        EXNINSW 1
                    207:     "noinplace", 0,
                    208: #define        EXQISW  2
                    209:     "quiet", 0,
                    210: #define        EXNQISW 3
                    211:     "noquiet", 0,
                    212: #define        EXVBSW  4
                    213:     "verbose", 0,
                    214: #define        EXNVBSW 5
                    215:     "noverbose", 0,
                    216: #define        EXHELP  6
                    217:     "help", 4,
                    218: 
                    219:     NULL, NULL
                    220: };
                    221: 
                    222: /*  */
                    223: 
                    224: explcmd (args)
                    225: char  **args;
                    226: {
                    227:     int     inplace = 0,
                    228:             quietsw = 0,
                    229:             verbosw = 0,
                    230:             msgp = 0,
                    231:             hi,
                    232:             msgnum;
                    233:     char   *cp,
                    234:             buf[BUFSIZ],
                    235:            *msgs[MAXARGS];
                    236:     struct Msg *smsgs;
                    237: 
                    238:     if (fmsh) {
                    239:        forkcmd (args, cmd_name);
                    240:        return;
                    241:     }
                    242: 
                    243:     while (cp = *args++) {
                    244:        if (*cp == '-')
                    245:            switch (smatch (++cp, explswit)) {
                    246:                case AMBIGSW: 
                    247:                    ambigsw (cp, explswit);
                    248:                    return;
                    249:                case UNKWNSW: 
                    250:                    fprintf (stderr, "-%s unknown\n", cp);
                    251:                    return;
                    252:                case EXHELP: 
                    253:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                    254:                    help (buf, explswit);
                    255:                    return;
                    256: 
                    257:                case EXINSW: 
                    258:                    inplace++;
                    259:                    continue;
                    260:                case EXNINSW: 
                    261:                    inplace = 0;
                    262:                    continue;
                    263:                case EXQISW: 
                    264:                    quietsw++;
                    265:                    continue;
                    266:                case EXNQISW: 
                    267:                    quietsw = 0;
                    268:                    continue;
                    269:                case EXVBSW: 
                    270:                    verbosw++;
                    271:                    continue;
                    272:                case EXNVBSW: 
                    273:                    verbosw = 0;
                    274:                    continue;
                    275:            }
                    276:        if (*cp == '+' || *cp == '@') {
                    277:            advise (NULLCP, "sorry, no folders allowed!");
                    278:            return;
                    279:        }
                    280:        else
                    281:            msgs[msgp++] = cp;
                    282:     }
                    283: 
                    284:     if (!msgp)
                    285:        msgs[msgp++] = "cur";
                    286:     for (msgnum = 0; msgnum < msgp; msgnum++)
                    287:        if (!m_convert (mp, msgs[msgnum]))
                    288:            return;
                    289:     m_setseq (mp);
                    290: 
                    291:     smsgs = (struct Msg *)
                    292:                calloc ((unsigned) (MAXFOLDER + 2), sizeof *smsgs);
                    293:     if (smsgs == NULL)
                    294:        adios (NULLCP, "unable to allocate folder storage");
                    295: 
                    296:     hi = mp -> hghmsg + 1;
                    297:     interrupted = 0;
                    298:     for (msgnum = mp -> lowsel;
                    299:            msgnum <= mp -> hghsel && !interrupted;
                    300:            msgnum++)
                    301:        if (mp -> msgstats[msgnum] & SELECTED)
                    302:            if (burst (smsgs, msgnum, inplace, quietsw, verbosw) != OK)
                    303:                break;
                    304: 
                    305:     free ((char *) smsgs);
                    306: 
                    307:     if (inplace)
                    308:        m_setcur (mp, mp -> lowsel);
                    309:     else
                    310:        if (hi <= mp -> hghmsg)
                    311:            m_setcur (mp, hi);
                    312: 
                    313:     mp -> msgflags |= MODIFIED;
                    314:     modified++;
                    315: }
                    316: 
                    317: /*  */
                    318: 
                    319: static  burst (smsgs, msgnum, inplace, quietsw, verbosw)
                    320: struct Msg *smsgs;
                    321: int     msgnum,
                    322:         inplace,
                    323:         quietsw,
                    324:         verbosw;
                    325: {
                    326:     int     i,
                    327:             j,
                    328:             ld3,
                    329:            wasdlm,
                    330:             msgp;
                    331:     long    pos;
                    332:     char    c,
                    333:             buffer[BUFSIZ];
                    334:     register FILE *zp;
                    335: 
                    336:     ld3 = strlen (delim3);
                    337: 
                    338:     if (Msgs[msgnum].m_scanl) {
                    339:        free (Msgs[msgnum].m_scanl);
                    340:        Msgs[msgnum].m_scanl = NULL;
                    341:     }
                    342: 
                    343:     pos = ftell (zp = msh_ready (msgnum, 1));
                    344:     for (msgp = 1; msgp <= MAXFOLDER;) {
                    345:        while (fgets (buffer, sizeof buffer, zp) != NULL
                    346:                && buffer[0] == '\n'
                    347:                && pos < Msgs[msgnum].m_stop)
                    348:            pos += (long) strlen (buffer);
                    349:        if (feof (zp) || pos >= Msgs[msgnum].m_stop)
                    350:            break;
                    351:        (void) fseek (zp, pos, 0);
                    352:        smsgs[msgp].m_start = pos;
                    353: 
                    354:        for (c = NULL;
                    355:                fgets (buffer, sizeof buffer, zp) != NULL
                    356:                && pos < Msgs[msgnum].m_stop;
                    357:                c = buffer[0])
                    358:            if (strncmp (buffer, delim3, ld3) == 0
                    359:                    && peekc (zp) == '\n'
                    360:                    && (msgp == 1 || c == '\n'))
                    361:                break;
                    362:            else
                    363:                pos += (long) strlen (buffer);
                    364: 
                    365:        wasdlm = strncmp (buffer, delim3, ld3) == 0;
                    366:        if (smsgs[msgp].m_start != pos)
                    367:            smsgs[msgp++].m_stop = c == '\n' && wasdlm ? pos - 1 : pos;
                    368:        if (feof (zp) || pos >= Msgs[msgnum].m_stop) {
                    369:            if (wasdlm) {
                    370:                smsgs[msgp - 1].m_stop -= ((long) strlen (buffer) + 1);
                    371:                msgp++;         /* fake "End of XXX Digest" */
                    372:            }
                    373:            break;
                    374:        }
                    375:        pos += (long) strlen (buffer);
                    376:     }
                    377: 
                    378:     switch (--msgp) {          /* toss "End of XXX Digest" */
                    379:        case 0: 
                    380:            adios (NULLCP, "burst() botch -- you lose big");
                    381: 
                    382:        case 1: 
                    383:            if (!quietsw)
                    384:                printf ("message %d not in digest format\n", msgnum);
                    385:            return OK;
                    386: 
                    387:        default: 
                    388:            if (verbosw)
                    389:                printf ("%d message%s exploded from digest %d\n",
                    390:                        msgp - 1, msgp - 1 != 1 ? "s" : "", msgnum);
                    391:            if (msgp == 2)
                    392:                msgp++;
                    393:            break;
                    394:     }
                    395: 
                    396:     msgp--;
                    397:     if ((i = msgp + mp -> hghmsg) > MAXFOLDER) {
                    398:        advise (NULLCP, "more than %d messages", MAXFOLDER);
                    399:        return NOTOK;
                    400:     }
                    401:     if ((mp = m_remsg (mp, 0, i)) == NULL)
                    402:        adios (NULLCP, "unable to allocate folder storage");
                    403: 
                    404:     j = mp -> hghmsg;
                    405:     mp -> hghmsg += msgp - 1;
                    406:     mp -> nummsg += msgp - 1;
                    407:     if (mp -> hghsel > msgnum)
                    408:        mp -> hghsel += msgp - 1;
                    409: 
                    410:     if (inplace && msgp > 1)
                    411:        for (i = mp -> hghmsg; j > msgnum; i--, j--) {
                    412:            if (verbosw)
                    413:                printf ("message %d becomes message %d\n", j, i);
                    414: 
                    415:            Msgs[i].m_bboard_id = Msgs[j].m_bboard_id;
                    416:            Msgs[i].m_top = Msgs[j].m_top;
                    417:            Msgs[i].m_start = Msgs[j].m_start;
                    418:            Msgs[i].m_stop = Msgs[j].m_stop;
                    419:            Msgs[i].m_scanl = NULL;
                    420:            if (Msgs[j].m_scanl) {
                    421:                free (Msgs[j].m_scanl);
                    422:                Msgs[j].m_scanl = NULL;
                    423:            }
                    424:            mp -> msgstats[i] = mp -> msgstats[j];
                    425:        }
                    426: 
                    427:     if (Msgs[msgnum].m_bboard_id == 0)
                    428:        (void) readid (msgnum);
                    429: 
                    430:     mp -> msgstats[msgnum] &= ~SELECTED;
                    431:     i = inplace ? msgnum + msgp - 1 : mp -> hghmsg;
                    432:     for (j = msgp; j >= (inplace ? 1 : 2); i--, j--) {
                    433:        if (verbosw && i != msgnum)
                    434:            printf ("message %d of digest %d becomes message %d\n",
                    435:                    j, msgnum, i);
                    436: 
                    437:        Msgs[i].m_bboard_id = Msgs[msgnum].m_bboard_id;
                    438:        Msgs[i].m_top = Msgs[j].m_top;
                    439:        Msgs[i].m_start = smsgs[j].m_start;
                    440:        Msgs[i].m_stop = smsgs[j].m_stop;
                    441:        Msgs[i].m_scanl = NULL;
                    442:        mp -> msgstats[i] = mp -> msgstats[msgnum];
                    443:     }
                    444: 
                    445:     return OK;
                    446: }
                    447: 
                    448: /*  */
                    449: 
                    450: static struct swit fileswit[] = {
                    451: #define        FIDRFT  0
                    452:     "draft", 0,
                    453: #define        FILINK  1
                    454:     "link", 0,
                    455: #define        FINLINK 2
                    456:     "nolink", 0,
                    457: #define        FIPRES  3
                    458:     "preserve", 0,
                    459: #define FINPRES        4
                    460:     "nopreserve", 0,
                    461: #define        FISRC   5
                    462:     "src +folder", 0,
                    463: #define        FIFILE  6
                    464:     "file file", 0,
                    465: #define        FIHELP  7
                    466:     "help", 4,
                    467: 
                    468:     NULL, NULL
                    469: };
                    470: 
                    471: /*  */
                    472: 
                    473: filecmd (args)
                    474: char  **args;
                    475: {
                    476:     int            linksw = 0,
                    477:            msgp = 0,
                    478:             vecp = 1,
                    479:            i,
                    480:             msgnum;
                    481:     char   *cp,
                    482:             buf[BUFSIZ],
                    483:            *msgs[MAXARGS],
                    484:            *vec[MAXARGS];
                    485: 
                    486:     if (fmsh) {
                    487:        forkcmd (args, cmd_name);
                    488:        return;
                    489:     }
                    490: 
                    491:     while (cp = *args++) {
                    492:        if (*cp == '-')
                    493:            switch (i = smatch (++cp, fileswit)) {
                    494:                case AMBIGSW: 
                    495:                    ambigsw (cp, fileswit);
                    496:                    return;
                    497:                case UNKWNSW: 
                    498:                    fprintf (stderr, "-%s unknown\n", cp);
                    499:                    return;
                    500:                case FIHELP: 
                    501:                    (void) sprintf (buf, "%s +folder... [msgs] [switches]",
                    502:                            cmd_name);
                    503:                    help (buf, fileswit);
                    504:                    return;
                    505: 
                    506:                case FILINK:
                    507:                    linksw++;
                    508:                    continue;
                    509:                case FINLINK: 
                    510:                    linksw = 0;
                    511:                    continue;
                    512: 
                    513:                case FIPRES: 
                    514:                case FINPRES: 
                    515:                    continue;
                    516: 
                    517:                case FISRC: 
                    518:                case FIDRFT:
                    519:                case FIFILE: 
                    520:                    advise (NULLCP, "sorry, -%s not allowed!", fileswit[i].sw);
                    521:                    return;
                    522:            }
                    523:        if (*cp == '+' || *cp == '@')
                    524:            vec[vecp++] = cp;
                    525:        else
                    526:            msgs[msgp++] = cp;
                    527:     }
                    528: 
                    529:     vec[0] = cmd_name;
                    530:     vec[vecp++] = "-file";
                    531:     vec[vecp] = NULL;
                    532:     if (!msgp)
                    533:        msgs[msgp++] = "cur";
                    534:     for (msgnum = 0; msgnum < msgp; msgnum++)
                    535:        if (!m_convert (mp, msgs[msgnum]))
                    536:            return;
                    537:     m_setseq (mp);
                    538: 
                    539:     interrupted = 0;
                    540:     for (msgnum = mp -> lowsel;
                    541:            msgnum <= mp -> hghsel && !interrupted;
                    542:            msgnum++)
                    543:        if (mp -> msgstats[msgnum] & SELECTED)
                    544:            if (process (msgnum, fileproc, vecp, vec)) {
                    545:                mp -> msgstats[msgnum] &= ~SELECTED;
                    546:                mp -> numsel--;
                    547:            }
                    548: 
                    549:     if (mp -> numsel != mp -> nummsg || linksw)
                    550:        m_setcur (mp, mp -> hghsel);
                    551:     if (!linksw)
                    552:        rmm ();
                    553: }
                    554: 
                    555: /*  */
                    556: 
                    557: int    filehak (args)
                    558: char  **args;
                    559: {
                    560:     int            result,
                    561:            vecp = 0;
                    562:     char   *cp,
                    563:           *cwd,
                    564:            *vec[MAXARGS];
                    565: 
                    566:     while (cp = *args++) {
                    567:        if (*cp == '-')
                    568:            switch (smatch (++cp, fileswit)) {
                    569:                case AMBIGSW: 
                    570:                case UNKWNSW: 
                    571:                case FIHELP: 
                    572:                    return NOTOK;
                    573: 
                    574:                case FILINK:
                    575:                case FINLINK: 
                    576:                case FIPRES: 
                    577:                case FINPRES: 
                    578:                    continue;
                    579: 
                    580:                case FISRC: 
                    581:                case FIDRFT:
                    582:                case FIFILE: 
                    583:                    return NOTOK;
                    584:            }
                    585:        if (*cp == '+' || *cp == '@')
                    586:            vec[vecp++] = cp;
                    587:     }
                    588:     vec[vecp] = NULL;
                    589: 
                    590:     result = NOTOK;
                    591:     cwd = NULL;
                    592:     for (vecp = 0; (cp = vec[vecp]) && result == NOTOK; vecp++) {
                    593:        if (cwd == NULL)
                    594:            cwd = getcpy (pwd ());
                    595:        (void) chdir (m_maildir (""));
                    596:        cp = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
                    597:        if (access (m_maildir (cp), 0) == NOTOK)
                    598:            result = OK;
                    599:        free (cp);
                    600:     }
                    601:     if (cwd)
                    602:        (void) chdir (cwd);
                    603: 
                    604:     return result;
                    605: }
                    606: 
                    607: /*  */
                    608: 
                    609: static struct swit foldswit[] = {
                    610: #define        FLALSW  0
                    611:     "all", 0,
                    612: #define        FLFASW  1
                    613:     "fast", 0,
                    614: #define        FLNFASW 2
                    615:     "nofast", 0,
                    616: #define        FLHDSW  3
                    617:     "header", 0,
                    618: #define        FLNHDSW 4
                    619:     "noheader", 0,
                    620: #define        FLPKSW  5
                    621:     "pack", 0,
                    622: #define        FLNPKSW 6
                    623:     "nopack", 0,
                    624: #define        FLRCSW  7
                    625:     "recurse", 0,
                    626: #define        FLNRCSW 8
                    627:     "norecurse", 0,
                    628: #define        FLTLSW  9
                    629:     "total", 0,
                    630: #define        FLNTLSW 10
                    631:     "nototal", 0,
                    632: #define        FLPRSW  11
                    633:     "print", 0,
                    634: #define        FLPUSW  12
                    635:     "push", 0,
                    636: #define        FLPOSW  13
                    637:     "pop", 0,
                    638: #define        FLLISW  14
                    639:     "list", 0,
                    640: #define        FLHELP  15
                    641:     "help", 4,
                    642: 
                    643:     NULL, NULL
                    644: };
                    645: 
                    646: /*  */
                    647: 
                    648: foldcmd (args)
                    649: char  **args;
                    650: {
                    651:     int     fastsw = 0,
                    652:             headersw = 0,
                    653:            packsw = 0,
                    654:            hole,
                    655:            msgnum;
                    656:     char   *cp,
                    657:            *folder = NULL,
                    658:            *msg = NULL,
                    659:             buf[BUFSIZ],
                    660:          **vec = args;
                    661: 
                    662:     if (args == NULL)
                    663:        goto fast;
                    664: 
                    665:     while (cp = *args++) {
                    666:        if (*cp == '-')
                    667:            switch (smatch (++cp, foldswit)) {
                    668:                case AMBIGSW: 
                    669:                    ambigsw (cp, foldswit);
                    670:                    return;
                    671:                case UNKWNSW: 
                    672:                    fprintf (stderr, "-%s unknown\n", cp);
                    673:                    return;
                    674:                case FLHELP: 
                    675:                    (void) sprintf (buf, "%s [+folder] [msg] [switches]",
                    676:                            cmd_name);
                    677:                    help (buf, foldswit);
                    678:                    return;
                    679: 
                    680:                case FLALSW:    /* not implemented */
                    681:                case FLRCSW: 
                    682:                case FLNRCSW: 
                    683:                case FLTLSW: 
                    684:                case FLNTLSW: 
                    685:                case FLPRSW:
                    686:                case FLPUSW:
                    687:                case FLPOSW:
                    688:                case FLLISW:
                    689:                    continue;
                    690: 
                    691:                case FLFASW: 
                    692:                    fastsw++;
                    693:                    continue;
                    694:                case FLNFASW: 
                    695:                    fastsw = 0;
                    696:                    continue;
                    697:                case FLHDSW: 
                    698:                    headersw++;
                    699:                    continue;
                    700:                case FLNHDSW: 
                    701:                    headersw = 0;
                    702:                    continue;
                    703:                case FLPKSW: 
                    704:                    packsw++;
                    705:                    continue;
                    706:                case FLNPKSW: 
                    707:                    packsw = 0;
                    708:                    continue;
                    709:            }
                    710:        if (*cp == '+' || *cp == '@')
                    711:            if (folder) {
                    712:                advise (NULLCP, "only one folder at a time!\n");
                    713:                return;
                    714:            }
                    715:            else
                    716:                folder = fmsh ? path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF)
                    717:                            : cp + 1;
                    718:        else
                    719:            if (msg) {
                    720:                advise (NULLCP, "only one message at a time!\n");
                    721:                return;
                    722:            }
                    723:            else
                    724:                msg = cp;
                    725:     }
                    726: 
                    727:     if (folder) {
                    728:        if (*folder == NULL) {
                    729:            advise (NULLCP, "null folder names are not permitted");
                    730:            return;
                    731:        }
                    732:        if (fmsh) {
                    733:            if (access (m_maildir (folder), 04) == NOTOK) {
                    734:                advise (folder, "unable to read");
                    735:                return;
                    736:            }
                    737:        }
                    738:        else {
                    739:            (void) strcpy (buf, folder);
                    740:            if (expand (buf) == NOTOK)
                    741:                return;
                    742:            folder = buf;
                    743:            if (access (folder, 04) == NOTOK) {
                    744:                advise (folder, "unable to read");
                    745:                return;
                    746:            }
                    747:        }
                    748:        m_reset ();
                    749: 
                    750:        if (fmsh)
                    751:            fsetup (folder);
                    752:        else
                    753:            setup (folder);
                    754:        readids (0);
                    755:        display_info (0);
                    756:     }
                    757: 
                    758:     if (msg) {
                    759:        if (!m_convert (mp, msg))
                    760:            return;
                    761:        m_setseq (mp);
                    762: 
                    763:        if (mp -> numsel > 1) {
                    764:            advise (NULLCP, "only one message at a time!");
                    765:            return;
                    766:        }
                    767:        m_setcur (mp, mp -> hghsel);
                    768:     }
                    769: 
                    770:     if (packsw) {
                    771:        if (fmsh) {
                    772:            forkcmd (vec, cmd_name);
                    773:            return;
                    774:        }
                    775: 
                    776:        if (mp -> lowmsg > 1 && (mp = m_remsg (mp, 1, mp -> hghmsg)) == NULL)
                    777:            adios (NULLCP, "unable to allocate folder storage");
                    778:        for (msgnum = mp -> lowmsg, hole = 1; msgnum <= mp -> hghmsg; msgnum++)
                    779:            if (mp -> msgstats[msgnum] & EXISTS) {
                    780:                if (msgnum != hole) {
                    781:                    Msgs[hole].m_bboard_id = Msgs[msgnum].m_bboard_id;
                    782:                    Msgs[hole].m_top = Msgs[msgnum].m_top;
                    783:                    Msgs[hole].m_start = Msgs[msgnum].m_start;
                    784:                    Msgs[hole].m_stop = Msgs[msgnum].m_stop;
                    785:                    Msgs[hole].m_scanl = NULL;
                    786:                    if (Msgs[msgnum].m_scanl) {
                    787:                        free (Msgs[msgnum].m_scanl);
                    788:                        Msgs[msgnum].m_scanl = NULL;
                    789:                    }
                    790:                    mp -> msgstats[hole] = mp -> msgstats[msgnum];
                    791:                    if (mp -> curmsg == msgnum)
                    792:                        m_setcur (mp, hole);
                    793:                }
                    794:                hole++;
                    795:            }
                    796:        if (mp -> nummsg > 0) {
                    797:            mp -> lowmsg = 1;
                    798:            mp -> hghmsg = hole - 1;
                    799:        }
                    800:        mp -> msgflags |= MODIFIED;
                    801:        modified++;
                    802:     }
                    803: 
                    804: fast: ;
                    805:     if (fastsw)
                    806:        printf ("%s\n", fmsh ? fmsh : mp -> foldpath);
                    807:     else {
                    808:        if (headersw)
                    809:            printf ("\t\tFolder  %*s# of messages (%*srange%*s); cur%*smsg\n",
                    810:                DMAXFOLDER, "", DMAXFOLDER - 2, "", DMAXFOLDER - 2, "",
                    811:                DMAXFOLDER - 2, "");
                    812:        printf (args ? "%22s  " : "%s ", fmsh ? fmsh : mp -> foldpath);
                    813:        if (mp -> hghmsg == 0)
                    814:            printf ("has   no messages%*s",
                    815:                    mp -> msgflags & OTHERS ? DMAXFOLDER * 2 + 4 : 0, "");
                    816:        else {
                    817:            printf ("has %*d message%s (%*d-%*d)",
                    818:                    DMAXFOLDER, mp -> nummsg, mp -> nummsg != 1 ? "s" : "",
                    819:                    DMAXFOLDER, mp -> lowmsg, DMAXFOLDER, mp -> hghmsg);
                    820:            if (mp -> curmsg >= mp -> lowmsg
                    821:                    && mp -> curmsg <= mp -> hghmsg)
                    822:                printf ("; cur=%*d", DMAXFOLDER, mp -> curmsg);
                    823:        }
                    824:        printf (".\n");
                    825:     }
                    826: }
                    827: 
                    828: /*  */
                    829: 
                    830: static struct swit forwswit[] = {
                    831: #define        FOANSW  0
                    832:     "annotate", 0,
                    833: #define        FONANSW 1
                    834:     "noannotate", 0,
                    835: #define        FODFSW  2
                    836:     "draftfolder +folder", 0,
                    837: #define        FODMSW  3
                    838:     "draftmessage msg", 0,
                    839: #define        FONDFSW 4
                    840:     "nodraftfolder", 0,
                    841: #define        FOEDTSW 5
                    842:     "editor editor", 0,
                    843: #define        FONEDSW 6
                    844:     "noedit", 0,
                    845: #define        FOFTRSW 7
                    846:     "filter filterfile", 0,
                    847: #define        FOFRMSW 8
                    848:     "form formfile", 0,
                    849: #define        FOFTSW  9
                    850:     "format", 5,
                    851: #define        FONFTSW 10
                    852:     "noformat", 7,
                    853: #define        FOINSW  11
                    854:     "inplace", 0,
                    855: #define        FONINSW 12
                    856:     "noinplace", 0,
                    857: #define        FOWHTSW 13
                    858:     "whatnowproc program", 0,
                    859: #define        FONWTSW 14
                    860:     "nowhatnow", 0,
                    861: #define        FOHELP  15
                    862:     "help", 4,
                    863: 
                    864:     NULL, NULL
                    865: };
                    866: 
                    867: /*  */
                    868: 
                    869: forwcmd (args)
                    870: char  **args;
                    871: {
                    872:     int            msgp = 0,
                    873:             vecp = 1,
                    874:             msgnum;
                    875:     char   *cp,
                    876:            *filter = NULL,
                    877:             buf[BUFSIZ],
                    878:            *msgs[MAXARGS],
                    879:            *vec[MAXARGS];
                    880: 
                    881:     if (fmsh) {
                    882:        forkcmd (args, cmd_name);
                    883:        return;
                    884:     }
                    885: 
                    886:     while (cp = *args++) {
                    887:        if (*cp == '-')
                    888:            switch (smatch (++cp, forwswit)) {
                    889:                case AMBIGSW: 
                    890:                    ambigsw (cp, forwswit);
                    891:                    return;
                    892:                case UNKWNSW: 
                    893:                    fprintf (stderr, "-%s unknown\n", cp);
                    894:                    return;
                    895:                case FOHELP: 
                    896:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                    897:                    help (buf, forwswit);
                    898:                    return;
                    899: 
                    900:                case FOANSW:    /* not implemented */
                    901:                case FONANSW: 
                    902:                case FOINSW: 
                    903:                case FONINSW: 
                    904:                    continue;
                    905: 
                    906:                case FONDFSW:
                    907:                case FONEDSW:
                    908:                case FONWTSW:
                    909:                    vec[vecp++] = --cp;
                    910:                    continue;
                    911: 
                    912:                case FOEDTSW: 
                    913:                case FOFRMSW: 
                    914:                case FODFSW:
                    915:                case FODMSW:
                    916:                case FOWHTSW:
                    917:                    vec[vecp++] = --cp;
                    918:                    if (!(cp = *args++) || *cp == '-') {
                    919:                        advise (NULLCP, "missing argument to %s", args[-2]);
                    920:                        return;
                    921:                    }
                    922:                    vec[vecp++] = cp;
                    923:                    continue;
                    924:                case FOFTRSW: 
                    925:                    if (!(filter = *args++) || *filter == '-') {
                    926:                        advise (NULLCP, "missing argument to %s", args[-2]);
                    927:                        return;
                    928:                    }
                    929:                    continue;
                    930:                case FOFTSW: 
                    931:                    if (access (filter = myfilter, 04) == NOTOK) {
                    932:                        advise (filter, "unable to read default filter file");
                    933:                        return;
                    934:                    }
                    935:                    continue;
                    936:                case FONFTSW: 
                    937:                    filter = NULL;
                    938:                    continue;
                    939:            }
                    940:        if (*cp == '+' || *cp == '@') {
                    941:            advise (NULLCP, "sorry, no folders allowed!");
                    942:            return;
                    943:        }
                    944:        else
                    945:            msgs[msgp++] = cp;
                    946:     }
                    947: 
                    948:                                        /* foil search of .mh_profile */
                    949:     (void) sprintf (buf, "%sXXXXXX", invo_name);
                    950:     vec[0] = mktemp (buf);
                    951:     vec[vecp++] = "-file";
                    952:     vec[vecp] = NULL;
                    953:     if (!msgp)
                    954:        msgs[msgp++] = "cur";
                    955:     for (msgnum = 0; msgnum < msgp; msgnum++)
                    956:        if (!m_convert (mp, msgs[msgnum]))
                    957:            return;
                    958:     m_setseq (mp);
                    959: 
                    960:     if (filter) {
                    961:        (void) strcpy (buf, filter);
                    962:        if (expand (buf) == NOTOK)
                    963:            return;
                    964:        if (access (filter = getcpy (libpath (buf)), 04) == NOTOK) {
                    965:            advise (filter, "unable to read");
                    966:            free (filter);
                    967:            return;
                    968:        }
                    969:     }
                    970:     forw (cmd_name, filter, vecp, vec);
                    971:     m_setcur (mp, mp -> hghsel);
                    972:     if (filter)
                    973:        free (filter);
                    974: }
                    975: 
                    976: /*  */
                    977: 
                    978: static forw (proc, filter, vecp, vec)
                    979: int     vecp;
                    980: char   *proc,
                    981:        *filter,
                    982:       **vec;
                    983: {
                    984:     int     i,
                    985:             child_id,
                    986:             msgnum,
                    987:             msgcnt;
                    988:     char    tmpfil[80],
                    989:            *args[MAXARGS];
                    990:     FILE   *out;
                    991: 
                    992:     (void) strcpy (tmpfil, m_tmpfil (invo_name));
                    993:     interrupted = 0;
                    994:     if (filter)
                    995:        switch (child_id = fork ()) {
                    996:            case NOTOK: 
                    997:                advise ("fork", "unable to");
                    998:                return;
                    999: 
                   1000:            case OK:            /* "trust me" */
                   1001:                if (freopen (tmpfil, "w", stdout) == NULL) {
                   1002:                    fprintf (stderr, "unable to create ");
                   1003:                    perror (tmpfil);
                   1004:                    _exit (1);
                   1005:                }
                   1006:                args[0] = r1bindex (mhlproc, '/');
                   1007:                i = 1;
                   1008:                args[i++] = "-forwall";
                   1009:                args[i++] = "-form";
                   1010:                args[i++] = filter;
                   1011:                for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                   1012:                    if (mp -> msgstats[msgnum] & SELECTED)
                   1013:                        args[i++] = getcpy (m_name (msgnum));
                   1014:                args[i] = NULL;
                   1015:                (void) mhlsbr (i, args, mhl_action);
                   1016:                m_eomsbr ((int (*) ()) 0);
                   1017:                (void) fclose (stdout);
                   1018:                _exit (0);
                   1019: 
                   1020:            default: 
                   1021:                if (pidXwait (child_id, NULLCP))
                   1022:                    interrupted++;
                   1023:                break;
                   1024:        }
                   1025:     else {
                   1026:        if ((out = fopen (tmpfil, "w")) == NULL) {
                   1027:            advise (tmpfil, "unable to create temporary file");
                   1028:            return;
                   1029:        }
                   1030: 
                   1031:        msgcnt = 1;
                   1032:        for (msgnum = mp -> lowsel;
                   1033:                msgnum <= mp -> hghsel && !interrupted;
                   1034:                msgnum++)
                   1035:            if (mp -> msgstats[msgnum] & SELECTED) {
                   1036:                fprintf (out, "\n\n-------");
                   1037:                if (msgnum == mp -> lowsel)
                   1038:                    fprintf (out, " Forwarded Message%s",
                   1039:                            mp -> numsel > 1 ? "s" : "");
                   1040:                else
                   1041:                    fprintf (out, " Message %d", msgcnt);
                   1042:                fprintf (out, "\n\n");
                   1043:                copy_digest (msgnum, out);
                   1044:                msgcnt++;
                   1045:            }
                   1046: 
                   1047:        fprintf (out, "\n\n------- End of Forwarded Message%s\n",
                   1048:                mp -> numsel > 1 ? "s" : "");
                   1049:        (void) fclose (out);
                   1050:     }
                   1051: 
                   1052:     (void) fflush (stdout);
                   1053:     if (!interrupted)
                   1054:        switch (child_id = fork ()) {
                   1055:            case NOTOK: 
                   1056:                advise ("fork", "unable to");
                   1057:                break;
                   1058: 
                   1059:            case OK: 
                   1060:                closefds (3);
                   1061:                (void) signal (SIGINT, istat);
                   1062:                (void) signal (SIGQUIT, qstat);
                   1063: 
                   1064:                vec[vecp++] = tmpfil;
                   1065:                vec[vecp] = NULL;
                   1066: 
                   1067:                execvp (proc, vec);
                   1068:                fprintf (stderr, "unable to exec ");
                   1069:                perror (proc);
                   1070:                _exit (1);
                   1071: 
                   1072:            default: 
                   1073:                (void) pidXwait (child_id, NULLCP);
                   1074:                break;
                   1075:        }
                   1076: 
                   1077:     (void) unlink (tmpfil);
                   1078: }
                   1079: 
                   1080: /*  */
                   1081: 
                   1082: static char *hlpmsg[] = {
                   1083:     "The %s program emulates many of the commands found in the Rand MH",
                   1084:     "system.  Instead of operating on MH folders, commands to %s concern",
                   1085:     "a single file.",
                   1086:     "",
                   1087:     "To see the list of commands available, just type a ``?'' followed by",
                   1088:     "the RETURN key.  To find out what switches each command takes, type",
                   1089:     "the name of the command followed by ``-help''.  To leave %s, use the",
                   1090:     "``quit'' command.",
                   1091:     "",
                   1092:     "Although a lot of MH commands are found in %s, not all are fully",
                   1093:     "implemented.  %s will always recognize all legal switches for a",
                   1094:     "given command though, and will let you know when you ask for an",
                   1095:     "option that it is unable to perform.",
                   1096:     "",
                   1097:     "Running %s is fun, but using MH from your shell is far superior.",
                   1098:     "After you have familiarized yourself with the MH style by using %s,",
                   1099:     "you should try using MH from the shell.  You can still use %s for",
                   1100:     "message files that aren't in MH format, such as BBoard files.",
                   1101:     NULL
                   1102: };
                   1103: 
                   1104: 
                   1105: /* ARGSUSED */
                   1106: 
                   1107: helpcmd (args)
                   1108: char  **args;
                   1109: {
                   1110:     int     i;
                   1111: 
                   1112:     for (i = 0; hlpmsg[i]; i++) {
                   1113:        printf (hlpmsg[i], invo_name);
                   1114:        (void) putchar ('\n');
                   1115:     }
                   1116: }
                   1117: 
                   1118: /*  */
                   1119: 
                   1120: static struct swit markswit[] = {
                   1121: #define        MADDSW  0
                   1122:     "add", 0,
                   1123: #define        MDELSW  1
                   1124:     "delete", 0,
                   1125: #define        MLSTSW  2
                   1126:     "list", 0,
                   1127: #define        MSEQSW  3
                   1128:     "sequence name", 0,
                   1129: #define        MPUBSW  4
                   1130:     "public", 0,
                   1131: #define        MNPUBSW 5
                   1132:     "nopublic", 0,
                   1133: #define        MZERSW  6
                   1134:     "zero", 0,
                   1135: #define        MNZERSW 7
                   1136:     "nozero", 0,
                   1137: #define        MHELP   8
                   1138:     "help", 4,
                   1139: #define        MDBUGSW 9
                   1140:     "debug", -5,
                   1141: 
                   1142:     NULL, NULL
                   1143: };
                   1144: 
                   1145: /*  */
                   1146: 
                   1147: markcmd (args)
                   1148: char  **args;
                   1149: {
                   1150:     int     addsw = 0,
                   1151:             deletesw = 0,
                   1152:             debugsw = 0,
                   1153:             listsw = 0,
                   1154:             zerosw = 0,
                   1155:             seqp = 0,
                   1156:             msgp = 0,
                   1157:             i,
                   1158:             msgnum;
                   1159:     char   *cp,
                   1160:             buf[BUFSIZ],
                   1161:            *seqs[NATTRS + 1],
                   1162:            *msgs[MAXARGS];
                   1163: 
                   1164:     while (cp = *args++) {
                   1165:        if (*cp == '-')
                   1166:            switch (smatch (++cp, markswit)) {
                   1167:                case AMBIGSW: 
                   1168:                    ambigsw (cp, markswit);
                   1169:                    return;
                   1170:                case UNKWNSW: 
                   1171:                    fprintf (stderr, "-%s unknown\n", cp);
                   1172:                    return;
                   1173:                case MHELP: 
                   1174:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                   1175:                    help (buf, markswit);
                   1176:                    return;
                   1177: 
                   1178:                case MADDSW: 
                   1179:                    addsw++;
                   1180:                    deletesw = listsw = 0;
                   1181:                    continue;
                   1182:                case MDELSW: 
                   1183:                    deletesw++;
                   1184:                    addsw = listsw = 0;
                   1185:                    continue;
                   1186:                case MLSTSW: 
                   1187:                    listsw++;
                   1188:                    addsw = deletesw = 0;
                   1189:                    continue;
                   1190: 
                   1191:                case MSEQSW: 
                   1192:                    if (!(cp = *args++) || *cp == '-') {
                   1193:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   1194:                        return;
                   1195:                    }
                   1196:                    if (seqp < NATTRS)
                   1197:                        seqs[seqp++] = cp;
                   1198:                    else {
                   1199:                        advise (NULLCP, "only %d sequences allowed!", NATTRS);
                   1200:                        return;
                   1201:                    }
                   1202:                    continue;
                   1203: 
                   1204:                case MPUBSW:    /* not implemented */
                   1205:                case MNPUBSW: 
                   1206:                    continue;
                   1207: 
                   1208:                case MDBUGSW: 
                   1209:                    debugsw++;
                   1210:                    continue;
                   1211: 
                   1212:                case MZERSW: 
                   1213:                    zerosw++;
                   1214:                    continue;
                   1215:                case MNZERSW: 
                   1216:                    zerosw = 0;
                   1217:                    continue;
                   1218:            }
                   1219:        if (*cp == '+' || *cp == '@') {
                   1220:            advise (NULLCP, "sorry, no folders allowed!");
                   1221:            return;
                   1222:        }
                   1223:        else
                   1224:            msgs[msgp++] = cp;
                   1225:     }
                   1226: 
                   1227:     if (!addsw && !deletesw && !listsw)
                   1228:        if (seqp)
                   1229:            addsw++;
                   1230:        else
                   1231:            if (debugsw)
                   1232:                listsw++;
                   1233:            else {
                   1234:                seqs[seqp++] = "unseen";
                   1235:                deletesw++;
                   1236:                zerosw = 0;
                   1237:                if (!msgp)
                   1238:                    msgs[msgp++] = "all";
                   1239:            }
                   1240: 
                   1241:     if (!msgp)
                   1242:        msgs[msgp++] = listsw ? "all" :"cur";
                   1243:     for (msgnum = 0; msgnum < msgp; msgnum++)
                   1244:        if (!m_convert (mp, msgs[msgnum]))
                   1245:            return;
                   1246: 
                   1247:     if (debugsw) {
                   1248:        printf ("invo_name=%s mypath=%s defpath=%s\n",
                   1249:                invo_name, mypath, defpath);
                   1250:        printf ("ctxpath=%s context flags=%s\n",
                   1251:                ctxpath, sprintb (buf, (unsigned) ctxflags, DBITS));
                   1252:        printf ("foldpath=%s flags=%s\n",
                   1253:                mp -> foldpath,
                   1254:                sprintb (buf, (unsigned) mp -> msgflags, FBITS));
                   1255:        printf ("hghmsg=%d lowmsg=%d nummsg=%d curmsg=%d\n",
                   1256:                mp -> hghmsg, mp -> lowmsg, mp -> nummsg, mp -> curmsg);
                   1257:        printf ("lowsel=%d hghsel=%d numsel=%d\n",
                   1258:                mp -> lowsel, mp -> hghsel, mp -> numsel);
                   1259: #ifndef        MTR
                   1260:        printf ("lowoff=%d hghoff=%d\n",
                   1261:                mp -> lowoff, mp -> hghoff);
                   1262: #else  MTR
                   1263:        printf ("lowoff=%d hghoff=%d msgbase=0x%x msgstats=0x%x\n",
                   1264:                mp -> lowoff, mp -> hghoff, mp -> msgbase, mp -> msgstats);
                   1265: #endif MTR
                   1266:     }
                   1267: 
                   1268:     if (seqp == 0 && (addsw || deletesw)) {
                   1269:        advise (NULLCP, "-%s requires at least one -sequence argument",
                   1270:                addsw ? "add" : "delete");
                   1271:        return;
                   1272:     }
                   1273:     seqs[seqp] = NULL;
                   1274: 
                   1275:     if (addsw)
                   1276:        for (seqp = 0; seqs[seqp]; seqp++) {
                   1277:            if (zerosw && !m_seqnew (mp, seqs[seqp], 0))
                   1278:                return;
                   1279:            for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                   1280:                if (mp -> msgstats[msgnum] & SELECTED)
                   1281:                    if (!m_seqadd (mp, seqs[seqp], msgnum, 0))
                   1282:                        return;
                   1283:        }
                   1284: 
                   1285:     if (deletesw)
                   1286:        for (seqp = 0; seqs[seqp]; seqp++) {
                   1287:            if (zerosw)
                   1288:                for (msgnum = mp -> lowmsg; msgnum <= mp -> hghmsg; msgnum++)
                   1289:                    if (mp -> msgstats[msgnum] & EXISTS)
                   1290:                        if (!m_seqadd (mp, seqs[seqp], msgnum, 0))
                   1291:                            return;
                   1292:            for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                   1293:                if (mp -> msgstats[msgnum] & SELECTED)
                   1294:                    if (!m_seqdel (mp, seqs[seqp], msgnum))
                   1295:                        return;
                   1296:        }
                   1297: 
                   1298:     if (listsw) {
                   1299:        int     bits = FFATTRSLOT;
                   1300: 
                   1301:        if (seqp == 0)
                   1302:            for (i = 0; mp -> msgattrs[i]; i++)
                   1303:                printf ("%s%s: %s\n", mp -> msgattrs[i],
                   1304:                        mp -> attrstats & (1 << (bits + i))
                   1305:                        ? " (private)" : "",
                   1306:                        m_seq (mp, mp -> msgattrs[i]));
                   1307:        else
                   1308:            for (seqp = 0; seqs[seqp]; seqp++)
                   1309:                printf ("%s%s: %s\n", seqs[seqp], m_seq (mp, seqs[seqp]));
                   1310: 
                   1311:        interrupted = 0;
                   1312:        if (debugsw)
                   1313:            for (msgnum = mp -> lowsel;
                   1314:                    msgnum <= mp -> hghsel && !interrupted;
                   1315:                    msgnum++)
                   1316:                if (mp -> msgstats[msgnum] & SELECTED) {
                   1317:                    printf ("%*d: id=%d top=%d start=%ld stop=%ld %s\n",
                   1318:                            DMAXFOLDER, msgnum,
                   1319:                            Msgs[msgnum].m_bboard_id, Msgs[msgnum].m_top,
                   1320:                            Msgs[msgnum].m_start, Msgs[msgnum].m_stop,
                   1321:                            sprintb (buf, (unsigned) mp -> msgstats[msgnum],
                   1322:                                m_seqbits (mp)));
                   1323:                    if (Msgs[msgnum].m_scanl)
                   1324:                        printf ("%s", Msgs[msgnum].m_scanl);
                   1325:                }                           
                   1326:     }
                   1327: }
                   1328: 
                   1329: /*  */
                   1330: 
                   1331: static struct swit packswit[] = {
                   1332: #define        PAFISW  0
                   1333:     "file name", 0,
                   1334: 
                   1335: #define        PAHELP  1
                   1336:     "help", 4,
                   1337: 
                   1338:     NULL, NULL
                   1339: };
                   1340: 
                   1341: /*  */
                   1342: 
                   1343: packcmd (args)
                   1344: char  **args;
                   1345: {
                   1346:     int     msgp = 0,
                   1347:             md,
                   1348:             msgnum;
                   1349:     char   *cp,
                   1350:            *file = NULL,
                   1351:             buf[BUFSIZ],
                   1352:            *msgs[MAXARGS];
                   1353:     struct stat st;
                   1354: 
                   1355:     if (fmsh) {
                   1356:        forkcmd (args, cmd_name);
                   1357:        return;
                   1358:     }
                   1359: 
                   1360:     while (cp = *args++) {
                   1361:        if (*cp == '-')
                   1362:            switch (smatch (++cp, packswit)) {
                   1363:                case AMBIGSW: 
                   1364:                    ambigsw (cp, packswit);
                   1365:                    return;
                   1366:                case UNKWNSW: 
                   1367:                    fprintf (stderr, "-%s unknown\n", cp);
                   1368:                    return;
                   1369:                case PAHELP: 
                   1370:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                   1371:                    help (buf, packswit);
                   1372:                    return;
                   1373: 
                   1374:                case PAFISW: 
                   1375:                    if (!(file = *args++) || *file == '-') {
                   1376:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   1377:                        return;
                   1378:                    }
                   1379:                    continue;
                   1380:            }
                   1381:        if (*cp == '+' || *cp == '@') {
                   1382:            advise (NULLCP, "sorry, no folders allowed!");
                   1383:            return;
                   1384:        }
                   1385:        else
                   1386:            msgs[msgp++] = cp;
                   1387:     }
                   1388: 
                   1389:     if (!file)
                   1390:        file = "./msgbox";
                   1391:     file = path (file, TFILE);
                   1392:     if (stat (file, &st) == NOTOK) {
                   1393:        if (errno != ENOENT) {
                   1394:            advise (file, "error on file");
                   1395:            goto done_pack;
                   1396:        }
                   1397:        md = getanswer (cp = concat ("Create file \"", file, "\"? ", NULLCP));
                   1398:        free (cp);
                   1399:        if (!md)
                   1400:            goto done_pack;
                   1401:     }
                   1402: 
                   1403:     if (!msgp)
                   1404:        msgs[msgp++] = "all";
                   1405:     for (msgnum = 0; msgnum < msgp; msgnum++)
                   1406:        if (!m_convert (mp, msgs[msgnum]))
                   1407:            goto done_pack;
                   1408:     m_setseq (mp);
                   1409: 
                   1410:     if ((md = mbx_open (file, getuid (), getgid (), m_gmprot ())) == NOTOK) {
                   1411:        advise (file, "unable to open");
                   1412:        goto done_pack;
                   1413:     }
                   1414:     for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                   1415:        if (mp -> msgstats[msgnum] & SELECTED)
                   1416:            if (pack (file, md, msgnum) == NOTOK)
                   1417:                break;
                   1418:     (void) mbx_close (file, md);
                   1419: 
                   1420:     if (mp -> hghsel != mp -> curmsg)
                   1421:        m_setcur (mp, mp -> lowsel);
                   1422: 
                   1423: done_pack: ;
                   1424:     free (file);
                   1425: }
                   1426: 
                   1427: /*  */
                   1428: 
                   1429: int    pack (mailbox, md, msgnum)
                   1430: char   *mailbox;
                   1431: int     md,
                   1432:         msgnum;
                   1433: {
                   1434:     register FILE *zp;
                   1435: 
                   1436:     if (Msgs[msgnum].m_bboard_id == 0)
                   1437:        (void) readid (msgnum);
                   1438: 
                   1439:     zp = msh_ready (msgnum, 1);
                   1440:     return mbx_write (mailbox, md, zp, Msgs[msgnum].m_bboard_id,
                   1441:            ftell (zp), Msgs[msgnum].m_stop, 1, 1);
                   1442: }
                   1443: 
                   1444: /*  */
                   1445: 
                   1446: int    packhak (args)
                   1447: char  **args;
                   1448: {
                   1449:     int            result;
                   1450:     char   *cp,
                   1451:           *file = NULL;
                   1452: 
                   1453:     while (cp = *args++) {
                   1454:        if (*cp == '-')
                   1455:            switch (smatch (++cp, packswit)) {
                   1456:                case AMBIGSW: 
                   1457:                case UNKWNSW: 
                   1458:                case PAHELP: 
                   1459:                    return NOTOK;
                   1460: 
                   1461:                case PAFISW: 
                   1462:                    if (!(file = *args++) || *file == '-') 
                   1463:                        return NOTOK;
                   1464:                    continue;
                   1465:            }
                   1466:        if (*cp == '+' || *cp == '@')
                   1467:            return NOTOK;
                   1468:     }
                   1469: 
                   1470:     file = path (file ? file : "./msgbox", TFILE);
                   1471:     result = access (file, 0) == NOTOK ? OK : NOTOK;
                   1472:     free (file);
                   1473: 
                   1474:     return result;
                   1475: }
                   1476: 
                   1477: /*  */
                   1478: 
                   1479: static struct swit pickswit[] = {
                   1480: #define        PIANSW  0
                   1481:     "and", 0,
                   1482: #define        PIORSW  1
                   1483:     "or", 0,
                   1484: #define        PINTSW  2
                   1485:     "not", 0,
                   1486: #define        PILBSW  3
                   1487:     "lbrace", 0,
                   1488: #define        PIRBSW  4
                   1489:     "rbrace", 0,
                   1490: 
                   1491: #define        PICCSW  5
                   1492:     "cc  pattern", 0,
                   1493: #define        PIDASW  6
                   1494:     "date  pattern", 0,
                   1495: #define        PIFRSW  7
                   1496:     "from  pattern", 0,
                   1497: #define        PISESW  8
                   1498:     "search  pattern", 0,
                   1499: #define        PISUSW  9
                   1500:     "subject  pattern", 0,
                   1501: #define        PITOSW  10
                   1502:     "to  pattern", 0,
                   1503: #define        PIOTSW  11
                   1504:     "-othercomponent  pattern", 15,
                   1505: #define        PIAFSW  12
                   1506:     "after date", 0,
                   1507: #define        PIBFSW  13
                   1508:     "before date", 0,
                   1509: #define        PIDFSW  14
                   1510:     "datefield field", 5,
                   1511: #define        PISQSW  15
                   1512:     "sequence name", 0,
                   1513: #define        PIPUSW  16
                   1514:     "public", 0,
                   1515: #define        PINPUSW 17
                   1516:     "nopublic", 0,
                   1517: #define        PIZRSW  18
                   1518:     "zero", 0,
                   1519: #define        PINZRSW 19
                   1520:     "nozero", 0,
                   1521: #define        PILISW  20
                   1522:     "list", 0,
                   1523: #define        PINLISW 21
                   1524:     "nolist", 0,
                   1525: #define        PIHELP  22
                   1526:     "help", 4,
                   1527: 
                   1528:     NULL, NULL
                   1529: };
                   1530: 
                   1531: /*  */
                   1532: 
                   1533: pickcmd (args)
                   1534: char  **args;
                   1535: {
                   1536:     int     zerosw = 1,
                   1537:             msgp = 0,
                   1538:             seqp = 0,
                   1539:             vecp = 0,
                   1540:             hi,
                   1541:             lo,
                   1542:             msgnum;
                   1543:     char   *cp,
                   1544:             buf[BUFSIZ],
                   1545:            *msgs[MAXARGS],
                   1546:            *seqs[NATTRS],
                   1547:            *vec[MAXARGS];
                   1548:     register FILE *zp;
                   1549: 
                   1550:     while (cp = *args++) {
                   1551:        if (*cp == '-') {
                   1552:            if (*++cp == '-') {
                   1553:                vec[vecp++] = --cp;
                   1554:                goto pattern;
                   1555:            }
                   1556:            switch (smatch (cp, pickswit)) {
                   1557:                case AMBIGSW: 
                   1558:                    ambigsw (cp, pickswit);
                   1559:                    return;
                   1560:                case UNKWNSW: 
                   1561:                    fprintf (stderr, "-%s unknown\n", cp);
                   1562:                    return;
                   1563:                case PIHELP: 
                   1564:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                   1565:                    help (buf, pickswit);
                   1566:                    return;
                   1567: 
                   1568:                case PICCSW: 
                   1569:                case PIDASW: 
                   1570:                case PIFRSW: 
                   1571:                case PISUSW: 
                   1572:                case PITOSW: 
                   1573:                case PIDFSW: 
                   1574:                case PIAFSW: 
                   1575:                case PIBFSW: 
                   1576:                case PISESW: 
                   1577:                    vec[vecp++] = --cp;
                   1578: pattern: ;
                   1579:                    if (!(cp = *args++)) {/* allow -xyz arguments */
                   1580:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   1581:                        return;
                   1582:                    }
                   1583:                    vec[vecp++] = cp;
                   1584:                    continue;
                   1585:                case PIOTSW: 
                   1586:                    advise (NULLCP, "internal error!");
                   1587:                    return;
                   1588:                case PIANSW: 
                   1589:                case PIORSW: 
                   1590:                case PINTSW: 
                   1591:                case PILBSW: 
                   1592:                case PIRBSW: 
                   1593:                    vec[vecp++] = --cp;
                   1594:                    continue;
                   1595: 
                   1596:                case PISQSW: 
                   1597:                    if (!(cp = *args++) || *cp == '-') {
                   1598:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   1599:                        return;
                   1600:                    }
                   1601:                    if (seqp < NATTRS)
                   1602:                        seqs[seqp++] = cp;
                   1603:                    else {
                   1604:                        advise (NULLCP, "only %d sequences allowed!", NATTRS);
                   1605:                        return;
                   1606:                    }
                   1607:                    continue;
                   1608:                case PIZRSW: 
                   1609:                    zerosw++;
                   1610:                    continue;
                   1611:                case PINZRSW: 
                   1612:                    zerosw = 0;
                   1613:                    continue;
                   1614: 
                   1615:                case PIPUSW:    /* not implemented */
                   1616:                case PINPUSW: 
                   1617:                case PILISW: 
                   1618:                case PINLISW: 
                   1619:                    continue;
                   1620:            }
                   1621:        }
                   1622:        if (*cp == '+' || *cp == '@') {
                   1623:            advise (NULLCP, "sorry, no folders allowed!");
                   1624:            return;
                   1625:        }
                   1626:        else
                   1627:            msgs[msgp++] = cp;
                   1628:     }
                   1629:     vec[vecp] = NULL;
                   1630: 
                   1631:     if (!msgp)
                   1632:        msgs[msgp++] = "all";
                   1633:     for (msgnum = 0; msgnum < msgp; msgnum++)
                   1634:        if (!m_convert (mp, msgs[msgnum]))
                   1635:            return;
                   1636:     m_setseq (mp);
                   1637: 
                   1638:     interrupted = 0;
                   1639:     if (!pcompile (vec, NULLCP))
                   1640:        return;
                   1641: 
                   1642:     lo = mp -> lowsel;
                   1643:     hi = mp -> hghsel;
                   1644: 
                   1645:     for (msgnum = mp -> lowsel;
                   1646:            msgnum <= mp -> hghsel && !interrupted;
                   1647:            msgnum++)
                   1648:        if (mp -> msgstats[msgnum] & SELECTED) {
                   1649:            zp = msh_ready (msgnum, 1);
                   1650:            if (pmatches (zp, msgnum, fmsh ? 0L : Msgs[msgnum].m_start,
                   1651:                        fmsh ? 0L : Msgs[msgnum].m_stop)) {
                   1652:                if (msgnum < lo)
                   1653:                    lo = msgnum;
                   1654:                if (msgnum > hi)
                   1655:                    hi = msgnum;
                   1656:            }
                   1657:            else {
                   1658:                mp -> msgstats[msgnum] &= ~SELECTED;
                   1659:                mp -> numsel--;
                   1660:            }
                   1661:        }
                   1662: 
                   1663:     if (interrupted)
                   1664:        return;
                   1665: 
                   1666:     mp -> lowsel = lo;
                   1667:     mp -> hghsel = hi;
                   1668: 
                   1669:     if (mp -> numsel <= 0) {
                   1670:        advise (NULLCP, "no messages match specification");
                   1671:        return;
                   1672:     }
                   1673: 
                   1674:     seqs[seqp] = NULL;
                   1675:     for (seqp = 0; seqs[seqp]; seqp++) {
                   1676:        if (zerosw && !m_seqnew (mp, seqs[seqp], 0))
                   1677:            return;
                   1678:        for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                   1679:            if (mp -> msgstats[msgnum] & SELECTED)
                   1680:                if (!m_seqadd (mp, seqs[seqp], msgnum, 0))
                   1681:                    return;
                   1682:     }
                   1683: 
                   1684:     printf ("%d hit%s\n", mp -> numsel, mp -> numsel == 1 ? "" : "s");
                   1685: }
                   1686: 
                   1687: /*  */
                   1688: 
                   1689: static struct swit replswit[] = {
                   1690: #define        REANSW  0
                   1691:     "annotate", 0,
                   1692: #define        RENANSW 1
                   1693:     "noannotate", 0,
                   1694: #define        RECCSW  2
                   1695:     "cc type", 0,
                   1696: #define        RENCCSW 3
                   1697:     "nocc type", 0,
                   1698: #define        REDFSW  4
                   1699:     "draftfolder +folder", 0,
                   1700: #define        REDMSW  5
                   1701:     "draftmessage msg", 0,
                   1702: #define        RENDFSW 6
                   1703:     "nodraftfolder", 0,
                   1704: #define        REEDTSW 7
                   1705:     "editor editor", 0,
                   1706: #define        RENEDSW 8
                   1707:     "noedit", 0,
                   1708: #define        REFCCSW 9
                   1709:     "fcc +folder", 0,
                   1710: #define        REFLTSW 10
                   1711:     "filter filterfile", 0,
                   1712: #define        REFRMSW 11
                   1713:     "form formfile", 0,
                   1714: #define        REFRSW  12
                   1715:     "format", 5,
                   1716: #define        RENFRSW 13
                   1717:     "noformat", 7,
                   1718: #define        REINSW  14
                   1719:     "inplace", 0,
                   1720: #define        RENINSW 15
                   1721:     "noinplace", 0,
                   1722: #define        REQUSW  16
                   1723:     "query", 0,
                   1724: #define        RENQUSW 17
                   1725:     "noquery", 0,
                   1726: #define        REWHTSW 18
                   1727:     "whatnowproc program", 0,
                   1728: #define        RENWTSW 19
                   1729:     "nowhatnow", 0,
                   1730: #define        REWIDSW 20
                   1731:     "width columns", 0,
                   1732: #define        REHELP  21
                   1733:     "help", 4,
                   1734: 
                   1735:     NULL, NULL
                   1736: };
                   1737: 
                   1738: /*  */
                   1739: 
                   1740: replcmd (args)
                   1741: char  **args;
                   1742: {
                   1743:     int     vecp = 1;
                   1744:     char   *cp,
                   1745:            *msg = NULL,
                   1746:             buf[BUFSIZ],
                   1747:            *vec[MAXARGS];
                   1748: 
                   1749:     if (fmsh) {
                   1750:        forkcmd (args, cmd_name);
                   1751:        return;
                   1752:     }
                   1753: 
                   1754:     while (cp = *args++) {
                   1755:        if (*cp == '-')
                   1756:            switch (smatch (++cp, replswit)) {
                   1757:                case AMBIGSW: 
                   1758:                    ambigsw (cp, replswit);
                   1759:                    return;
                   1760:                case UNKWNSW: 
                   1761:                    fprintf (stderr, "-%s unknown\n", cp);
                   1762:                    return;
                   1763:                case REHELP: 
                   1764:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                   1765:                    help (buf, replswit);
                   1766:                    return;
                   1767: 
                   1768:                case REANSW:    /* not implemented */
                   1769:                case RENANSW: 
                   1770:                case REINSW: 
                   1771:                case RENINSW: 
                   1772:                    continue;
                   1773: 
                   1774:                case REFRSW: 
                   1775:                case RENFRSW: 
                   1776:                case REQUSW:
                   1777:                case RENQUSW:
                   1778:                case RENDFSW:
                   1779:                case RENEDSW:
                   1780:                case RENWTSW:
                   1781:                    vec[vecp++] = --cp;
                   1782:                    continue;
                   1783: 
                   1784:                case RECCSW: 
                   1785:                case RENCCSW: 
                   1786:                case REEDTSW: 
                   1787:                case REFCCSW: 
                   1788:                case REFLTSW:
                   1789:                case REFRMSW: 
                   1790:                case REWIDSW: 
                   1791:                case REDFSW:
                   1792:                case REDMSW:
                   1793:                case REWHTSW:
                   1794:                    vec[vecp++] = --cp;
                   1795:                    if (!(cp = *args++) || *cp == '-') {
                   1796:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   1797:                        return;
                   1798:                    }
                   1799:                    vec[vecp++] = cp;
                   1800:                    continue;
                   1801:            }
                   1802:        if (*cp == '+' || *cp == '@') {
                   1803:            advise (NULLCP, "sorry, no folders allowed!");
                   1804:            return;
                   1805:        }
                   1806:        else
                   1807:            if (msg) {
                   1808:                advise (NULLCP, "only one message at a time!");
                   1809:                return;
                   1810:            }
                   1811:            else
                   1812:                msg = cp;
                   1813:     }
                   1814: 
                   1815:     vec[0] = cmd_name;
                   1816:     vec[vecp++] = "-file";
                   1817:     vec[vecp] = NULL;
                   1818:     if (!msg)
                   1819:        msg = "cur";
                   1820:     if (!m_convert (mp, msg))
                   1821:        return;
                   1822:     m_setseq (mp);
                   1823: 
                   1824:     if (mp -> numsel > 1) {
                   1825:        advise (NULLCP, "only one message at a time!");
                   1826:        return;
                   1827:     }
                   1828:     (void) process (mp -> hghsel, cmd_name, vecp, vec);
                   1829:     m_setcur (mp, mp -> hghsel);
                   1830: }
                   1831: 
                   1832: /*  */
                   1833: 
                   1834: static struct swit rmmswit[] = {
                   1835: #define        RMHELP  0
                   1836:     "help", 4,
                   1837: 
                   1838:     NULL, NULL
                   1839: };
                   1840: 
                   1841: /*  */
                   1842: 
                   1843: rmmcmd (args)
                   1844: char  **args;
                   1845: {
                   1846:     int            msgp = 0,
                   1847:             msgnum;
                   1848:     char   *cp,
                   1849:             buf[BUFSIZ],
                   1850:            *msgs[MAXARGS];
                   1851: 
                   1852:     while (cp = *args++) {
                   1853:        if (*cp == '-')
                   1854:            switch (smatch (++cp, rmmswit)) {
                   1855:                case AMBIGSW: 
                   1856:                    ambigsw (cp, rmmswit);
                   1857:                    return;
                   1858:                case UNKWNSW: 
                   1859:                    fprintf (stderr, "-%s unknown\n", cp);
                   1860:                    return;
                   1861:                case RMHELP: 
                   1862:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                   1863:                    help (buf, rmmswit);
                   1864:                    return;
                   1865:            }
                   1866:        if (*cp == '+' || *cp == '@') {
                   1867:            advise (NULLCP, "sorry, no folders allowed!");
                   1868:            return;
                   1869:        }
                   1870:        else
                   1871:            msgs[msgp++] = cp;
                   1872:     }
                   1873: 
                   1874:     if (!msgp)
                   1875:        msgs[msgp++] = "cur";
                   1876:     for (msgnum = 0; msgnum < msgp; msgnum++)
                   1877:        if (!m_convert (mp, msgs[msgnum]))
                   1878:            return;
                   1879:     m_setseq (mp);
                   1880: 
                   1881:     rmm ();
                   1882: }
                   1883: 
                   1884: /*  */
                   1885: 
                   1886: static  rmm () {
                   1887:     register int    msgnum,
                   1888:                     vecp;
                   1889:     register char  *cp;
                   1890:     char    buffer[BUFSIZ],
                   1891:           *vec[MAXARGS];
                   1892: 
                   1893:     if (fmsh) {
                   1894:        if (rmmproc) {
                   1895:            if (mp -> numsel > MAXARGS - 1) {
                   1896:                advise (NULLCP, "more than %d messages for %s exec",
                   1897:                        MAXARGS - 1, rmmproc);
                   1898:                return;
                   1899:            }
                   1900:            vecp = 0;
                   1901:            for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                   1902:                if (mp -> msgstats[msgnum] & SELECTED)
                   1903:                    vec[vecp++] = getcpy (m_name (msgnum));
                   1904:            vec[vecp] = NULL;
                   1905:            forkcmd (vec, rmmproc);
                   1906:            for (vecp = 0; vec[vecp]; vecp++)
                   1907:                free (vec[vecp]);
                   1908:        }
                   1909:        else
                   1910:            for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                   1911:                if (mp -> msgstats[msgnum] & SELECTED) {
                   1912:                    (void) strcpy (buffer, m_backup (cp = m_name (msgnum)));
                   1913:                    if (rename (cp, buffer) == NOTOK)
                   1914:                        admonish (buffer, "unable to rename %s to", cp);
                   1915:                }
                   1916:     }
                   1917: 
                   1918:     for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
                   1919:        if (mp -> msgstats[msgnum] & SELECTED) {
                   1920:            mp -> msgstats[msgnum] |= DELETED;
                   1921:            mp -> msgstats[msgnum] &= ~EXISTS;
                   1922:        }
                   1923: 
                   1924:     if ((mp -> nummsg -= mp -> numsel) <= 0) {
                   1925:        if (fmsh)
                   1926:            admonish (NULLCP, "no messages remaining in +%s", fmsh);
                   1927:        else
                   1928:            admonish (NULLCP, "no messages remaining in %s", mp -> foldpath);
                   1929:        mp -> lowmsg = mp -> hghmsg = mp -> nummsg = 0;
                   1930:     }
                   1931:     if (mp -> lowsel == mp -> lowmsg) {
                   1932:        for (msgnum = mp -> lowmsg + 1; msgnum <= mp -> hghmsg; msgnum++)
                   1933:            if (mp -> msgstats[msgnum] & EXISTS)
                   1934:                break;
                   1935:        mp -> lowmsg = msgnum;
                   1936:     }
                   1937:     if (mp -> hghsel == mp -> hghmsg) {
                   1938:        for (msgnum = mp -> hghmsg - 1; msgnum >= mp -> lowmsg; msgnum--)
                   1939:            if (mp -> msgstats[msgnum] & EXISTS)
                   1940:                break;
                   1941:        mp -> hghmsg = msgnum;
                   1942:     }
                   1943: 
                   1944:     mp -> msgflags |= MODIFIED;
                   1945:     modified++;
                   1946: }
                   1947: 
                   1948: /*  */
                   1949: 
                   1950: static struct swit scanswit[] = {
                   1951: #define        SCCLR   0
                   1952:     "clear", 0,
                   1953: #define        SCNCLR  1
                   1954:     "noclear", 0,
                   1955: #define        SCFORM  2
                   1956:     "form formatfile", 0,
                   1957: #define        SCFMT   3
                   1958:     "format string", 5,
                   1959: #define        SCHEAD  4
                   1960:     "header", 0,
                   1961: #define SCNHEAD        5
                   1962:     "noheader", 0,
                   1963: #define        SCWID   6
                   1964:     "width columns", 0,
                   1965: #define        SCHELP  7
                   1966:     "help", 4,
                   1967: 
                   1968:     NULL, NULL
                   1969: };
                   1970: 
                   1971: /*  */
                   1972: 
                   1973: scancmd (args)
                   1974: char  **args;
                   1975: {
                   1976: #define        equiv(a,b)      (a ? b && !strcmp (a, b) : !b)
                   1977: 
                   1978:     int     clearsw = 0,
                   1979:             headersw = 0,
                   1980:            width = 0,
                   1981:             msgp = 0,
                   1982:             msgnum,
                   1983:            optim,
                   1984:            state;
                   1985:     char   *cp,
                   1986:           *form = NULL,
                   1987:           *format = NULL,
                   1988:             buf[BUFSIZ],
                   1989:           *nfs,
                   1990:            *msgs[MAXARGS];
                   1991:     register FILE *zp;
                   1992:     static int s_optim = 0;
                   1993:     static char *s_form = NULL,
                   1994:                *s_format = NULL;
                   1995: 
                   1996:     while (cp = *args++) {
                   1997:        if (*cp == '-')
                   1998:            switch (smatch (++cp, scanswit)) {
                   1999:                case AMBIGSW: 
                   2000:                    ambigsw (cp, scanswit);
                   2001:                    return;
                   2002:                case UNKWNSW: 
                   2003:                    fprintf (stderr, "-%s unknown\n", cp);
                   2004:                    return;
                   2005:                case SCHELP: 
                   2006:                    (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
                   2007:                    help (buf, scanswit);
                   2008:                    return;
                   2009: 
                   2010:                case SCCLR: 
                   2011:                    clearsw++;
                   2012:                    continue;
                   2013:                case SCNCLR: 
                   2014:                    clearsw = 0;
                   2015:                    continue;
                   2016:                case SCHEAD: 
                   2017:                    headersw++;
                   2018:                    continue;
                   2019:                case SCNHEAD: 
                   2020:                    headersw = 0;
                   2021:                    continue;
                   2022:                case SCFORM: 
                   2023:                    if (!(form = *args++) || *form == '-') {
                   2024:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   2025:                        return;
                   2026:                    }
                   2027:                    format = NULL;
                   2028:                    continue;
                   2029:                case SCFMT: 
                   2030:                    if (!(format = *args++) || *format == '-') {
                   2031:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   2032:                        return;
                   2033:                    }
                   2034:                    form = NULL;
                   2035:                    continue;
                   2036:                case SCWID: 
                   2037:                    if (!(cp = *args++) || *cp == '-') {
                   2038:                        advise (NULLCP, "missing argument to %s", args[-2]);
                   2039:                        return;
                   2040:                    }
                   2041:                    width = atoi (cp);
                   2042:                    continue;
                   2043:            }
                   2044:        if (*cp == '+' || *cp == '@') {
                   2045:            advise (NULLCP, "sorry, no folders allowed!");
                   2046:            return;
                   2047:        }
                   2048:        else
                   2049:            msgs[msgp++] = cp;
                   2050:     }
                   2051: 
                   2052:     if (!msgp)
                   2053:        msgs[msgp++] = "all";
                   2054:     for (msgnum = 0; msgnum < msgp; msgnum++)
                   2055:        if (!m_convert (mp, msgs[msgnum]))
                   2056:            return;
                   2057:     m_setseq (mp);
                   2058: 
                   2059:     nfs = new_fs (form, format, FORMAT);
                   2060:     if (scanl) {               /* force scansbr to (re)compile format */
                   2061:        (void) free (scanl);
                   2062:        scanl = NULL;
                   2063:     }
                   2064: 
                   2065:     if (s_optim == 0) {
                   2066:        s_optim = optim = 1;
                   2067:        s_form = form ? getcpy (form) : NULL;
                   2068:        s_format = format ? getcpy (format) : NULL;
                   2069:     }
                   2070:     else
                   2071:        optim = equiv (s_form, form) && equiv (s_format, format);
                   2072: 
                   2073:     interrupted = 0;
                   2074:     for (msgnum = mp -> lowsel;
                   2075:            msgnum <= mp -> hghsel && !interrupted;
                   2076:            msgnum++)
                   2077:        if (mp -> msgstats[msgnum] & SELECTED) {
                   2078:            if (optim && Msgs[msgnum].m_scanl)
                   2079:                printf ("%s", Msgs[msgnum].m_scanl);
                   2080:            else {
                   2081:                zp = msh_ready (msgnum, 0);
                   2082:                switch (state = scan (zp, msgnum, 0, nfs, width,
                   2083:                        msgnum == mp -> curmsg, headersw,
                   2084:                        fmsh ? 0L : (long) (Msgs[msgnum].m_stop - Msgs[msgnum].m_start),
                   2085:                        1)) {
                   2086:                    case SCNMSG:
                   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  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  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  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  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.