Annotation of 42BSD/ucb/Mail/cmd1.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)cmd1.c     2.12 (Berkeley) 8/11/83";
                      3: #endif
                      4: 
                      5: #include "rcv.h"
                      6: #include <sys/stat.h>
                      7: 
                      8: /*
                      9:  * Mail -- a mail program
                     10:  *
                     11:  * User commands.
                     12:  */
                     13: 
                     14: /*
                     15:  * Print the current active headings.
                     16:  * Don't change dot if invoker didn't give an argument.
                     17:  */
                     18: 
                     19: static int screen;
                     20: 
                     21: headers(msgvec)
                     22:        int *msgvec;
                     23: {
                     24:        register int n, mesg, flag;
                     25:        register struct message *mp;
                     26:        int size;
                     27: 
                     28:        size = screensize();
                     29:        n = msgvec[0];
                     30:        if (n != 0)
                     31:                screen = (n-1)/size;
                     32:        if (screen < 0)
                     33:                screen = 0;
                     34:        mp = &message[screen * size];
                     35:        if (mp >= &message[msgCount])
                     36:                mp = &message[msgCount - size];
                     37:        if (mp < &message[0])
                     38:                mp = &message[0];
                     39:        flag = 0;
                     40:        mesg = mp - &message[0];
                     41:        if (dot != &message[n-1])
                     42:                dot = mp;
                     43:        for (; mp < &message[msgCount]; mp++) {
                     44:                mesg++;
                     45:                if (mp->m_flag & MDELETED)
                     46:                        continue;
                     47:                if (flag++ >= size)
                     48:                        break;
                     49:                printhead(mesg);
                     50:                sreset();
                     51:        }
                     52:        if (flag == 0) {
                     53:                printf("No more mail.\n");
                     54:                return(1);
                     55:        }
                     56:        return(0);
                     57: }
                     58: 
                     59: /*
                     60:  * Set the list of alternate names for out host.
                     61:  */
                     62: local(namelist)
                     63:        char **namelist;
                     64: {
                     65:        register int c;
                     66:        register char **ap, **ap2, *cp;
                     67: 
                     68:        c = argcount(namelist) + 1;
                     69:        if (c == 1) {
                     70:                if (localnames == 0)
                     71:                        return(0);
                     72:                for (ap = localnames; *ap; ap++)
                     73:                        printf("%s ", *ap);
                     74:                printf("\n");
                     75:                return(0);
                     76:        }
                     77:        if (localnames != 0)
                     78:                cfree((char *) localnames);
                     79:        localnames = (char **) calloc(c, sizeof (char *));
                     80:        for (ap = namelist, ap2 = localnames; *ap; ap++, ap2++) {
                     81:                cp = (char *) calloc(strlen(*ap) + 1, sizeof (char));
                     82:                strcpy(cp, *ap);
                     83:                *ap2 = cp;
                     84:        }
                     85:        *ap2 = 0;
                     86:        return(0);
                     87: }
                     88: 
                     89: /*
                     90:  * Scroll to the next/previous screen
                     91:  */
                     92: 
                     93: scroll(arg)
                     94:        char arg[];
                     95: {
                     96:        register int s, size;
                     97:        int cur[1];
                     98: 
                     99:        cur[0] = 0;
                    100:        size = screensize();
                    101:        s = screen;
                    102:        switch (*arg) {
                    103:        case 0:
                    104:        case '+':
                    105:                s++;
                    106:                if (s * size > msgCount) {
                    107:                        printf("On last screenful of messages\n");
                    108:                        return(0);
                    109:                }
                    110:                screen = s;
                    111:                break;
                    112: 
                    113:        case '-':
                    114:                if (--s < 0) {
                    115:                        printf("On first screenful of messages\n");
                    116:                        return(0);
                    117:                }
                    118:                screen = s;
                    119:                break;
                    120: 
                    121:        default:
                    122:                printf("Unrecognized scrolling command \"%s\"\n", arg);
                    123:                return(1);
                    124:        }
                    125:        return(headers(cur));
                    126: }
                    127: 
                    128: /*
                    129:  * Compute what the screen size should be.
                    130:  * We use the following algorithm:
                    131:  *     If user specifies with screen option, use that.
                    132:  *     If baud rate < 1200, use  5
                    133:  *     If baud rate = 1200, use 10
                    134:  *     If baud rate > 1200, use 20
                    135:  */
                    136: screensize()
                    137: {
                    138:        register char *cp;
                    139:        register int s;
                    140: 
                    141:        if ((cp = value("screen")) != NOSTR) {
                    142:                s = atoi(cp);
                    143:                if (s > 0)
                    144:                        return(s);
                    145:        }
                    146:        if (baud < B1200)
                    147:                s = 5;
                    148:        else if (baud == B1200)
                    149:                s = 10;
                    150:        else
                    151:                s = 20;
                    152:        return(s);
                    153: }
                    154: 
                    155: /*
                    156:  * Print out the headlines for each message
                    157:  * in the passed message list.
                    158:  */
                    159: 
                    160: from(msgvec)
                    161:        int *msgvec;
                    162: {
                    163:        register int *ip;
                    164: 
                    165:        for (ip = msgvec; *ip != NULL; ip++) {
                    166:                printhead(*ip);
                    167:                sreset();
                    168:        }
                    169:        if (--ip >= msgvec)
                    170:                dot = &message[*ip - 1];
                    171:        return(0);
                    172: }
                    173: 
                    174: /*
                    175:  * Print out the header of a specific message.
                    176:  * This is a slight improvement to the standard one.
                    177:  */
                    178: 
                    179: printhead(mesg)
                    180: {
                    181:        struct message *mp;
                    182:        FILE *ibuf;
                    183:        char headline[LINESIZE], wcount[10], *subjline, dispc, curind;
                    184:        char pbuf[BUFSIZ];
                    185:        int s;
                    186:        struct headline hl;
                    187:        register char *cp;
                    188: 
                    189:        mp = &message[mesg-1];
                    190:        ibuf = setinput(mp);
                    191:        readline(ibuf, headline);
                    192:        subjline = hfield("subject", mp);
                    193:        if (subjline == NOSTR)
                    194:                subjline = hfield("subj", mp);
                    195: 
                    196:        /*
                    197:         * Bletch!
                    198:         */
                    199: 
                    200:        if (subjline != NOSTR && strlen(subjline) > 28)
                    201:                subjline[29] = '\0';
                    202:        curind = dot == mp ? '>' : ' ';
                    203:        dispc = ' ';
                    204:        if (mp->m_flag & MSAVED)
                    205:                dispc = '*';
                    206:        if (mp->m_flag & MPRESERVE)
                    207:                dispc = 'P';
                    208:        if ((mp->m_flag & (MREAD|MNEW)) == MNEW)
                    209:                dispc = 'N';
                    210:        if ((mp->m_flag & (MREAD|MNEW)) == 0)
                    211:                dispc = 'U';
                    212:        if (mp->m_flag & MBOX)
                    213:                dispc = 'M';
                    214:        parse(headline, &hl, pbuf);
                    215:        sprintf(wcount, " %d/%ld", mp->m_lines, mp->m_size);
                    216:        s = strlen(wcount);
                    217:        cp = wcount + s;
                    218:        while (s < 7)
                    219:                s++, *cp++ = ' ';
                    220:        *cp = '\0';
                    221:        if (subjline != NOSTR)
                    222:                printf("%c%c%3d %-8s %16.16s %s \"%s\"\n", curind, dispc, mesg,
                    223:                    nameof(mp, 0), hl.l_date, wcount, subjline);
                    224:        else
                    225:                printf("%c%c%3d %-8s %16.16s %s\n", curind, dispc, mesg,
                    226:                    nameof(mp, 0), hl.l_date, wcount);
                    227: }
                    228: 
                    229: /*
                    230:  * Print out the value of dot.
                    231:  */
                    232: 
                    233: pdot()
                    234: {
                    235:        printf("%d\n", dot - &message[0] + 1);
                    236:        return(0);
                    237: }
                    238: 
                    239: /*
                    240:  * Print out all the possible commands.
                    241:  */
                    242: 
                    243: pcmdlist()
                    244: {
                    245:        register struct cmd *cp;
                    246:        register int cc;
                    247:        extern struct cmd cmdtab[];
                    248: 
                    249:        printf("Commands are:\n");
                    250:        for (cc = 0, cp = cmdtab; cp->c_name != NULL; cp++) {
                    251:                cc += strlen(cp->c_name) + 2;
                    252:                if (cc > 72) {
                    253:                        printf("\n");
                    254:                        cc = strlen(cp->c_name) + 2;
                    255:                }
                    256:                if ((cp+1)->c_name != NOSTR)
                    257:                        printf("%s, ", cp->c_name);
                    258:                else
                    259:                        printf("%s\n", cp->c_name);
                    260:        }
                    261:        return(0);
                    262: }
                    263: 
                    264: /*
                    265:  * Type out messages, honor ignored fields.
                    266:  */
                    267: type(msgvec)
                    268:        int *msgvec;
                    269: {
                    270: 
                    271:        return(type1(msgvec, 1));
                    272: }
                    273: 
                    274: /*
                    275:  * Type out messages, even printing ignored fields.
                    276:  */
                    277: Type(msgvec)
                    278:        int *msgvec;
                    279: {
                    280: 
                    281:        return(type1(msgvec, 0));
                    282: }
                    283: 
                    284: /*
                    285:  * Type out the messages requested.
                    286:  */
                    287: jmp_buf        pipestop;
                    288: 
                    289: type1(msgvec, doign)
                    290:        int *msgvec;
                    291: {
                    292:        register *ip;
                    293:        register struct message *mp;
                    294:        register int mesg;
                    295:        register char *cp;
                    296:        int c, nlines;
                    297:        int brokpipe();
                    298:        FILE *ibuf, *obuf;
                    299: 
                    300:        obuf = stdout;
                    301:        if (setjmp(pipestop)) {
                    302:                if (obuf != stdout) {
                    303:                        pipef = NULL;
                    304:                        pclose(obuf);
                    305:                }
                    306:                sigset(SIGPIPE, SIG_DFL);
                    307:                return(0);
                    308:        }
                    309:        if (intty && outtty && (cp = value("crt")) != NOSTR) {
                    310:                for (ip = msgvec, nlines = 0; *ip && ip-msgvec < msgCount; ip++)
                    311:                        nlines += message[*ip - 1].m_lines;
                    312:                if (nlines > atoi(cp)) {
                    313:                        obuf = popen(MORE, "w");
                    314:                        if (obuf == NULL) {
                    315:                                perror(MORE);
                    316:                                obuf = stdout;
                    317:                        }
                    318:                        else {
                    319:                                pipef = obuf;
                    320:                                sigset(SIGPIPE, brokpipe);
                    321:                        }
                    322:                }
                    323:        }
                    324:        for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
                    325:                mesg = *ip;
                    326:                touch(mesg);
                    327:                mp = &message[mesg-1];
                    328:                dot = mp;
                    329:                print(mp, obuf, doign);
                    330:        }
                    331:        if (obuf != stdout) {
                    332:                pipef = NULL;
                    333:                pclose(obuf);
                    334:        }
                    335:        sigset(SIGPIPE, SIG_DFL);
                    336:        return(0);
                    337: }
                    338: 
                    339: /*
                    340:  * Respond to a broken pipe signal --
                    341:  * probably caused by using quitting more.
                    342:  */
                    343: 
                    344: brokpipe()
                    345: {
                    346: # ifndef VMUNIX
                    347:        signal(SIGPIPE, brokpipe);
                    348: # endif
                    349:        longjmp(pipestop, 1);
                    350: }
                    351: 
                    352: /*
                    353:  * Print the indicated message on standard output.
                    354:  */
                    355: 
                    356: print(mp, obuf, doign)
                    357:        register struct message *mp;
                    358:        FILE *obuf;
                    359: {
                    360: 
                    361:        if (value("quiet") == NOSTR)
                    362:                fprintf(obuf, "Message %2d:\n", mp - &message[0] + 1);
                    363:        touch(mp - &message[0] + 1);
                    364:        send(mp, obuf, doign);
                    365: }
                    366: 
                    367: /*
                    368:  * Print the top so many lines of each desired message.
                    369:  * The number of lines is taken from the variable "toplines"
                    370:  * and defaults to 5.
                    371:  */
                    372: 
                    373: top(msgvec)
                    374:        int *msgvec;
                    375: {
                    376:        register int *ip;
                    377:        register struct message *mp;
                    378:        register int mesg;
                    379:        int c, topl, lines, lineb;
                    380:        char *valtop, linebuf[LINESIZE];
                    381:        FILE *ibuf;
                    382: 
                    383:        topl = 5;
                    384:        valtop = value("toplines");
                    385:        if (valtop != NOSTR) {
                    386:                topl = atoi(valtop);
                    387:                if (topl < 0 || topl > 10000)
                    388:                        topl = 5;
                    389:        }
                    390:        lineb = 1;
                    391:        for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
                    392:                mesg = *ip;
                    393:                touch(mesg);
                    394:                mp = &message[mesg-1];
                    395:                dot = mp;
                    396:                if (value("quiet") == NOSTR)
                    397:                        printf("Message %2d:\n", mesg);
                    398:                ibuf = setinput(mp);
                    399:                c = mp->m_lines;
                    400:                if (!lineb)
                    401:                        printf("\n");
                    402:                for (lines = 0; lines < c && lines <= topl; lines++) {
                    403:                        if (readline(ibuf, linebuf) <= 0)
                    404:                                break;
                    405:                        puts(linebuf);
                    406:                        lineb = blankline(linebuf);
                    407:                }
                    408:        }
                    409:        return(0);
                    410: }
                    411: 
                    412: /*
                    413:  * Touch all the given messages so that they will
                    414:  * get mboxed.
                    415:  */
                    416: 
                    417: stouch(msgvec)
                    418:        int msgvec[];
                    419: {
                    420:        register int *ip;
                    421: 
                    422:        for (ip = msgvec; *ip != 0; ip++) {
                    423:                dot = &message[*ip-1];
                    424:                dot->m_flag |= MTOUCH;
                    425:                dot->m_flag &= ~MPRESERVE;
                    426:        }
                    427:        return(0);
                    428: }
                    429: 
                    430: /*
                    431:  * Make sure all passed messages get mboxed.
                    432:  */
                    433: 
                    434: mboxit(msgvec)
                    435:        int msgvec[];
                    436: {
                    437:        register int *ip;
                    438: 
                    439:        for (ip = msgvec; *ip != 0; ip++) {
                    440:                dot = &message[*ip-1];
                    441:                dot->m_flag |= MTOUCH|MBOX;
                    442:                dot->m_flag &= ~MPRESERVE;
                    443:        }
                    444:        return(0);
                    445: }
                    446: 
                    447: /*
                    448:  * List the folders the user currently has.
                    449:  */
                    450: folders()
                    451: {
                    452:        char dirname[BUFSIZ], cmd[BUFSIZ];
                    453:        int pid, s, e;
                    454: 
                    455:        if (getfold(dirname) < 0) {
                    456:                printf("No value set for \"folder\"\n");
                    457:                return(-1);
                    458:        }
                    459:        switch ((pid = fork())) {
                    460:        case 0:
                    461:                sigchild();
                    462:                execlp("ls", "ls", dirname, 0);
                    463:                clrbuf(stdout);
                    464:                exit(1);
                    465: 
                    466:        case -1:
                    467:                perror("fork");
                    468:                return(-1);
                    469: 
                    470:        default:
                    471:                while ((e = wait(&s)) != -1 && e != pid)
                    472:                        ;
                    473:        }
                    474:        return(0);
                    475: }

unix.superglobalmegacorp.com

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