Annotation of 43BSDTahoe/ucb/Mail/cmd3.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted
        !             6:  * provided that this notice is preserved and that due credit is given
        !             7:  * to the University of California at Berkeley. The name of the University
        !             8:  * may not be used to endorse or promote products derived from this
        !             9:  * software without specific prior written permission. This software
        !            10:  * is provided ``as is'' without express or implied warranty.
        !            11:  */
        !            12: 
        !            13: #ifdef notdef
        !            14: static char sccsid[] = "@(#)cmd3.c     5.5 (Berkeley) 2/18/88";
        !            15: #endif /* notdef */
        !            16: 
        !            17: #include "rcv.h"
        !            18: #include <sys/stat.h>
        !            19: #include <sys/wait.h>
        !            20: 
        !            21: /*
        !            22:  * Mail -- a mail program
        !            23:  *
        !            24:  * Still more user commands.
        !            25:  */
        !            26: 
        !            27: /*
        !            28:  * Process a shell escape by saving signals, ignoring signals,
        !            29:  * and forking a sh -c
        !            30:  */
        !            31: 
        !            32: shell(str)
        !            33:        char *str;
        !            34: {
        !            35:        int (*sigint)(), (*sigquit)();
        !            36:        union wait stat;
        !            37:        register int t;
        !            38:        char *Shell;
        !            39:        char cmd[BUFSIZ];
        !            40: 
        !            41:        strcpy(cmd, str);
        !            42:        if (bangexp(cmd) < 0)
        !            43:                return(-1);
        !            44:        if ((Shell = value("SHELL")) == NOSTR)
        !            45:                Shell = SHELL;
        !            46:        sigint = signal(SIGINT, SIG_IGN);
        !            47:        sigquit = signal(SIGQUIT, SIG_IGN);
        !            48:        t = vfork();
        !            49:        if (t == 0) {
        !            50:                if (sigint != SIG_IGN)
        !            51:                        signal(SIGINT, SIG_DFL);
        !            52:                if (sigquit != SIG_IGN)
        !            53:                        signal(SIGQUIT, SIG_DFL);
        !            54:                execl(Shell, Shell, "-c", cmd, (char *)0);
        !            55:                perror(Shell);
        !            56:                _exit(1);
        !            57:        }
        !            58:        while (wait(&stat) != t)
        !            59:                ;
        !            60:        if (t == -1)
        !            61:                perror("fork");
        !            62:        signal(SIGINT, sigint);
        !            63:        signal(SIGQUIT, sigquit);
        !            64:        printf("!\n");
        !            65:        return(0);
        !            66: }
        !            67: 
        !            68: /*
        !            69:  * Fork an interactive shell.
        !            70:  */
        !            71: 
        !            72: /*ARGSUSED*/
        !            73: dosh(str)
        !            74:        char *str;
        !            75: {
        !            76:        int (*sigint)(), (*sigquit)();
        !            77:        union wait stat;
        !            78:        register int t;
        !            79:        char *Shell;
        !            80: 
        !            81:        if ((Shell = value("SHELL")) == NOSTR)
        !            82:                Shell = SHELL;
        !            83:        sigint = signal(SIGINT, SIG_IGN);
        !            84:        sigquit = signal(SIGQUIT, SIG_IGN);
        !            85:        t = vfork();
        !            86:        if (t == 0) {
        !            87:                if (sigint != SIG_IGN)
        !            88:                        signal(SIGINT, SIG_DFL);
        !            89:                if (sigquit != SIG_IGN)
        !            90:                        signal(SIGQUIT, SIG_DFL);
        !            91:                execl(Shell, Shell, (char *)0);
        !            92:                perror(Shell);
        !            93:                _exit(1);
        !            94:        }
        !            95:        while (wait(&stat) != t)
        !            96:                ;
        !            97:        if (t == -1)
        !            98:                perror("fork");
        !            99:        signal(SIGINT, sigint);
        !           100:        signal(SIGQUIT, sigquit);
        !           101:        putchar('\n');
        !           102:        return(0);
        !           103: }
        !           104: 
        !           105: /*
        !           106:  * Expand the shell escape by expanding unescaped !'s into the
        !           107:  * last issued command where possible.
        !           108:  */
        !           109: 
        !           110: char   lastbang[128];
        !           111: 
        !           112: bangexp(str)
        !           113:        char *str;
        !           114: {
        !           115:        char bangbuf[BUFSIZ];
        !           116:        register char *cp, *cp2;
        !           117:        register int n;
        !           118:        int changed = 0;
        !           119: 
        !           120:        cp = str;
        !           121:        cp2 = bangbuf;
        !           122:        n = BUFSIZ;
        !           123:        while (*cp) {
        !           124:                if (*cp == '!') {
        !           125:                        if (n < strlen(lastbang)) {
        !           126: overf:
        !           127:                                printf("Command buffer overflow\n");
        !           128:                                return(-1);
        !           129:                        }
        !           130:                        changed++;
        !           131:                        strcpy(cp2, lastbang);
        !           132:                        cp2 += strlen(lastbang);
        !           133:                        n -= strlen(lastbang);
        !           134:                        cp++;
        !           135:                        continue;
        !           136:                }
        !           137:                if (*cp == '\\' && cp[1] == '!') {
        !           138:                        if (--n <= 1)
        !           139:                                goto overf;
        !           140:                        *cp2++ = '!';
        !           141:                        cp += 2;
        !           142:                        changed++;
        !           143:                }
        !           144:                if (--n <= 1)
        !           145:                        goto overf;
        !           146:                *cp2++ = *cp++;
        !           147:        }
        !           148:        *cp2 = 0;
        !           149:        if (changed) {
        !           150:                printf("!%s\n", bangbuf);
        !           151:                fflush(stdout);
        !           152:        }
        !           153:        strcpy(str, bangbuf);
        !           154:        strncpy(lastbang, bangbuf, 128);
        !           155:        lastbang[127] = 0;
        !           156:        return(0);
        !           157: }
        !           158: 
        !           159: /*
        !           160:  * Print out a nice help message from some file or another.
        !           161:  */
        !           162: 
        !           163: help()
        !           164: {
        !           165:        register c;
        !           166:        register FILE *f;
        !           167: 
        !           168:        if ((f = fopen(HELPFILE, "r")) == NULL) {
        !           169:                perror(HELPFILE);
        !           170:                return(1);
        !           171:        }
        !           172:        while ((c = getc(f)) != EOF)
        !           173:                putchar(c);
        !           174:        fclose(f);
        !           175:        return(0);
        !           176: }
        !           177: 
        !           178: /*
        !           179:  * Change user's working directory.
        !           180:  */
        !           181: 
        !           182: schdir(str)
        !           183:        char *str;
        !           184: {
        !           185:        register char *cp;
        !           186: 
        !           187:        for (cp = str; *cp == ' '; cp++)
        !           188:                ;
        !           189:        if (*cp == '\0')
        !           190:                cp = homedir;
        !           191:        else
        !           192:                if ((cp = expand(cp)) == NOSTR)
        !           193:                        return(1);
        !           194:        if (chdir(cp) < 0) {
        !           195:                perror(cp);
        !           196:                return(1);
        !           197:        }
        !           198:        return(0);
        !           199: }
        !           200: 
        !           201: respond(msgvec)
        !           202:        int *msgvec;
        !           203: {
        !           204:        if (value("Replyall") == NOSTR)
        !           205:                return (_respond(msgvec));
        !           206:        else
        !           207:                return (_Respond(msgvec));
        !           208: }
        !           209: 
        !           210: /*
        !           211:  * Reply to a list of messages.  Extract each name from the
        !           212:  * message header and send them off to mail1()
        !           213:  */
        !           214: 
        !           215: _respond(msgvec)
        !           216:        int *msgvec;
        !           217: {
        !           218:        struct message *mp;
        !           219:        char *cp, *rcv, *replyto;
        !           220:        char buf[2 * LINESIZE], **ap;
        !           221:        struct name *np;
        !           222:        struct header head;
        !           223: 
        !           224:        if (msgvec[1] != 0) {
        !           225:                printf("Sorry, can't reply to multiple messages at once\n");
        !           226:                return(1);
        !           227:        }
        !           228:        mp = &message[msgvec[0] - 1];
        !           229:        dot = mp;
        !           230:        rcv = NOSTR;
        !           231:        cp = skin(nameof(mp, 1));
        !           232:        if (cp != NOSTR)
        !           233:            rcv = cp;
        !           234:        cp = skin(hfield("from", mp));
        !           235:        if (cp != NOSTR)
        !           236:            rcv = cp;
        !           237:        replyto = skin(hfield("reply-to", mp));
        !           238:        strcpy(buf, "");
        !           239:        if (replyto != NOSTR)
        !           240:                strcpy(buf, replyto);
        !           241:        else {
        !           242:                cp = skin(hfield("to", mp));
        !           243:                if (cp != NOSTR)
        !           244:                        strcpy(buf, cp);
        !           245:        }
        !           246:        np = elide(extract(buf, GTO));
        !           247:        mapf(np, rcv);
        !           248:        /*
        !           249:         * Delete my name from the reply list,
        !           250:         * and with it, all my alternate names.
        !           251:         */
        !           252:        np = delname(np, myname, icequal);
        !           253:        if (altnames)
        !           254:                for (ap = altnames; *ap; ap++)
        !           255:                        np = delname(np, *ap, icequal);
        !           256:        head.h_seq = 1;
        !           257:        cp = detract(np, 0);
        !           258:        if (cp != NOSTR && replyto == NOSTR) {
        !           259:                strcpy(buf, cp);
        !           260:                strcat(buf, " ");
        !           261:                strcat(buf, rcv);
        !           262:        }
        !           263:        else {
        !           264:                if (cp == NOSTR && replyto != NOSTR)
        !           265:                        printf("Empty reply-to field -- replying to author\n");
        !           266:                if (cp == NOSTR)
        !           267:                        strcpy(buf, rcv);
        !           268:                else
        !           269:                        strcpy(buf, cp);
        !           270:        }
        !           271:        head.h_to = buf;
        !           272:        head.h_subject = hfield("subject", mp);
        !           273:        if (head.h_subject == NOSTR)
        !           274:                head.h_subject = hfield("subj", mp);
        !           275:        head.h_subject = reedit(head.h_subject);
        !           276:        head.h_cc = NOSTR;
        !           277:        if (replyto == NOSTR) {
        !           278:                cp = skin(hfield("cc", mp));
        !           279:                if (cp != NOSTR) {
        !           280:                        np = elide(extract(cp, GCC));
        !           281:                        mapf(np, rcv);
        !           282:                        np = delname(np, myname, icequal);
        !           283:                        if (altnames != 0)
        !           284:                                for (ap = altnames; *ap; ap++)
        !           285:                                        np = delname(np, *ap, icequal);
        !           286:                        head.h_cc = detract(np, 0);
        !           287:                }
        !           288:        }
        !           289:        head.h_bcc = NOSTR;
        !           290:        mail1(&head);
        !           291:        return(0);
        !           292: }
        !           293: 
        !           294: /*
        !           295:  * Modify the subject we are replying to to begin with Re: if
        !           296:  * it does not already.
        !           297:  */
        !           298: 
        !           299: char *
        !           300: reedit(subj)
        !           301:        char *subj;
        !           302: {
        !           303:        char sbuf[10];
        !           304:        register char *newsubj;
        !           305: 
        !           306:        if (subj == NOSTR)
        !           307:                return(NOSTR);
        !           308:        strncpy(sbuf, subj, 3);
        !           309:        sbuf[3] = 0;
        !           310:        if (icequal(sbuf, "re:"))
        !           311:                return(subj);
        !           312:        newsubj = salloc(strlen(subj) + 6);
        !           313:        sprintf(newsubj, "Re: %s", subj);
        !           314:        return(newsubj);
        !           315: }
        !           316: 
        !           317: /*
        !           318:  * Preserve the named messages, so that they will be sent
        !           319:  * back to the system mailbox.
        !           320:  */
        !           321: 
        !           322: preserve(msgvec)
        !           323:        int *msgvec;
        !           324: {
        !           325:        register struct message *mp;
        !           326:        register int *ip, mesg;
        !           327: 
        !           328:        if (edit) {
        !           329:                printf("Cannot \"preserve\" in edit mode\n");
        !           330:                return(1);
        !           331:        }
        !           332:        for (ip = msgvec; *ip != NULL; ip++) {
        !           333:                mesg = *ip;
        !           334:                mp = &message[mesg-1];
        !           335:                mp->m_flag |= MPRESERVE;
        !           336:                mp->m_flag &= ~MBOX;
        !           337:                dot = mp;
        !           338:        }
        !           339:        return(0);
        !           340: }
        !           341: 
        !           342: /*
        !           343:  * Mark all given messages as unread.
        !           344:  */
        !           345: unread(msgvec)
        !           346:        int     msgvec[];
        !           347: {
        !           348:        register int *ip;
        !           349: 
        !           350:        for (ip = msgvec; *ip != NULL; ip++) {
        !           351:                dot = &message[*ip-1];
        !           352:                dot->m_flag &= ~(MREAD|MTOUCH);
        !           353:                dot->m_flag |= MSTATUS;
        !           354:        }
        !           355:        return(0);
        !           356: }
        !           357: 
        !           358: /*
        !           359:  * Print the size of each message.
        !           360:  */
        !           361: 
        !           362: messize(msgvec)
        !           363:        int *msgvec;
        !           364: {
        !           365:        register struct message *mp;
        !           366:        register int *ip, mesg;
        !           367: 
        !           368:        for (ip = msgvec; *ip != NULL; ip++) {
        !           369:                mesg = *ip;
        !           370:                mp = &message[mesg-1];
        !           371:                printf("%d: %d/%ld\n", mesg, mp->m_lines, mp->m_size);
        !           372:        }
        !           373:        return(0);
        !           374: }
        !           375: 
        !           376: /*
        !           377:  * Quit quickly.  If we are sourcing, just pop the input level
        !           378:  * by returning an error.
        !           379:  */
        !           380: 
        !           381: rexit(e)
        !           382: {
        !           383:        if (sourcing)
        !           384:                return(1);
        !           385:        if (Tflag != NOSTR)
        !           386:                close(creat(Tflag, 0600));
        !           387:        exit(e);
        !           388:        /*NOTREACHED*/
        !           389: }
        !           390: 
        !           391: /*
        !           392:  * Set or display a variable value.  Syntax is similar to that
        !           393:  * of csh.
        !           394:  */
        !           395: 
        !           396: set(arglist)
        !           397:        char **arglist;
        !           398: {
        !           399:        register struct var *vp;
        !           400:        register char *cp, *cp2;
        !           401:        char varbuf[BUFSIZ], **ap, **p;
        !           402:        int errs, h, s;
        !           403: 
        !           404:        if (argcount(arglist) == 0) {
        !           405:                for (h = 0, s = 1; h < HSHSIZE; h++)
        !           406:                        for (vp = variables[h]; vp != NOVAR; vp = vp->v_link)
        !           407:                                s++;
        !           408:                ap = (char **) salloc(s * sizeof *ap);
        !           409:                for (h = 0, p = ap; h < HSHSIZE; h++)
        !           410:                        for (vp = variables[h]; vp != NOVAR; vp = vp->v_link)
        !           411:                                *p++ = vp->v_name;
        !           412:                *p = NOSTR;
        !           413:                sort(ap);
        !           414:                for (p = ap; *p != NOSTR; p++)
        !           415:                        printf("%s\t%s\n", *p, value(*p));
        !           416:                return(0);
        !           417:        }
        !           418:        errs = 0;
        !           419:        for (ap = arglist; *ap != NOSTR; ap++) {
        !           420:                cp = *ap;
        !           421:                cp2 = varbuf;
        !           422:                while (*cp != '=' && *cp != '\0')
        !           423:                        *cp2++ = *cp++;
        !           424:                *cp2 = '\0';
        !           425:                if (*cp == '\0')
        !           426:                        cp = "";
        !           427:                else
        !           428:                        cp++;
        !           429:                if (equal(varbuf, "")) {
        !           430:                        printf("Non-null variable name required\n");
        !           431:                        errs++;
        !           432:                        continue;
        !           433:                }
        !           434:                assign(varbuf, cp);
        !           435:        }
        !           436:        return(errs);
        !           437: }
        !           438: 
        !           439: /*
        !           440:  * Unset a bunch of variable values.
        !           441:  */
        !           442: 
        !           443: unset(arglist)
        !           444:        char **arglist;
        !           445: {
        !           446:        register struct var *vp, *vp2;
        !           447:        int errs, h;
        !           448:        char **ap;
        !           449: 
        !           450:        errs = 0;
        !           451:        for (ap = arglist; *ap != NOSTR; ap++) {
        !           452:                if ((vp2 = lookup(*ap)) == NOVAR) {
        !           453:                        if (!sourcing) {
        !           454:                                printf("\"%s\": undefined variable\n", *ap);
        !           455:                                errs++;
        !           456:                        }
        !           457:                        continue;
        !           458:                }
        !           459:                h = hash(*ap);
        !           460:                if (vp2 == variables[h]) {
        !           461:                        variables[h] = variables[h]->v_link;
        !           462:                        vfree(vp2->v_name);
        !           463:                        vfree(vp2->v_value);
        !           464:                        cfree((char *)vp2);
        !           465:                        continue;
        !           466:                }
        !           467:                for (vp = variables[h]; vp->v_link != vp2; vp = vp->v_link)
        !           468:                        ;
        !           469:                vp->v_link = vp2->v_link;
        !           470:                vfree(vp2->v_name);
        !           471:                vfree(vp2->v_value);
        !           472:                cfree((char *) vp2);
        !           473:        }
        !           474:        return(errs);
        !           475: }
        !           476: 
        !           477: /*
        !           478:  * Put add users to a group.
        !           479:  */
        !           480: 
        !           481: group(argv)
        !           482:        char **argv;
        !           483: {
        !           484:        register struct grouphead *gh;
        !           485:        register struct group *gp;
        !           486:        register int h;
        !           487:        int s;
        !           488:        char **ap, *gname, **p;
        !           489: 
        !           490:        if (argcount(argv) == 0) {
        !           491:                for (h = 0, s = 1; h < HSHSIZE; h++)
        !           492:                        for (gh = groups[h]; gh != NOGRP; gh = gh->g_link)
        !           493:                                s++;
        !           494:                ap = (char **) salloc(s * sizeof *ap);
        !           495:                for (h = 0, p = ap; h < HSHSIZE; h++)
        !           496:                        for (gh = groups[h]; gh != NOGRP; gh = gh->g_link)
        !           497:                                *p++ = gh->g_name;
        !           498:                *p = NOSTR;
        !           499:                sort(ap);
        !           500:                for (p = ap; *p != NOSTR; p++)
        !           501:                        printgroup(*p);
        !           502:                return(0);
        !           503:        }
        !           504:        if (argcount(argv) == 1) {
        !           505:                printgroup(*argv);
        !           506:                return(0);
        !           507:        }
        !           508:        gname = *argv;
        !           509:        h = hash(gname);
        !           510:        if ((gh = findgroup(gname)) == NOGRP) {
        !           511:                gh = (struct grouphead *) calloc(sizeof *gh, 1);
        !           512:                gh->g_name = vcopy(gname);
        !           513:                gh->g_list = NOGE;
        !           514:                gh->g_link = groups[h];
        !           515:                groups[h] = gh;
        !           516:        }
        !           517: 
        !           518:        /*
        !           519:         * Insert names from the command list into the group.
        !           520:         * Who cares if there are duplicates?  They get tossed
        !           521:         * later anyway.
        !           522:         */
        !           523: 
        !           524:        for (ap = argv+1; *ap != NOSTR; ap++) {
        !           525:                gp = (struct group *) calloc(sizeof *gp, 1);
        !           526:                gp->ge_name = vcopy(*ap);
        !           527:                gp->ge_link = gh->g_list;
        !           528:                gh->g_list = gp;
        !           529:        }
        !           530:        return(0);
        !           531: }
        !           532: 
        !           533: /*
        !           534:  * Sort the passed string vecotor into ascending dictionary
        !           535:  * order.
        !           536:  */
        !           537: 
        !           538: sort(list)
        !           539:        char **list;
        !           540: {
        !           541:        register char **ap;
        !           542:        int diction();
        !           543: 
        !           544:        for (ap = list; *ap != NOSTR; ap++)
        !           545:                ;
        !           546:        if (ap-list < 2)
        !           547:                return;
        !           548:        qsort((char *)list, ap-list, sizeof *list, diction);
        !           549: }
        !           550: 
        !           551: /*
        !           552:  * Do a dictionary order comparison of the arguments from
        !           553:  * qsort.
        !           554:  */
        !           555: 
        !           556: diction(a, b)
        !           557:        register char **a, **b;
        !           558: {
        !           559:        return(strcmp(*a, *b));
        !           560: }
        !           561: 
        !           562: /*
        !           563:  * The do nothing command for comments.
        !           564:  */
        !           565: 
        !           566: /*ARGSUSED*/
        !           567: null(e)
        !           568: {
        !           569:        return 0;
        !           570: }
        !           571: 
        !           572: /*
        !           573:  * Print out the current edit file, if we are editing.
        !           574:  * Otherwise, print the name of the person who's mail
        !           575:  * we are reading.
        !           576:  */
        !           577: 
        !           578: file(argv)
        !           579:        char **argv;
        !           580: {
        !           581:        register char *cp;
        !           582:        int edit;
        !           583: 
        !           584:        if (argv[0] == NOSTR) {
        !           585:                newfileinfo();
        !           586:                return(0);
        !           587:        }
        !           588: 
        !           589:        /*
        !           590:         * Acker's!  Must switch to the new file.
        !           591:         * We use a funny interpretation --
        !           592:         *      # -- gets the previous file
        !           593:         *      % -- gets the invoker's post office box
        !           594:         *      %user -- gets someone else's post office box
        !           595:         *      & -- gets invoker's mbox file
        !           596:         *      string -- reads the given file
        !           597:         */
        !           598: 
        !           599:        cp = getfilename(argv[0], &edit);
        !           600:        if (cp == NOSTR)
        !           601:                return(-1);
        !           602:        if (setfile(cp, edit)) {
        !           603:                perror(cp);
        !           604:                return(-1);
        !           605:        }
        !           606:        announce(0);
        !           607:        return 0;
        !           608: }
        !           609: 
        !           610: /*
        !           611:  * Evaluate the string given as a new mailbox name.
        !           612:  * Ultimately, we want this to support a number of meta characters.
        !           613:  * Possibly:
        !           614:  *     % -- for my system mail box
        !           615:  *     %user -- for user's system mail box
        !           616:  *     # -- for previous file
        !           617:  *     & -- get's invoker's mbox file
        !           618:  *     file name -- for any other file
        !           619:  */
        !           620: 
        !           621: char   prevfile[PATHSIZE];
        !           622: 
        !           623: char *
        !           624: getfilename(name, aedit)
        !           625:        char *name;
        !           626:        int *aedit;
        !           627: {
        !           628:        register char *cp;
        !           629:        char savename[BUFSIZ];
        !           630:        char oldmailname[BUFSIZ];
        !           631: 
        !           632:        /*
        !           633:         * Assume we will be in "edit file" mode, until
        !           634:         * proven wrong.
        !           635:         */
        !           636:        *aedit = 1;
        !           637:        switch (*name) {
        !           638:        case '%':
        !           639:                *aedit = 0;
        !           640:                strcpy(prevfile, mailname);
        !           641:                if (name[1] != 0) {
        !           642:                        strcpy(savename, myname);
        !           643:                        strcpy(oldmailname, mailname);
        !           644:                        strncpy(myname, name+1, PATHSIZE-1);
        !           645:                        myname[PATHSIZE-1] = 0;
        !           646:                        findmail();
        !           647:                        cp = savestr(mailname);
        !           648:                        strcpy(myname, savename);
        !           649:                        strcpy(mailname, oldmailname);
        !           650:                        return(cp);
        !           651:                }
        !           652:                strcpy(oldmailname, mailname);
        !           653:                findmail();
        !           654:                cp = savestr(mailname);
        !           655:                strcpy(mailname, oldmailname);
        !           656:                return(cp);
        !           657: 
        !           658:        case '#':
        !           659:                if (name[1] != 0)
        !           660:                        goto regular;
        !           661:                if (prevfile[0] == 0) {
        !           662:                        printf("No previous file\n");
        !           663:                        return(NOSTR);
        !           664:                }
        !           665:                cp = savestr(prevfile);
        !           666:                strcpy(prevfile, mailname);
        !           667:                return(cp);
        !           668: 
        !           669:        case '&':
        !           670:                strcpy(prevfile, mailname);
        !           671:                if (name[1] == 0)
        !           672:                        return(mbox);
        !           673:                /* Fall into . . . */
        !           674: 
        !           675:        default:
        !           676: regular:
        !           677:                strcpy(prevfile, mailname);
        !           678:                cp = expand(name);
        !           679:                return(cp);
        !           680:        }
        !           681: }
        !           682: 
        !           683: /*
        !           684:  * Expand file names like echo
        !           685:  */
        !           686: 
        !           687: echo(argv)
        !           688:        char **argv;
        !           689: {
        !           690:        register char **ap;
        !           691:        register char *cp;
        !           692: 
        !           693:        for (ap = argv; *ap != NOSTR; ap++) {
        !           694:                cp = *ap;
        !           695:                if ((cp = expand(cp)) != NOSTR)
        !           696:                        printf("%s ", cp);
        !           697:        }
        !           698:        return(0);
        !           699: }
        !           700: 
        !           701: Respond(msgvec)
        !           702:        int *msgvec;
        !           703: {
        !           704:        if (value("Replyall") == NOSTR)
        !           705:                return (_Respond(msgvec));
        !           706:        else
        !           707:                return (_respond(msgvec));
        !           708: }
        !           709: 
        !           710: /*
        !           711:  * Reply to a series of messages by simply mailing to the senders
        !           712:  * and not messing around with the To: and Cc: lists as in normal
        !           713:  * reply.
        !           714:  */
        !           715: 
        !           716: _Respond(msgvec)
        !           717:        int msgvec[];
        !           718: {
        !           719:        struct header head;
        !           720:        struct message *mp;
        !           721:        register int s, *ap;
        !           722:        register char *cp, *cp2, *subject;
        !           723: 
        !           724:        for (s = 0, ap = msgvec; *ap != 0; ap++) {
        !           725:                mp = &message[*ap - 1];
        !           726:                dot = mp;
        !           727:                if ((cp = skin(hfield("from", mp))) != NOSTR)
        !           728:                    s+= strlen(cp) + 1;
        !           729:                else
        !           730:                    s += strlen(skin(nameof(mp, 2))) + 1;
        !           731:        }
        !           732:        if (s == 0)
        !           733:                return(0);
        !           734:        cp = salloc(s + 2);
        !           735:        head.h_to = cp;
        !           736:        for (ap = msgvec; *ap != 0; ap++) {
        !           737:                mp = &message[*ap - 1];
        !           738:                if ((cp2 = skin(hfield("from", mp))) == NOSTR)
        !           739:                    cp2 = skin(nameof(mp, 2));
        !           740:                cp = copy(cp2, cp);
        !           741:                *cp++ = ' ';
        !           742:        }
        !           743:        *--cp = 0;
        !           744:        mp = &message[msgvec[0] - 1];
        !           745:        subject = hfield("subject", mp);
        !           746:        head.h_seq = 0;
        !           747:        if (subject == NOSTR)
        !           748:                subject = hfield("subj", mp);
        !           749:        head.h_subject = reedit(subject);
        !           750:        if (subject != NOSTR)
        !           751:                head.h_seq++;
        !           752:        head.h_cc = NOSTR;
        !           753:        head.h_bcc = NOSTR;
        !           754:        mail1(&head);
        !           755:        return(0);
        !           756: }
        !           757: 
        !           758: /*
        !           759:  * Conditional commands.  These allow one to parameterize one's
        !           760:  * .mailrc and do some things if sending, others if receiving.
        !           761:  */
        !           762: 
        !           763: ifcmd(argv)
        !           764:        char **argv;
        !           765: {
        !           766:        register char *cp;
        !           767: 
        !           768:        if (cond != CANY) {
        !           769:                printf("Illegal nested \"if\"\n");
        !           770:                return(1);
        !           771:        }
        !           772:        cond = CANY;
        !           773:        cp = argv[0];
        !           774:        switch (*cp) {
        !           775:        case 'r': case 'R':
        !           776:                cond = CRCV;
        !           777:                break;
        !           778: 
        !           779:        case 's': case 'S':
        !           780:                cond = CSEND;
        !           781:                break;
        !           782: 
        !           783:        default:
        !           784:                printf("Unrecognized if-keyword: \"%s\"\n", cp);
        !           785:                return(1);
        !           786:        }
        !           787:        return(0);
        !           788: }
        !           789: 
        !           790: /*
        !           791:  * Implement 'else'.  This is pretty simple -- we just
        !           792:  * flip over the conditional flag.
        !           793:  */
        !           794: 
        !           795: elsecmd()
        !           796: {
        !           797: 
        !           798:        switch (cond) {
        !           799:        case CANY:
        !           800:                printf("\"Else\" without matching \"if\"\n");
        !           801:                return(1);
        !           802: 
        !           803:        case CSEND:
        !           804:                cond = CRCV;
        !           805:                break;
        !           806: 
        !           807:        case CRCV:
        !           808:                cond = CSEND;
        !           809:                break;
        !           810: 
        !           811:        default:
        !           812:                printf("Mail's idea of conditions is screwed up\n");
        !           813:                cond = CANY;
        !           814:                break;
        !           815:        }
        !           816:        return(0);
        !           817: }
        !           818: 
        !           819: /*
        !           820:  * End of if statement.  Just set cond back to anything.
        !           821:  */
        !           822: 
        !           823: endifcmd()
        !           824: {
        !           825: 
        !           826:        if (cond == CANY) {
        !           827:                printf("\"Endif\" without matching \"if\"\n");
        !           828:                return(1);
        !           829:        }
        !           830:        cond = CANY;
        !           831:        return(0);
        !           832: }
        !           833: 
        !           834: /*
        !           835:  * Set the list of alternate names.
        !           836:  */
        !           837: alternates(namelist)
        !           838:        char **namelist;
        !           839: {
        !           840:        register int c;
        !           841:        register char **ap, **ap2, *cp;
        !           842: 
        !           843:        c = argcount(namelist) + 1;
        !           844:        if (c == 1) {
        !           845:                if (altnames == 0)
        !           846:                        return(0);
        !           847:                for (ap = altnames; *ap; ap++)
        !           848:                        printf("%s ", *ap);
        !           849:                printf("\n");
        !           850:                return(0);
        !           851:        }
        !           852:        if (altnames != 0)
        !           853:                cfree((char *) altnames);
        !           854:        altnames = (char **) calloc((unsigned) c, sizeof (char *));
        !           855:        for (ap = namelist, ap2 = altnames; *ap; ap++, ap2++) {
        !           856:                cp = (char *) calloc((unsigned) strlen(*ap) + 1, sizeof (char));
        !           857:                strcpy(cp, *ap);
        !           858:                *ap2 = cp;
        !           859:        }
        !           860:        *ap2 = 0;
        !           861:        return(0);
        !           862: }

unix.superglobalmegacorp.com

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