Annotation of 43BSDTahoe/ucb/Mail/cmd3.c, revision 1.1.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.