Annotation of 43BSD/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.  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.