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

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

unix.superglobalmegacorp.com

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