Annotation of researchv10no/lbin/mailx/lex.c, revision 1.1.1.1

1.1       root        1: #ident "@(#)lex.c      1.5 'attmail mail(1) command'"
                      2: #ident "@(#)mailx:lex.c        1.21.3.1"
                      3: /*     Copyright (c) 1984 AT&T */
                      4: /*       All Rights Reserved   */
                      5: 
                      6: /*     THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T     */
                      7: /*     The copyright notice above does not evidence any        */
                      8: /*     actual or intended publication of such source code.     */
                      9: 
                     10: #ident "@(#)mailx:lex.c        1.21.1.1"
                     11: 
                     12: #include "rcv.h"
                     13: 
                     14: /*
                     15:  * mailx -- a modified version of a University of California at Berkeley
                     16:  *     mail program
                     17:  *
                     18:  * Lexical processing of commands.
                     19:  */
                     20: 
                     21: #ifdef SIGCONT
                     22: static void            contin();
                     23: #endif
                     24: static int             isprefix();
                     25: static struct cmd      *lex();
                     26: static int             Passeren();
                     27: static void            setmsize();
                     28: 
                     29: /*
                     30:  * Set up editing on the given file name.
                     31:  * If isedit is true, we are considered to be editing the file,
                     32:  * otherwise we are reading our mail which has signficance for
                     33:  * mbox and so forth.
                     34:  */
                     35: 
                     36: setfile(name, isedit)
                     37:        char *name;
                     38:        int isedit;
                     39: {
                     40:        FILE *ibuf;
                     41:        int i;
                     42:        static int shudclob;
                     43:        static char efile[PATHSIZE];
                     44:        char fortest[128];
                     45:        struct stat stbuf;
                     46: 
                     47:        if ((ibuf = fopen(name, "r")) == NULL) {
                     48:                if (exitflg)
                     49:                        exit(1);        /* no mail, return error */
                     50:                if (isedit)
                     51:                        perror(name);
                     52:                else if (!Hflag) {
                     53:                        if (strrchr(name,'/') == NOSTR)
                     54:                                fprintf(stderr, "No mail.\n");
                     55:                        else
                     56:                                fprintf(stderr, "No mail for %s\n", strrchr(name,'/')+1);
                     57:                }
                     58:                return(-1);
                     59:        }
                     60:        fstat(fileno(ibuf), &stbuf);
                     61:        if (stbuf.st_size == 0L) {
                     62:                if (exitflg)
                     63:                        exit(1);        /* no mail, return error */
                     64:                if (isedit)
                     65:                        fprintf(stderr, "%s: empty file\n", name);
                     66:                else if (!Hflag) {
                     67:                        if (strrchr(name,'/') == NOSTR)
                     68:                                fprintf(stderr, "No mail.\n");
                     69:                        else
                     70:                                fprintf(stderr, "No mail for %s\n", strrchr(name,'/')+1);
                     71:                }
                     72:                fclose(ibuf);
                     73:                return(-1);
                     74:        }
                     75: 
                     76:        fgets(fortest, sizeof fortest, ibuf);
                     77:        fseek(ibuf, 0L, 0);
                     78:        if (strncmp(fortest, "Forward to ", 11) == 0) {
                     79:                if (exitflg)
                     80:                        exit(1);        /* no mail, return error */
                     81:                fprintf(stderr, "Your mail is being forwarded to %s", fortest+11);
                     82:                fclose(ibuf);
                     83:                return (-1);
                     84:        }
                     85:        if (exitflg)
                     86:                exit(0);        /* there is mail, return success */
                     87: 
                     88:        /*
                     89:         * Looks like all will be well. Must hold signals
                     90:         * while we are reading the new file, else we will ruin
                     91:         * the message[] data structure.
                     92:         * Copy the messages into /tmp and set pointers.
                     93:         */
                     94: 
                     95:        if (shudclob) {
                     96:                holdsigs();
                     97:                if (edit)
                     98:                        edstop();
                     99:                else {
                    100:                        quit();
                    101:                        Verhogen();
                    102:                }
                    103:                relsesigs();
                    104:        }
                    105: 
                    106:        readonly = 0;
                    107:        if (!isedit)
                    108:                readonly = Passeren()==-1;
                    109:        lock(name);                                                     /* adb */
                    110:        fstat(fileno(ibuf), &stbuf);
                    111:        utimep->actime = stbuf.st_atime;
                    112:        utimep->modtime = stbuf.st_mtime;
                    113: 
                    114:        holdsigs();
                    115:        if (!readonly)
                    116:                if ((i = open(name, 1)) < 0)                            /* adb */
                    117:                        readonly++;
                    118:                else
                    119:                        close(i);
                    120:        if (shudclob) {
                    121:                fclose(itf);
                    122:                fclose(otf);
                    123:                free(message);
                    124:                space=0;
                    125:        }
                    126:        shudclob = 1;
                    127:        edit = isedit;
                    128:        strncpy(efile, name, PATHSIZE);
                    129:        editfile = efile;
                    130:        if (name != mailname)
                    131:                strcpy(mailname, name);
                    132:        mailsize = fsize(ibuf);
                    133:        if ((otf = fopen(tempMesg, "w")) == NULL) {
                    134:                perror(tempMesg);
                    135:                if (!edit)
                    136:                        Verhogen();
                    137:                exit(1);
                    138:        }
                    139:        if ((itf = fopen(tempMesg, "r")) == NULL) {
                    140:                perror(tempMesg);
                    141:                if (!edit)
                    142:                        Verhogen();
                    143:                exit(1);
                    144:        }
                    145:        removefile(tempMesg);
                    146:        setptr(ibuf);
                    147:        setmsize(msgCount);
                    148:        unlock();                                               /* adb */
                    149:        fclose(ibuf);
                    150:        relsesigs();
                    151:        sawcom = 0;
                    152:        return(0);
                    153: }
                    154: 
                    155: /* semaphore stuff is changed in V9/V10.                       adb */
                    156: /* global to semaphores */
                    157: static char semaphore[128];
                    158: 
                    159: /*
                    160:  *  return -1 if file is already being read, 0 otherwise
                    161:  */
                    162: static
                    163: Passeren()
                    164: {
                    165:        char file[128];
                    166:        struct stat sbuf;
                    167:        FILE *fp;
                    168:        int pid;
                    169:        extern char *getenv();
                    170:        char *home = getenv("HOME");
                    171: 
                    172:        if (home == NULL)
                    173:                return 0;
                    174:        (void)strcpy(file, home);
                    175:        (void)strcat(file, "/.Maillock");
                    176:        if (stat(file, &sbuf) >= 0) {
                    177: 
                    178:                /* lock file exists */
                    179:                fp = fopen(file, "r");
                    180:                if (fp != NULL) {
                    181:                        fscanf(fp, "%d", &pid);
                    182:                        fclose(fp);
                    183:                }
                    184:                if (fp == NULL || kill(pid, 0)==0) {
                    185:                        fprintf(stderr,"WARNING: You are already reading mail.\n");
                    186:                        fprintf(stderr, "\tThis instance of mail is read only.\n");
                    187:                        return -1;
                    188:                }
                    189:        }
                    190: 
                    191:        /* create a semaphore file */
                    192:        strcpy(semaphore, file);
                    193:        Verhogen();
                    194:        fp = fopen(semaphore, "w");
                    195:        if (fp == NULL)
                    196:                return 0;               /* nothing else we can do */
                    197:        fprintf(fp, "%d somewhere", getpid());
                    198:        fclose(fp);
                    199:        return 0;
                    200: }
                    201: 
                    202: void
                    203: Verhogen()
                    204: {
                    205:        unlink(semaphore);
                    206: }
                    207: 
                    208: /*
                    209:  * Interpret user commands one by one.  If standard input is not a tty,
                    210:  * print no prompt.
                    211:  */
                    212: 
                    213: static int     *msgvec;
                    214: static int     shudprompt;
                    215: 
                    216: void
                    217: commands()
                    218: {
                    219:        int eofloop;
                    220:        register int n;
                    221:        char linebuf[LINESIZE];
                    222:        struct stat minfo;
                    223:        FILE *ibuf;
                    224:        FILE *lockopen();                                               /* adb */
                    225: 
                    226: #ifdef SIGCONT
                    227: # ifdef preSVr4
                    228:        sigset(SIGCONT, SIG_DFL);
                    229: # else
                    230:        {
                    231:        struct sigaction nsig;
                    232:        nsig.sa_handler = SIG_DFL;
                    233:        sigemptyset(&nsig.sa_mask);
                    234:        nsig.sa_flags = SA_RESTART;
                    235:        (void) sigaction(SIGCONT, &nsig, (struct sigaction*)0);
                    236:        }
                    237: # endif
                    238: #endif
                    239:        if (rcvmode && !sourcing) {
                    240:                if (sigset(SIGINT, SIG_IGN) != (void (*)())SIG_IGN)     /* adb */
                    241:                        sigset(SIGINT, stop);
                    242:                if (sigset(SIGHUP, SIG_IGN) != (void (*)())SIG_IGN)     /* adb */
                    243:                        sigset(SIGHUP, hangup);
                    244:        }
                    245:        for (;;) {
                    246:                setjmp(srbuf);
                    247: 
                    248:                /*
                    249:                 * Print the prompt, if needed.  Clear out
                    250:                 * string space, and flush the output.
                    251:                 */
                    252: 
                    253:                if (!rcvmode && !sourcing)
                    254:                        return;
                    255:                eofloop = 0;
                    256: top:
                    257:                if ((shudprompt = (intty && !sourcing)) != 0) {
                    258:                        if (prompt==NOSTR)
                    259:                                prompt = "? ";
                    260: #ifdef SIGCONT
                    261: # ifdef preSVr4
                    262:                        sigset(SIGCONT, contin);
                    263: # else
                    264:                        {
                    265:                        struct sigaction nsig;
                    266:                        nsig.sa_handler = contin;
                    267:                        sigemptyset(&nsig.sa_mask);
                    268:                        nsig.sa_flags = SA_RESTART;
                    269:                        (void) sigaction(SIGCONT, &nsig, (struct sigaction*)0);
                    270:                        }
                    271: # endif
                    272: #endif
                    273:                        if (stat(mailname, &minfo) >=0 && minfo.st_size > mailsize) {
                    274:                                int OmsgCount, i;
                    275:                                OmsgCount = msgCount;
                    276:                                fseek(otf, 0L, 2);
                    277:                                holdsigs();
                    278:                                if ( (ibuf = lockopen(mailname, "r", 0666, -1, -1)) == NULL ) { /* adb */
                    279:                                        fprintf(stderr,"Can't reopen %s\n",mailname);
                    280:                                        exit(1);
                    281:                                        /* NOTREACHED */
                    282:                                }
                    283:                                fseek(ibuf, mailsize, 0);
                    284:                                setptr(ibuf);
                    285:                                setmsize(msgCount);
                    286:                                stat(mailname, &minfo);
                    287:                                mailsize = minfo.st_size;
                    288:                                lockclose(ibuf);                                /* adb */
                    289: /*                             unlockmail();                                      adb */
                    290:                                if (msgCount-OmsgCount > 0) {
                    291:                                        printf("New mail has arrived.\n");
                    292:                                        printf("Loaded %d new message%s\n",
                    293:                                                msgCount-OmsgCount,
                    294:                                                plural(msgCount-OmsgCount));
                    295:                                        if (value("header") != NOSTR) 
                    296:                                                for (i = OmsgCount+1;
                    297:                                                     i <= msgCount; i++) {
                    298:                                                        printhead(i);
                    299:                                                        sreset();
                    300:                                                }
                    301:                                }
                    302:                                relsesigs();
                    303:                        }
                    304:                        printf("%s", prompt);
                    305:                }
                    306:                flush();
                    307:                sreset();
                    308: 
                    309:                /*
                    310:                 * Read a line of commands from the current input
                    311:                 * and handle end of file specially.
                    312:                 */
                    313: 
                    314:                n = 0;
                    315:                for (;;) {
                    316:                        if (readline(input, &linebuf[n]) <= 0) {
                    317:                                if (n != 0)
                    318:                                        break;
                    319:                                if (loading)
                    320:                                        return;
                    321:                                if (sourcing) {
                    322:                                        unstack();
                    323:                                        goto more;
                    324:                                }
                    325:                                if (value("ignoreeof") != NOSTR && shudprompt) {
                    326:                                        if (++eofloop < 25) {
                    327:                                                printf("Use \"quit\" to quit.\n");
                    328:                                                goto top;
                    329:                                        }
                    330:                                }
                    331:                                if (edit)
                    332:                                        edstop();
                    333:                                return;
                    334:                        }
                    335:                        if ((n = strlen(linebuf)) == 0)
                    336:                                break;
                    337:                        n--;
                    338:                        if (linebuf[n] != '\\')
                    339:                                break;
                    340:                        linebuf[n++] = ' ';
                    341:                }
                    342: #ifdef SIGCONT
                    343: # ifdef preSVr4
                    344:                sigset(SIGCONT, SIG_DFL);
                    345: # else
                    346:                {
                    347:                struct sigaction nsig;
                    348:                nsig.sa_handler = SIG_DFL;
                    349:                sigemptyset(&nsig.sa_mask);
                    350:                nsig.sa_flags = SA_RESTART;
                    351:                (void) sigaction(SIGCONT, &nsig, (struct sigaction*)0);
                    352:                }
                    353: # endif
                    354: #endif
                    355:                if (execute(linebuf, 0))
                    356:                        return;
                    357: more:          ;
                    358:        }
                    359: }
                    360: 
                    361: /*
                    362:  * Execute a single command.  If the command executed
                    363:  * is "quit," then return non-zero so that the caller
                    364:  * will know to return back to main, if he cares.
                    365:  * Contxt is non-zero if called while composing mail.
                    366:  */
                    367: 
                    368: execute(linebuf, contxt)
                    369:        char linebuf[];
                    370: {
                    371:        char word[LINESIZE];
                    372:        char *arglist[MAXARGC];
                    373:        struct cmd *com;
                    374:        register char *cp, *cp2;
                    375:        register int c, e;
                    376:        int muvec[2];
                    377: 
                    378:        /*
                    379:         * Strip the white space away from the beginning
                    380:         * of the command, then scan out a word, which
                    381:         * consists of anything except digits and white space.
                    382:         *
                    383:         * Handle |, ! and # differently to get the correct
                    384:         * lexical conventions.
                    385:         */
                    386: 
                    387:        cp = linebuf;
                    388:        while (any(*cp, " \t"))
                    389:                cp++;
                    390:        cp2 = word;
                    391:        if (any(*cp, "!|#"))
                    392:                *cp2++ = *cp++;
                    393:        else
                    394:                while (*cp && !any(*cp, " \t0123456789$^.:/-+*'\""))
                    395:                        *cp2++ = *cp++;
                    396:        *cp2 = '\0';
                    397: 
                    398:        /*
                    399:         * Look up the command; if not found, complain.
                    400:         * Normally, a blank command would map to the
                    401:         * first command in the table; while sourcing,
                    402:         * however, we ignore blank lines to eliminate
                    403:         * confusion.
                    404:         */
                    405: 
                    406:        if (sourcing && equal(word, ""))
                    407:                return(0);
                    408:        com = lex(word);
                    409:        if (com == NONE) {
                    410:                printf("Unknown command: \"%s\"\n", word);
                    411:                if (loading) {
                    412:                        cond = CANY;
                    413:                        return(1);
                    414:                }
                    415:                if (sourcing) {
                    416:                        cond = CANY;
                    417:                        unstack();
                    418:                }
                    419:                return(0);
                    420:        }
                    421: 
                    422:        /*
                    423:         * See if we should execute the command -- if a conditional
                    424:         * we always execute it, otherwise, check the state of cond.
                    425:         */
                    426: 
                    427:        if ((com->c_argtype & F) == 0)
                    428:                if (cond == CRCV && !rcvmode || cond == CSEND && rcvmode)
                    429:                        return(0);
                    430: 
                    431:        /*
                    432:         * Special case so that quit causes a return to
                    433:         * main, who will call the quit code directly.
                    434:         * If we are in a source file, just unstack.
                    435:         */
                    436: 
                    437:        if (com->c_func == edstop && sourcing) {
                    438:                if (loading)
                    439:                        return(1);
                    440:                unstack();
                    441:                return(0);
                    442:        }
                    443:        if (!edit && com->c_func == edstop) {
                    444:                sigset(SIGINT, SIG_IGN);
                    445:                return(1);
                    446:        }
                    447: 
                    448:        /*
                    449:         * Process the arguments to the command, depending
                    450:         * on the type he expects.  Default to an error.
                    451:         * If we are sourcing an interactive command, it's
                    452:         * an error.
                    453:         */
                    454: 
                    455:        if (!rcvmode && (com->c_argtype & M) == 0) {
                    456:                printf("May not execute \"%s\" while sending\n",
                    457:                    com->c_name);
                    458:                if (loading)
                    459:                        return(1);
                    460:                if (sourcing)
                    461:                        unstack();
                    462:                return(0);
                    463:        }
                    464:        if (sourcing && com->c_argtype & I) {
                    465:                printf("May not execute \"%s\" while sourcing\n",
                    466:                    com->c_name);
                    467:                if (loading)
                    468:                        return(1);
                    469:                unstack();
                    470:                return(0);
                    471:        }
                    472:        if (readonly && com->c_argtype & W) {
                    473:                printf("May not execute \"%s\" -- message file is read only\n",
                    474:                   com->c_name);
                    475:                if (loading)
                    476:                        return(1);
                    477:                if (sourcing)
                    478:                        unstack();
                    479:                return(0);
                    480:        }
                    481:        if (contxt && com->c_argtype & R) {
                    482:                printf("Cannot recursively invoke \"%s\"\n", com->c_name);
                    483:                return(0);
                    484:        }
                    485:        e = 1;
                    486:        switch (com->c_argtype & ~(F|P|I|M|T|W|R)) {
                    487:        case MSGLIST:
                    488:                /*
                    489:                 * A message list defaulting to nearest forward
                    490:                 * legal message.
                    491:                 */
                    492:                if (msgvec == 0) {
                    493:                        printf("Illegal use of \"message list\"\n");
                    494:                        return(-1);
                    495:                }
                    496:                if ((c = getmsglist(cp, msgvec, com->c_msgflag)) < 0)
                    497:                        break;
                    498:                if (c  == 0)
                    499:                        if (msgCount == 0)
                    500:                                *msgvec = NULL;
                    501:                        else {
                    502:                                *msgvec = first(com->c_msgflag,
                    503:                                        com->c_msgmask);
                    504:                                msgvec[1] = NULL;
                    505:                        }
                    506:                if (*msgvec == NULL) {
                    507:                        printf("No applicable messages\n");
                    508:                        break;
                    509:                }
                    510:                e = (*com->c_func)(msgvec);
                    511:                break;
                    512: 
                    513:        case NDMLIST:
                    514:                /*
                    515:                 * A message list with no defaults, but no error
                    516:                 * if none exist.
                    517:                 */
                    518:                if (msgvec == 0) {
                    519:                        printf("Illegal use of \"message list\"\n");
                    520:                        return(-1);
                    521:                }
                    522:                if (getmsglist(cp, msgvec, com->c_msgflag) < 0)
                    523:                        break;
                    524:                e = (*com->c_func)(msgvec);
                    525:                break;
                    526: 
                    527:        case STRLIST:
                    528:                /*
                    529:                 * Just the straight string, with
                    530:                 * leading blanks removed.
                    531:                 */
                    532:                while (any(*cp, " \t"))
                    533:                        cp++;
                    534:                e = (*com->c_func)(cp);
                    535:                break;
                    536: 
                    537:        case RAWLIST:
                    538:                /*
                    539:                 * A vector of strings, in shell style.
                    540:                 */
                    541:                if ((c = getrawlist(cp, arglist)) < 0)
                    542:                        break;
                    543:                if (c < com->c_minargs) {
                    544:                        printf("%s requires at least %d arg(s)\n",
                    545:                                com->c_name, com->c_minargs);
                    546:                        break;
                    547:                }
                    548:                if (c > com->c_maxargs) {
                    549:                        printf("%s takes no more than %d arg(s)\n",
                    550:                                com->c_name, com->c_maxargs);
                    551:                        break;
                    552:                }
                    553:                e = (*com->c_func)(arglist);
                    554:                break;
                    555: 
                    556:        case NOLIST:
                    557:                /*
                    558:                 * Just the constant zero, for exiting,
                    559:                 * eg.
                    560:                 */
                    561:                e = (*com->c_func)(0);
                    562:                break;
                    563: 
                    564:        default:
                    565:                panic("Unknown argtype");
                    566:        }
                    567: 
                    568:        /*
                    569:         * Exit the current source file on
                    570:         * error.
                    571:         */
                    572: 
                    573:        if (e && loading)
                    574:                return(1);
                    575:        if (e && sourcing)
                    576:                unstack();
                    577:        if (com->c_func == edstop)
                    578:                return(1);
                    579:        if (value("autoprint") != NOSTR && com->c_argtype & P)
                    580:                if ((dot->m_flag & MDELETED) == 0) {
                    581:                        muvec[0] = dot - &message[0] + 1;
                    582:                        muvec[1] = 0;
                    583:                        type(muvec);
                    584:                }
                    585:        if (!sourcing && (com->c_argtype & T) == 0)
                    586:                sawcom = 1;
                    587:        return(0);
                    588: }
                    589: 
                    590: #ifdef SIGCONT
                    591: /*
                    592:  * When we wake up after ^Z, reprint the prompt.
                    593:  */
                    594: static void
                    595: contin()
                    596: {
                    597:        if (shudprompt)
                    598:                printf("%s", prompt);
                    599:        fflush(stdout);
                    600: }
                    601: #endif
                    602: 
                    603: /*
                    604:  * Branch here on hangup signal and simulate quit.
                    605:  */
                    606: void
                    607: hangup()
                    608: {
                    609: 
                    610:        holdsigs();
                    611:        sigignore(SIGHUP);
                    612:        if (edit) {
                    613:                if (setjmp(srbuf))
                    614:                        exit(0);
                    615:                edstop();
                    616:        } else {
                    617:                Verhogen();
                    618:                if (value("exit") != NOSTR)
                    619:                        exit(1);
                    620:                else
                    621:                        quit();
                    622:        }
                    623:        exit(0);
                    624: }
                    625: 
                    626: /*
                    627:  * Set the size of the message vector used to construct argument
                    628:  * lists to message list functions.
                    629:  */
                    630:  
                    631: static void
                    632: setmsize(sz)
                    633: {
                    634: 
                    635:        if (msgvec != (int *) 0)
                    636:                free(msgvec);
                    637:        if (sz < 1)
                    638:                sz = 1; /* need at least one cell for terminating 0 */
                    639:        msgvec = (int *) calloc((unsigned) (sz + 1), sizeof *msgvec);
                    640: }
                    641: 
                    642: /*
                    643:  * Find the correct command in the command table corresponding
                    644:  * to the passed command "word"
                    645:  */
                    646: 
                    647: static struct cmd *
                    648: lex(word)
                    649:        char word[];
                    650: {
                    651:        register struct cmd *cp;
                    652: 
                    653:        for (cp = &cmdtab[0]; cp->c_name != NOSTR; cp++)
                    654:                if (isprefix(word, cp->c_name))
                    655:                        return(cp);
                    656:        return(NONE);
                    657: }
                    658: 
                    659: /*
                    660:  * Determine if as1 is a valid prefix of as2.
                    661:  */
                    662: static int
                    663: isprefix(as1, as2)
                    664:        char *as1, *as2;
                    665: {
                    666:        register char *s1, *s2;
                    667: 
                    668:        s1 = as1;
                    669:        s2 = as2;
                    670:        while (*s1++ == *s2)
                    671:                if (*s2++ == '\0')
                    672:                        return(1);
                    673:        return(*--s1 == '\0');
                    674: }
                    675: 
                    676: /*
                    677:  * The following gets called on receipt of a rubout.  This is
                    678:  * to abort printout of a command, mainly.
                    679:  * Dispatching here when command() is inactive crashes rcv.
                    680:  * Close all open files except 0, 1, 2, and the temporary.
                    681:  * The special call to getuserid() is needed so it won't get
                    682:  * annoyed about losing its open file.
                    683:  * Also, unstack all source files.
                    684:  */
                    685: 
                    686: static int     inithdr;                /* am printing startup headers */
                    687: 
                    688: void
                    689: stop(s)
                    690: {
                    691:        register NODE *head;
                    692: 
                    693:        noreset = 0;
                    694:        if (!inithdr)
                    695:                sawcom++;
                    696:        inithdr = 0;
                    697:        while (sourcing)
                    698:                unstack();
                    699:        getuserid((char *) 0);
                    700:        if ( !maxfiles ) 
                    701:                if ( (maxfiles=ulimit(4, 0)) < 0 )
                    702:                        maxfiles = _NFILE;
                    703:        for (head = fplist; head != (NODE *)NULL; head = head->next) {
                    704:                if (head->fp == stdin || head->fp == stdout)
                    705:                        continue;
                    706:                if (head->fp == itf || head->fp == otf)
                    707:                        continue;
                    708:                if (head->fp == stderr)
                    709:                        continue;
                    710:                if (head->fp == pipef) {
                    711:                        npclose(pipef);
                    712:                        pipef = NULL;
                    713:                        continue;
                    714:                }
                    715:                fclose(head->fp);
                    716:        }
                    717:        if (image >= 0) {
                    718:                close(image);
                    719:                image = -1;
                    720:        }
                    721:        clrbuf(stdout);
                    722:        if (s) {
                    723:                printf("Interrupt\n");
                    724:                sigrelse(s);
                    725:        }
                    726:        longjmp(srbuf, 1);
                    727: }
                    728: 
                    729: /*
                    730:  * Announce the presence of the current mailx version,
                    731:  * give the message count, and print a header listing.
                    732:  */
                    733: 
                    734: static char    *greeting       = "%s  Type ? for help.\n";
                    735: 
                    736: void
                    737: announce()
                    738: {
                    739:        int vec[2], mdot;
                    740: 
                    741:        if (!Hflag && value("quiet")==NOSTR)
                    742:                printf(greeting, version);
                    743:        mdot = newfileinfo();
                    744:        vec[0] = mdot;
                    745:        vec[1] = 0;
                    746:        dot = &message[mdot - 1];
                    747:        if (msgCount > 0 && !noheader) {
                    748:                inithdr++;
                    749:                headers(vec);
                    750:                inithdr = 0;
                    751:        }
                    752: }
                    753: 
                    754: /*
                    755:  * Announce information about the file we are editing.
                    756:  * Return a likely place to set dot.
                    757:  */
                    758: newfileinfo()
                    759: {
                    760:        register struct message *mp;
                    761:        register int u, n, mdot, d, s;
                    762:        char fname[BUFSIZ], zname[BUFSIZ], *ename;
                    763: 
                    764:        if (Hflag)
                    765:                return(1);
                    766:        for (mp = &message[0]; mp < &message[msgCount]; mp++)
                    767:                if (mp->m_flag & MNEW)
                    768:                        break;
                    769:        if (mp >= &message[msgCount])
                    770:                for (mp = &message[0]; mp < &message[msgCount]; mp++)
                    771:                        if ((mp->m_flag & MREAD) == 0)
                    772:                                break;
                    773:        if (mp < &message[msgCount])
                    774:                mdot = mp - &message[0] + 1;
                    775:        else
                    776:                mdot = 1;
                    777:        s = d = 0;
                    778:        for (mp = &message[0], n = 0, u = 0; mp < &message[msgCount]; mp++) {
                    779:                if (mp->m_flag & MNEW)
                    780:                        n++;
                    781:                if ((mp->m_flag & MREAD) == 0)
                    782:                        u++;
                    783:                if (mp->m_flag & MDELETED)
                    784:                        d++;
                    785:                if (mp->m_flag & MSAVED)
                    786:                        s++;
                    787:        }
                    788:        ename=origname;
                    789:        if (getfold(fname) >= 0) {
                    790:                strcat(fname, "/");
                    791:                if (strncmp(fname, mailname, strlen(fname)) == 0) {
                    792:                        sprintf(zname, "+%s", mailname + strlen(fname));
                    793:                        ename = zname;
                    794:                }
                    795:        }
                    796:        printf("\"%s\": ", ename);
                    797:        if (msgCount == 1)
                    798:                printf("1 message");
                    799:        else
                    800:                printf("%d messages", msgCount);
                    801:        if (n > 0)
                    802:                printf(" %d new", n);
                    803:        if (u-n > 0)
                    804:                printf(" %d unread", u);
                    805:        if (d > 0)
                    806:                printf(" %d deleted", d);
                    807:        if (s > 0)
                    808:                printf(" %d saved", s);
                    809:        if (readonly)
                    810:                printf(" [Read only]");
                    811:        printf("\n");
                    812:        return(mdot);
                    813: }
                    814: 
                    815: /*
                    816:  * Print the current version number.
                    817:  */
                    818: 
                    819: pversion(e)
                    820:        char *e;
                    821: {
                    822:        (void) e;
                    823:        printf("%s\n", version);
                    824:        return(0);
                    825: }
                    826: 
                    827: /*
                    828:  * Load a file of user definitions.
                    829:  */
                    830: void
                    831: load(name)
                    832:        char *name;
                    833: {
                    834:        register FILE *in, *oldin;
                    835: 
                    836:        if ((in = fopen(name, "r")) == NULL)
                    837:                return;
                    838:        oldin = input;
                    839:        input = in;
                    840:        loading = 1;
                    841:        sourcing = 1;
                    842:        commands();
                    843:        loading = 0;
                    844:        sourcing = 0;
                    845:        input = oldin;
                    846:        fclose(in);
                    847: }

unix.superglobalmegacorp.com

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