Annotation of 40BSD/cmd/ucbmail/cmd3.c, revision 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.