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

unix.superglobalmegacorp.com

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