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

unix.superglobalmegacorp.com

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