Annotation of researchv10no/lbin/Mail/cmd3.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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