Annotation of 40BSD/cmd/ucbmail/cmd3.c, revision 1.1.1.1

1.1       root        1: #
                      2: 
                      3: #include "rcv.h"
                      4: #include <sys/stat.h>
                      5: 
                      6: /*
                      7:  * Mail -- a mail program
                      8:  *
                      9:  * Still more user commands.
                     10:  */
                     11: 
                     12: /*
                     13:  * Process a shell escape by saving signals, ignoring signals,
                     14:  * and forking a sh -c
                     15:  */
                     16: 
                     17: shell(str)
                     18:        char *str;
                     19: {
                     20:        int (*sig[2])(), stat[1];
                     21:        register int t;
                     22:        char *Shell;
                     23: 
                     24:        if ((Shell = value("SHELL")) == NOSTR)
                     25:                Shell = SHELL;
                     26:        for (t = 2; t < 4; t++)
                     27:                sig[t-2] = signal(t, SIG_IGN);
                     28:        t = vfork();
                     29:        if (t == 0) {
                     30:                for (t = 2; t < 4; t++)
                     31:                        if (sig[t-2] != SIG_IGN)
                     32:                                signal(t, SIG_DFL);
                     33:                execl(Shell, Shell, "-c", str, 0);
                     34:                perror(Shell);
                     35:                _exit(1);
                     36:        }
                     37:        while (wait(stat) != t)
                     38:                ;
                     39:        if (t == -1)
                     40:                perror("fork");
                     41:        for (t = 2; t < 4; t++)
                     42:                signal(t, sig[t-2]);
                     43:        printf("!\n");
                     44:        return(0);
                     45: }
                     46: 
                     47: /*
                     48:  * Fork an interactive shell.
                     49:  */
                     50: 
                     51: dosh(str)
                     52:        char *str;
                     53: {
                     54:        int (*sig[2])(), stat[1];
                     55:        register int t;
                     56:        char *Shell;
                     57: 
                     58:        if ((Shell = value("SHELL")) == NOSTR)
                     59:                Shell = SHELL;
                     60:        for (t = 2; t < 4; t++)
                     61:                sig[t-2] = signal(t, SIG_IGN);
                     62:        t = vfork();
                     63:        if (t == 0) {
                     64:                for (t = 2; t < 4; t++)
                     65:                        if (sig[t-2] != SIG_IGN)
                     66:                                signal(t, SIG_DFL);
                     67:                execl(Shell, Shell, 0);
                     68:                perror(Shell);
                     69:                _exit(1);
                     70:        }
                     71:        while (wait(stat) != t)
                     72:                ;
                     73:        if (t == -1)
                     74:                perror("fork");
                     75:        for (t = 2; t < 4; t++)
                     76:                signal(t, sig[t-2]);
                     77:        putchar('\n');
                     78:        return(0);
                     79: }
                     80: 
                     81: /*
                     82:  * Print out a nice help message from some file or another.
                     83:  */
                     84: 
                     85: help()
                     86: {
                     87:        register c;
                     88:        register FILE *f;
                     89: 
                     90:        if ((f = fopen(HELPFILE, "r")) == NULL) {
                     91:                printf("No help just now.\n");
                     92:                return(1);
                     93:        }
                     94:        while ((c = getc(f)) != EOF)
                     95:                putchar(c);
                     96:        fclose(f);
                     97:        return(0);
                     98: }
                     99: 
                    100: /*
                    101:  * Change user's working directory.
                    102:  */
                    103: 
                    104: schdir(str)
                    105:        char *str;
                    106: {
                    107:        register char *cp;
                    108: 
                    109:        for (cp = str; *cp == ' '; cp++)
                    110:                ;
                    111:        if (*cp == '\0')
                    112:                cp = homedir;
                    113:        else
                    114:                if ((cp = expand(cp)) == NOSTR)
                    115:                        return(1);
                    116:        if (chdir(cp) < 0) {
                    117:                perror(cp);
                    118:                return(1);
                    119:        }
                    120:        return(0);
                    121: }
                    122: 
                    123: /*
                    124:  * Reply to a list of messages.  Extract each name from the
                    125:  * message header and send them off to mail1()
                    126:  */
                    127: 
                    128: respond(msgvec)
                    129:        int *msgvec;
                    130: {
                    131:        struct message *mp;
                    132:        char *cp, buf[2 * LINESIZE], *rcv;
                    133:        struct name *np;
                    134:        struct header head;
                    135:        char *netmap();
                    136: 
                    137:        if (msgvec[1] != 0) {
                    138:                printf("Sorry, can't reply to multiple messages at once\n");
                    139:                return(1);
                    140:        }
                    141:        mp = &message[msgvec[0] - 1];
                    142:        dot = mp;
                    143:        rcv = nameof(mp);
                    144:        strcpy(buf, "");
                    145:        cp = hfield("to", mp);
                    146:        if (cp != NOSTR)
                    147:                strcpy(buf, cp);
                    148:        np = elide(extract(buf, GTO));
                    149:        /* rcv = rename(rcv); */
                    150:        mapf(np, rcv);
                    151:        np = delname(np, myname);
                    152:        head.h_seq = 1;
                    153:        cp = detract(np, 0);
                    154:        if (cp != NOSTR) {
                    155:                strcpy(buf, cp);
                    156:                strcat(buf, " ");
                    157:                strcat(buf, rcv);
                    158:        }
                    159:        else
                    160:                strcpy(buf, rcv);
                    161:        head.h_to = buf;
                    162:        head.h_subject = hfield("subject", mp);
                    163:        if (head.h_subject == NOSTR)
                    164:                head.h_subject = hfield("subj", mp);
                    165:        head.h_cc = NOSTR;
                    166:        cp = hfield("cc", mp);
                    167:        if (cp != NOSTR) {
                    168:                np = elide(extract(cp, GCC));
                    169:                mapf(np, rcv);
                    170:                np = delname(np, myname);
                    171:                head.h_cc = detract(np, 0);
                    172:        }
                    173:        head.h_bcc = NOSTR;
                    174:        mail1(&head);
                    175:        return(0);
                    176: }
                    177: 
                    178: /*
                    179:  * Preserve the named messages, so that they will be sent
                    180:  * back to the system mailbox.
                    181:  */
                    182: 
                    183: preserve(msgvec)
                    184:        int *msgvec;
                    185: {
                    186:        register struct message *mp;
                    187:        register int *ip, mesg;
                    188: 
                    189:        if (edit) {
                    190:                printf("Cannot \"preserve\" in edit mode\n");
                    191:                return(1);
                    192:        }
                    193:        for (ip = msgvec; *ip != NULL; ip++) {
                    194:                mesg = *ip;
                    195:                mp = &message[mesg-1];
                    196:                mp->m_flag |= MPRESERVE;
                    197:                dot = mp;
                    198:        }
                    199:        return(0);
                    200: }
                    201: 
                    202: /*
                    203:  * Print the size of each message.
                    204:  */
                    205: 
                    206: messize(msgvec)
                    207:        int *msgvec;
                    208: {
                    209:        register struct message *mp;
                    210:        register int *ip, mesg;
                    211: 
                    212:        for (ip = msgvec; *ip != NULL; ip++) {
                    213:                mesg = *ip;
                    214:                mp = &message[mesg-1];
                    215:                printf("%d: %d\n", mesg, msize(mp));
                    216:        }
                    217:        return(0);
                    218: }
                    219: 
                    220: /*
                    221:  * Quit quickly.  If we are sourcing, just pop the input level
                    222:  * by returning an error.
                    223:  */
                    224: 
                    225: rexit(e)
                    226: {
                    227:        if (sourcing)
                    228:                return(1);
                    229:        exit(e);
                    230: }
                    231: 
                    232: /*
                    233:  * Set or display a variable value.  Syntax is similar to that
                    234:  * of csh.
                    235:  */
                    236: 
                    237: set(arglist)
                    238:        char **arglist;
                    239: {
                    240:        register struct var *vp;
                    241:        register char *cp, *cp2;
                    242:        char varbuf[BUFSIZ], **ap, **p;
                    243:        int errs, h, s;
                    244: 
                    245:        if (argcount(arglist) == 0) {
                    246:                for (h = 0, s = 1; h < HSHSIZE; h++)
                    247:                        for (vp = variables[h]; vp != NOVAR; vp = vp->v_link)
                    248:                                s++;
                    249:                ap = (char **) salloc(s * sizeof *ap);
                    250:                for (h = 0, p = ap; h < HSHSIZE; h++)
                    251:                        for (vp = variables[h]; vp != NOVAR; vp = vp->v_link)
                    252:                                *p++ = vp->v_name;
                    253:                *p = NOSTR;
                    254:                sort(ap);
                    255:                for (p = ap; *p != NOSTR; p++)
                    256:                        printf("%s\t%s\n", *p, value(*p));
                    257:                return(0);
                    258:        }
                    259:        errs = 0;
                    260:        for (ap = arglist; *ap != NOSTR; ap++) {
                    261:                cp = *ap;
                    262:                cp2 = varbuf;
                    263:                while (*cp != '=' && *cp != '\0')
                    264:                        *cp2++ = *cp++;
                    265:                *cp2 = '\0';
                    266:                if (*cp == '\0')
                    267:                        cp = "";
                    268:                else
                    269:                        cp++;
                    270:                if (equal(varbuf, "")) {
                    271:                        printf("Non-null variable name required\n");
                    272:                        errs++;
                    273:                        continue;
                    274:                }
                    275:                assign(varbuf, cp);
                    276:        }
                    277:        return(errs);
                    278: }
                    279: 
                    280: /*
                    281:  * Unset a bunch of variable values.
                    282:  */
                    283: 
                    284: unset(arglist)
                    285:        char **arglist;
                    286: {
                    287:        register struct var *vp, *vp2;
                    288:        register char *cp;
                    289:        int errs, h;
                    290:        char **ap;
                    291: 
                    292:        errs = 0;
                    293:        for (ap = arglist; *ap != NOSTR; ap++) {
                    294:                if ((vp2 = lookup(*ap)) == NOVAR) {
                    295:                        if (!sourcing) {
                    296:                                printf("\"%s\": undefined variable\n", *ap);
                    297:                                errs++;
                    298:                        }
                    299:                        continue;
                    300:                }
                    301:                h = hash(*ap);
                    302:                if (vp2 == variables[h]) {
                    303:                        variables[h] = variables[h]->v_link;
                    304:                        vfree(vp2->v_name);
                    305:                        vfree(vp2->v_value);
                    306:                        cfree(vp2);
                    307:                        continue;
                    308:                }
                    309:                for (vp = variables[h]; vp->v_link != vp2; vp = vp->v_link)
                    310:                        ;
                    311:                vp->v_link = vp2->v_link;
                    312:                vfree(vp2->v_name);
                    313:                vfree(vp2->v_value);
                    314:                cfree(vp2);
                    315:        }
                    316:        return(errs);
                    317: }
                    318: 
                    319: /*
                    320:  * Put add users to a group.
                    321:  */
                    322: 
                    323: group(argv)
                    324:        char **argv;
                    325: {
                    326:        register struct grouphead *gh;
                    327:        register struct group *gp;
                    328:        register int h;
                    329:        int s;
                    330:        char **ap, *gname, **p;
                    331: 
                    332:        if (argcount(argv) == 0) {
                    333:                for (h = 0, s = 1; h < HSHSIZE; h++)
                    334:                        for (gh = groups[h]; gh != NOGRP; gh = gh->g_link)
                    335:                                s++;
                    336:                ap = (char **) salloc(s * sizeof *ap);
                    337:                for (h = 0, p = ap; h < HSHSIZE; h++)
                    338:                        for (gh = groups[h]; gh != NOGRP; gh = gh->g_link)
                    339:                                *p++ = gh->g_name;
                    340:                *p = NOSTR;
                    341:                sort(ap);
                    342:                for (p = ap; *p != NOSTR; p++)
                    343:                        printgroup(*p);
                    344:                return(0);
                    345:        }
                    346:        if (argcount(argv) == 1) {
                    347:                printgroup(*argv);
                    348:                return(0);
                    349:        }
                    350:        gname = *argv;
                    351:        h = hash(gname);
                    352:        if ((gh = findgroup(gname)) == NOGRP) {
                    353:                gh = (struct grouphead *) calloc(sizeof *gh, 1);
                    354:                gh->g_name = vcopy(gname);
                    355:                gh->g_list = NOGE;
                    356:                gh->g_link = groups[h];
                    357:                groups[h] = gh;
                    358:        }
                    359: 
                    360:        /*
                    361:         * Insert names from the command list into the group.
                    362:         * Who cares if there are duplicates?  They get tossed
                    363:         * later anyway.
                    364:         */
                    365: 
                    366:        for (ap = argv+1; *ap != NOSTR; ap++) {
                    367:                gp = (struct group *) calloc(sizeof *gp, 1);
                    368:                gp->ge_name = vcopy(*ap);
                    369:                gp->ge_link = gh->g_list;
                    370:                gh->g_list = gp;
                    371:        }
                    372:        return(0);
                    373: }
                    374: 
                    375: /*
                    376:  * Sort the passed string vecotor into ascending dictionary
                    377:  * order.
                    378:  */
                    379: 
                    380: sort(list)
                    381:        char **list;
                    382: {
                    383:        register char **ap;
                    384:        int diction();
                    385: 
                    386:        for (ap = list; *ap != NOSTR; ap++)
                    387:                ;
                    388:        if (ap-list < 2)
                    389:                return;
                    390:        qsort(list, ap-list, sizeof *list, diction);
                    391: }
                    392: 
                    393: /*
                    394:  * Do a dictionary order comparison of the arguments from
                    395:  * qsort.
                    396:  */
                    397: 
                    398: diction(a, b)
                    399:        register char **a, **b;
                    400: {
                    401:        return(strcmp(*a, *b));
                    402: }
                    403: 
                    404: /*
                    405:  * The do nothing command for comments.
                    406:  */
                    407: 
                    408: null(e)
                    409: {
                    410:        return(0);
                    411: }
                    412: 
                    413: /*
                    414:  * Print out the current edit file, if we are editting.
                    415:  * Otherwise, print the name of the person who's mail
                    416:  * we are reading.
                    417:  */
                    418: 
                    419: file(e)
                    420: {
                    421:        register char *cp;
                    422: 
                    423:        if (edit)
                    424:                printf("Reading \"%s\"\n", editfile);
                    425:        else
                    426:                printf("Reading %s's mail\n", rindex(mailname, '/') + 1);
                    427:        return(0);
                    428: }
                    429: 
                    430: /*
                    431:  * Expand file names like echo
                    432:  */
                    433: 
                    434: echo(argv)
                    435:        char **argv;
                    436: {
                    437:        register char **ap;
                    438:        register char *cp;
                    439: 
                    440:        for (ap = argv; *ap != NOSTR; ap++) {
                    441:                cp = *ap;
                    442:                if ((cp = expand(cp)) != NOSTR)
                    443:                        printf("%s\n", cp);
                    444:        }
                    445:        return(0);
                    446: }
                    447: 
                    448: /*
                    449:  * Reply to a series of messages by simply mailing to the senders
                    450:  * and not messing around with the To: and Cc: lists as in normal
                    451:  * reply.
                    452:  */
                    453: 
                    454: Respond(msgvec)
                    455:        int msgvec[];
                    456: {
                    457:        struct header head;
                    458:        struct message *mp;
                    459:        register int s, *ap;
                    460:        register char *cp, *subject;
                    461: 
                    462:        for (s = 0, ap = msgvec; *ap != 0; ap++) {
                    463:                mp = &message[*ap - 1];
                    464:                dot = mp;
                    465:                s += strlen(nameof(mp)) + 1;
                    466:        }
                    467:        if (s == 0)
                    468:                return(0);
                    469:        cp = salloc(s + 2);
                    470:        head.h_to = cp;
                    471:        for (ap = msgvec; *ap != 0; ap++) {
                    472:                mp = &message[*ap - 1];
                    473:                cp = copy(nameof(mp), cp);
                    474:                *cp++ = ' ';
                    475:        }
                    476:        *--cp = 0;
                    477:        mp = &message[msgvec[0] - 1];
                    478:        subject = hfield("subject", mp);
                    479:        head.h_seq = 0;
                    480:        if (subject == NOSTR)
                    481:                subject = hfield("subj", mp);
                    482:        head.h_subject = subject;
                    483:        if (subject != NOSTR)
                    484:                head.h_seq++;
                    485:        head.h_cc = NOSTR;
                    486:        head.h_bcc = NOSTR;
                    487:        mail1(&head);
                    488:        return(0);
                    489: }

unix.superglobalmegacorp.com

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