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

unix.superglobalmegacorp.com

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