Annotation of 3BSD/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:        rcv = nameof(mp);
                    143:        strcpy(buf, "");
                    144:        cp = hfield("to", mp);
                    145:        if (cp != NOSTR)
                    146:                strcpy(buf, cp);
                    147:        np = elide(extract(buf));
                    148:        mapf(np, rcv);
                    149:        np = delname(np, myname);
                    150:        head.h_seq = 1;
                    151:        cp = detract(np);
                    152:        if (cp != NOSTR) {
                    153:                strcpy(buf, cp);
                    154:                strcat(buf, " ");
                    155:                strcat(buf, rcv);
                    156:        }
                    157:        else
                    158:                strcpy(buf, rcv);
                    159:        head.h_to = buf;
                    160:        head.h_subject = hfield("subject", mp);
                    161:        if (head.h_subject == NOSTR)
                    162:                head.h_subject = hfield("subj", mp);
                    163:        head.h_cc = NOSTR;
                    164:        cp = hfield("cc", mp);
                    165:        if (cp != NOSTR) {
                    166:                np = elide(extract(cp));
                    167:                mapf(np, rcv);
                    168:                np = delname(np, myname);
                    169:                head.h_cc = detract(np);
                    170:        }
                    171:        head.h_bcc = NOSTR;
                    172:        mail1(&head);
                    173:        return(0);
                    174: }
                    175: 
                    176: /*
                    177:  * Preserve the named messages, so that they will be sent
                    178:  * back to the system mailbox.
                    179:  */
                    180: 
                    181: preserve(msgvec)
                    182:        int *msgvec;
                    183: {
                    184:        register struct message *mp;
                    185:        register int *ip, mesg;
                    186: 
                    187:        if (edit) {
                    188:                printf("Cannot \"preserve\" in edit mode\n");
                    189:                return(1);
                    190:        }
                    191:        for (ip = msgvec; *ip != NULL; ip++) {
                    192:                mesg = *ip;
                    193:                mp = &message[mesg-1];
                    194:                mp->m_flag |= MPRESERVE;
                    195:                dot = mp;
                    196:        }
                    197:        return(0);
                    198: }
                    199: 
                    200: /*
                    201:  * Print the size of each message.
                    202:  */
                    203: 
                    204: messize(msgvec)
                    205:        int *msgvec;
                    206: {
                    207:        register struct message *mp;
                    208:        register int *ip, mesg;
                    209: 
                    210:        for (ip = msgvec; *ip != NULL; ip++) {
                    211:                mesg = *ip;
                    212:                mp = &message[mesg-1];
                    213:                printf("%d: %d\n", mesg, msize(mp));
                    214:        }
                    215:        return(0);
                    216: }
                    217: 
                    218: /*
                    219:  * Quit quickly.  If we are sourcing, just pop the input level
                    220:  * by returning an error.
                    221:  */
                    222: 
                    223: rexit(e)
                    224: {
                    225:        if (sourcing)
                    226:                return(1);
                    227:        exit(e);
                    228: }
                    229: 
                    230: /*
                    231:  * Set or display a variable value.  Syntax is similar to that
                    232:  * of csh.
                    233:  */
                    234: 
                    235: set(arglist)
                    236:        char **arglist;
                    237: {
                    238:        register struct var *vp;
                    239:        register char *cp, *cp2;
                    240:        char varbuf[BUFSIZ], **ap, **p;
                    241:        int errs, h, s;
                    242: 
                    243:        if (argcount(arglist) == 0) {
                    244:                for (h = 0, s = 1; h < HSHSIZE; h++)
                    245:                        for (vp = variables[h]; vp != NOVAR; vp = vp->v_link)
                    246:                                s++;
                    247:                ap = (char **) salloc(s * sizeof *ap);
                    248:                for (h = 0, p = ap; h < HSHSIZE; h++)
                    249:                        for (vp = variables[h]; vp != NOVAR; vp = vp->v_link)
                    250:                                *p++ = vp->v_name;
                    251:                *p = NOSTR;
                    252:                sort(ap);
                    253:                for (p = ap; *p != NOSTR; p++)
                    254:                        printf("%s\t%s\n", *p, value(*p));
                    255:                return(0);
                    256:        }
                    257:        errs = 0;
                    258:        for (ap = arglist; *ap != NOSTR; ap++) {
                    259:                cp = *ap;
                    260:                cp2 = varbuf;
                    261:                while (*cp != '=' && *cp != '\0')
                    262:                        *cp2++ = *cp++;
                    263:                *cp2 = '\0';
                    264:                if (*cp == '\0')
                    265:                        cp = "";
                    266:                else
                    267:                        cp++;
                    268:                if (equal(varbuf, "")) {
                    269:                        printf("Non-null variable name required\n");
                    270:                        errs++;
                    271:                        continue;
                    272:                }
                    273:                assign(varbuf, cp);
                    274:        }
                    275:        return(errs);
                    276: }
                    277: 
                    278: /*
                    279:  * Unset a bunch of variable values.
                    280:  */
                    281: 
                    282: unset(arglist)
                    283:        char **arglist;
                    284: {
                    285:        register struct var *vp, *vp2;
                    286:        register char *cp;
                    287:        int errs, h;
                    288:        char **ap;
                    289: 
                    290:        errs = 0;
                    291:        for (ap = arglist; *ap != NOSTR; ap++) {
                    292:                if ((vp2 = lookup(*ap)) == NOVAR) {
                    293:                        if (!sourcing) {
                    294:                                printf("\"%s\": undefined variable\n", *ap);
                    295:                                errs++;
                    296:                        }
                    297:                        continue;
                    298:                }
                    299:                h = hash(*ap);
                    300:                if (vp2 == variables[h]) {
                    301:                        variables[h] = variables[h]->v_link;
                    302:                        vfree(vp2->v_name);
                    303:                        vfree(vp2->v_value);
                    304:                        cfree(vp2);
                    305:                        continue;
                    306:                }
                    307:                for (vp = variables[h]; vp->v_link != vp2; vp = vp->v_link)
                    308:                        ;
                    309:                vp->v_link = vp2->v_link;
                    310:                vfree(vp2->v_name);
                    311:                vfree(vp2->v_value);
                    312:                cfree(vp2);
                    313:        }
                    314:        return(errs);
                    315: }
                    316: 
                    317: /*
                    318:  * Put add users to a group.
                    319:  */
                    320: 
                    321: group(argv)
                    322:        char **argv;
                    323: {
                    324:        register struct grouphead *gh;
                    325:        register struct group *gp;
                    326:        register int h;
                    327:        int s;
                    328:        char **ap, *gname, **p;
                    329: 
                    330:        if (argcount(argv) == 0) {
                    331:                for (h = 0, s = 1; h < HSHSIZE; h++)
                    332:                        for (gh = groups[h]; gh != NOGRP; gh = gh->g_link)
                    333:                                s++;
                    334:                ap = (char **) salloc(s * sizeof *ap);
                    335:                for (h = 0, p = ap; h < HSHSIZE; h++)
                    336:                        for (gh = groups[h]; gh != NOGRP; gh = gh->g_link)
                    337:                                *p++ = gh->g_name;
                    338:                *p = NOSTR;
                    339:                sort(ap);
                    340:                for (p = ap; *p != NOSTR; p++)
                    341:                        printgroup(*p);
                    342:                return(0);
                    343:        }
                    344:        if (argcount(argv) == 1) {
                    345:                printgroup(*argv);
                    346:                return(0);
                    347:        }
                    348:        gname = *argv;
                    349:        h = hash(gname);
                    350:        if ((gh = findgroup(gname)) == NOGRP) {
                    351:                gh = (struct grouphead *) calloc(sizeof *gh, 1);
                    352:                gh->g_name = vcopy(gname);
                    353:                gh->g_list = NOGE;
                    354:                gh->g_link = groups[h];
                    355:                groups[h] = gh;
                    356:        }
                    357: 
                    358:        /*
                    359:         * Insert names from the command list into the group.
                    360:         * Who cares if there are duplicates?  They got tossed
                    361:         * later anyway.
                    362:         */
                    363: 
                    364:        for (ap = argv+1; *ap != NOSTR; ap++) {
                    365:                gp = (struct group *) calloc(sizeof *gp, 1);
                    366:                gp->ge_name = vcopy(*ap);
                    367:                gp->ge_link = gh->g_list;
                    368:                gh->g_list = gp;
                    369:        }
                    370:        return(0);
                    371: }
                    372: 
                    373: /*
                    374:  * Sort the passed string vecotor into ascending dictionary
                    375:  * order.
                    376:  */
                    377: 
                    378: sort(list)
                    379:        char **list;
                    380: {
                    381:        register char **ap;
                    382:        int diction();
                    383: 
                    384:        for (ap = list; *ap != NOSTR; ap++)
                    385:                ;
                    386:        if (ap-list < 2)
                    387:                return;
                    388:        qsort(list, ap-list, sizeof *list, diction);
                    389: }
                    390: 
                    391: /*
                    392:  * Do a dictionary order comparison of the arguments from
                    393:  * qsort.
                    394:  */
                    395: 
                    396: diction(a, b)
                    397:        register char **a, **b;
                    398: {
                    399:        return(strcmp(*a, *b));
                    400: }
                    401: 
                    402: /*
                    403:  * The do nothing command for comments.
                    404:  */
                    405: 
                    406: null(e)
                    407: {
                    408:        return(0);
                    409: }
                    410: 
                    411: /*
                    412:  * Print out the current edit file, if we are editting.
                    413:  * Otherwise, print the name of the person who's mail
                    414:  * we are reading.
                    415:  */
                    416: 
                    417: file(e)
                    418: {
                    419:        register char *cp;
                    420: 
                    421:        if (edit)
                    422:                printf("Reading \"%s\"\n", editfile);
                    423:        else
                    424:                printf("Reading %s's mail\n", rindex(mailname, '/') + 1);
                    425:        return(0);
                    426: }
                    427: 
                    428: /*
                    429:  * Expand file names like echo
                    430:  */
                    431: 
                    432: echo(argv)
                    433:        char **argv;
                    434: {
                    435:        register char **ap;
                    436:        register char *cp;
                    437: 
                    438:        for (ap = argv; *ap != NOSTR; ap++) {
                    439:                cp = *ap;
                    440:                if ((cp = expand(cp)) != NOSTR)
                    441:                        printf("%s\n", cp);
                    442:        }
                    443:        return(0);
                    444: }
                    445: 
                    446: /*
                    447:  * Reply to a series of messages by simply mailing to the senders
                    448:  * and not messing around with the To: and Cc: lists as in normal
                    449:  * reply.
                    450:  */
                    451: 
                    452: Respond(msgvec)
                    453:        int msgvec[];
                    454: {
                    455:        struct header head;
                    456:        struct message *mp;
                    457:        register int s, *ap;
                    458:        register char *cp, *subject;
                    459: 
                    460:        for (s = 0, ap = msgvec; *ap != 0; ap++) {
                    461:                mp = &message[*ap - 1];
                    462:                s += strlen(nameof(mp)) + 1;
                    463:        }
                    464:        if (s == 0)
                    465:                return(0);
                    466:        cp = salloc(s + 2);
                    467:        head.h_to = cp;
                    468:        for (ap = msgvec; *ap != 0; ap++) {
                    469:                mp = &message[*ap - 1];
                    470:                cp = copy(nameof(mp), cp);
                    471:                *cp++ = ' ';
                    472:        }
                    473:        *--cp = 0;
                    474:        mp = &message[msgvec[0] - 1];
                    475:        subject = hfield("subject", mp);
                    476:        if (subject == NOSTR)
                    477:                subject = hfield("subj", mp);
                    478:        head.h_subject = subject;
                    479:        head.h_cc = NOSTR;
                    480:        head.h_bcc = NOSTR;
                    481:        head.h_seq = 0;
                    482:        mail1(&head);
                    483:        return(0);
                    484: }

unix.superglobalmegacorp.com

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