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

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

unix.superglobalmegacorp.com

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