Annotation of researchv10no/lbin/mailx/lex.c, revision 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.