Annotation of researchv10no/lbin/mailx/cmd1.c, revision 1.1.1.1

1.1       root        1: #ident "@(#)cmd1.c     1.5 'attmail mail(1) command'"
                      2: #ident "@(#)mailx:cmd1.c       1.7.1.1"
                      3: /*     Copyright (c) 1984 AT&T */
                      4: /*       All Rights Reserved   */
                      5: 
                      6: /*     THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T     */
                      7: /*     The copyright notice above does not evidence any        */
                      8: /*     actual or intended publication of such source code.     */
                      9: 
                     10: #ident "@(#)mailx:cmd1.c       1.7"
                     11: 
                     12: #include "rcv.h"
                     13: 
                     14: /*
                     15:  * mailx -- a modified version of a University of California at Berkeley
                     16:  *     mail program
                     17:  *
                     18:  * User commands.
                     19:  */
                     20: 
                     21: static void    brokpipe();
                     22: static char    *dispname();
                     23: static void    print();
                     24: static int     screensize();
                     25: static int     type1();
                     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 curscreen = 0, oldscreensize = 0;
                     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:                curscreen = (n-1)/size;
                     45:        if (curscreen < 0)
                     46:                curscreen = 0;
                     47:        mp = &message[curscreen * 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:        if (Hflag)
                     57:                mp = message;
                     58:        for (; mp < &message[msgCount]; mp++) {
                     59:                mesg++;
                     60:                if (mp->m_flag & MDELETED)
                     61:                        continue;
                     62:                if (flag++ >= size && !Hflag)
                     63:                        break;
                     64:                printhead(mesg);
                     65:                sreset();
                     66:        }
                     67:        if (flag == 0) {
                     68:                printf("No more mail.\n");
                     69:                return(1);
                     70:        }
                     71:        return(0);
                     72: }
                     73: 
                     74: /*
                     75:  * Scroll to the next/previous screen
                     76:  */
                     77: 
                     78: scroll(arg)
                     79:        char arg[];
                     80: {
                     81:        register int s, size;
                     82:        int cur[1];
                     83: 
                     84:        cur[0] = 0;
                     85:        size = screensize();
                     86:        s = curscreen;
                     87:        switch (*arg) {
                     88:        case 0:
                     89:        case '+':
                     90:                s++;
                     91:                if (s * size > msgCount) {
                     92:                        printf("On last screenful of messages\n");
                     93:                        return(0);
                     94:                }
                     95:                curscreen = s;
                     96:                break;
                     97: 
                     98:        case '-':
                     99:                if (--s < 0) {
                    100:                        printf("On first screenful of messages\n");
                    101:                        return(0);
                    102:                }
                    103:                curscreen = s;
                    104:                break;
                    105: 
                    106:        default:
                    107:                printf("Unrecognized scrolling command \"%s\"\n", arg);
                    108:                return(1);
                    109:        }
                    110:        return(headers(cur));
                    111: }
                    112: 
                    113: /*
                    114:  * Compute what the screen size should be.
                    115:  * We use the following algorithm:
                    116:  *     If user specifies with screen option, use that.
                    117:  *     If baud rate < 1200, use  5
                    118:  *     If baud rate = 1200, use 10
                    119:  *     If baud rate > 1200, use 20
                    120:  *     the variable 'baud' has screensize encoded into it
                    121:  */
                    122: static int
                    123: screensize()
                    124: {
                    125:        register char *cp;
                    126:        register int newscreensize, tmp;
                    127: 
                    128:        cp = value("screen");
                    129:        newscreensize = ((cp != NOSTR) && ((tmp = atoi(cp)) > 0)) ? tmp : baud;
                    130:        /* renormalize the value of curscreen */
                    131:        if (newscreensize != oldscreensize) {
                    132:                curscreen = curscreen * oldscreensize / newscreensize;
                    133:                oldscreensize = newscreensize;
                    134:        }
                    135:        return(newscreensize);
                    136: }
                    137: 
                    138: /*
                    139:  * Print out the headlines for each message
                    140:  * in the passed message list.
                    141:  */
                    142: 
                    143: from(msgvec)
                    144:        int *msgvec;
                    145: {
                    146:        register int *ip;
                    147: 
                    148:        for (ip = msgvec; *ip != NULL; ip++) {
                    149:                printhead(*ip);
                    150:                sreset();
                    151:        }
                    152:        if (--ip >= msgvec)
                    153:                dot = &message[*ip - 1];
                    154:        return(0);
                    155: }
                    156: 
                    157: /*
                    158:  * Print out the header of a specific message.
                    159:  * This is a slight improvement to the standard one.
                    160:  */
                    161: 
                    162: void
                    163: printhead(mesg)
                    164: {
                    165:        struct message *mp;
                    166:        FILE *ibuf;
                    167:        char headline[LINESIZE], *subjline, dispc, curind;
                    168:        char *fromline;
                    169:        char pbuf[LINESIZE];
                    170:        char name[LINESIZE];
                    171:        struct headline hl;
                    172:        register char *cp;
                    173:        int showto;
                    174: 
                    175:        mp = &message[mesg-1];
                    176:        ibuf = setinput(mp);
                    177:        readline(ibuf, headline);
                    178:        if ((subjline = hfield("subject", mp, addone)) == NOSTR
                    179:         && (subjline = hfield("subj", mp, addone)) == NOSTR
                    180:         && (subjline = hfield("message-status", mp, addone)) == NOSTR)
                    181:                subjline = "";
                    182: 
                    183:        curind = (!Hflag && dot == mp) ? '>' : ' ';
                    184:        dispc = ' ';
                    185:        showto = 0;
                    186:        if ((mp->m_flag & (MREAD|MNEW)) == (MREAD|MNEW))
                    187:                dispc = 'R';
                    188:        if ((mp->m_flag & (MREAD|MNEW)) == MREAD)
                    189:                dispc = 'O';
                    190:        if ((mp->m_flag & (MREAD|MNEW)) == MNEW)
                    191:                dispc = 'N';
                    192:        if ((mp->m_flag & (MREAD|MNEW)) == 0)
                    193:                dispc = 'U';
                    194:        if (mp->m_flag & MSAVED)
                    195:                dispc = 'S';
                    196:        if (mp->m_flag & MPRESERVE)
                    197:                dispc = 'H';
                    198:        if (mp->m_flag & MBOX)
                    199:                dispc = 'M';
                    200:        parse(headline, &hl, pbuf);
                    201: 
                    202:        /*
                    203:         * Netnews interface?
                    204:         */
                    205: 
                    206:        if (newsflg) {
                    207:            if ( (fromline=hfield("newsgroups",mp,addone)) == NOSTR     /* A */
                    208:              && (fromline=hfield("article-id",mp,addone)) == NOSTR )   /* B */
                    209:                  fromline = "<>";
                    210:            else
                    211:                  for(cp=fromline; *cp; cp++) {         /* limit length */
                    212:                        if( any(*cp, " ,\n")){
                    213:                              *cp = '\0';
                    214:                              break;
                    215:                        }
                    216:                  }
                    217:        /*
                    218:         * else regular.
                    219:         */
                    220: 
                    221:        } else {
                    222:                fromline = nameof(mp);
                    223:                if (value("showto") && samebody(myname, skin(fromline))
                    224:                 && (cp = hfield("to", mp, addto))) {
                    225:                        showto = 1;
                    226:                        yankword(cp, fromline = name, docomma(cp));
                    227:                }
                    228:                fromline = dispname(fromline);
                    229:        }
                    230:        printf("%c%c%3d ", curind, dispc, mesg);
                    231:        if (showto)
                    232:                printf("To %-15.15s ", fromline);
                    233:        else
                    234:                printf("%-18.18s ", fromline);
                    235:        if (mp->m_text) {
                    236:                printf("%16.16s %4ld/%-5ld %-.25s\n",
                    237:                        hl.l_date, mp->m_lines, mp->m_size, subjline);
                    238:        } else {
                    239:                printf("%16.16s binary/%-5ld %-.25s\n", hl.l_date, mp->m_size, subjline);
                    240:        }
                    241: }
                    242: 
                    243: /*
                    244:  * Return the full name from an RFC-822 header line
                    245:  * or the last two (or one) component of the address.
                    246:  */
                    247: 
                    248: static char *
                    249: dispname(hdr)
                    250:        char *hdr;
                    251: {
                    252:        char *cp, *cp2;
                    253: 
                    254:        if (hdr == 0)
                    255:                return 0;
                    256:        if (cp = strchr(hdr, '<')) {
                    257:                /* if name field is of the form
                    258:                        Any Name <addr-spec>
                    259:                   return Any Name.  If it's
                    260:                        "Any Name" <addr-spec>
                    261:                   return Any Name (strip off quotes).
                    262:                   Otherwise, return addr-spec
                    263:                */
                    264:                if (cp == hdr) {                                        /* adb */
                    265:                        if (cp = strrchr(hdr, '>'))                     /* adb */
                    266:                                *cp = 0;                                /* adb */
                    267:                }                                                       /* adb */
                    268:                else if (*hdr == '"' && (cp = strrchr(++hdr, '"'))) {   /* adb */
                    269:                        *cp = 0;                                        /* adb */
                    270:                }                                                       /* adb */
                    271:                else *cp = 0;                                           /* adb */
                    272:                return hdr;
                    273:        } else if (cp = strchr(hdr, '(')) {
                    274:                hdr = ++cp;
                    275:                if (cp = strchr(hdr, '+'))
                    276:                        *cp = 0;
                    277:                if (cp = strrchr(hdr, ')'))
                    278:                        *cp = 0;
                    279:                return hdr;
                    280:        }
                    281:        cp = skin(hdr);
                    282:        if (cp2 = strrchr(cp, '!')) {
                    283:                while (cp2 >= cp && *--cp2 != '!');
                    284:                cp = ++cp2;
                    285:        }
                    286:        return cp;
                    287: }
                    288: 
                    289: /*
                    290:  * Print out the value of dot.
                    291:  */
                    292: 
                    293: pdot()
                    294: {
                    295:        printf("%d\n", dot - &message[0] + 1);
                    296:        return(0);
                    297: }
                    298: 
                    299: /*
                    300:  * Print out all the possible commands.
                    301:  */
                    302: 
                    303: pcmdlist()
                    304: {
                    305:        register struct cmd *cp;
                    306:        register int cc;
                    307: 
                    308:        printf("Commands are:\n");
                    309:        for (cc = 0, cp = cmdtab; cp->c_name != NULL; cp++) {
                    310:                cc += strlen(cp->c_name) + 2;
                    311:                if (cc > 72) {
                    312:                        printf("\n");
                    313:                        cc = strlen(cp->c_name) + 2;
                    314:                }
                    315:                if ((cp+1)->c_name != NOSTR)
                    316:                        printf("%s, ", cp->c_name);
                    317:                else
                    318:                        printf("%s\n", cp->c_name);
                    319:        }
                    320:        return(0);
                    321: }
                    322: 
                    323: /*
                    324:  * Type out messages, honor ignored fields.
                    325:  */
                    326: type(msgvec)
                    327:        int *msgvec;
                    328: {
                    329: 
                    330:        return(type1(msgvec, 1));
                    331: }
                    332: 
                    333: /*
                    334:  * Type out messages, even printing ignored fields.
                    335:  */
                    336: Type(msgvec)
                    337:        int *msgvec;
                    338: {
                    339: 
                    340:        return(type1(msgvec, 0));
                    341: }
                    342: 
                    343: /*
                    344:  * Type out the messages requested.
                    345:  */
                    346: static jmp_buf pipestop;
                    347: 
                    348: static int
                    349: type1(msgvec, doign)
                    350:        int *msgvec;
                    351: {
                    352:        register *ip;
                    353:        register struct message *mp;
                    354:        register int mesg;
                    355:        register char *cp;
                    356:        long nlines;
                    357:        FILE *obuf;
                    358:        void (*sigint)(), (*sigpipe)();
                    359:        int setsigs = 0;
                    360: 
                    361:        obuf = stdout;
                    362:        if (setjmp(pipestop)) {
                    363:                if (obuf != stdout) {
                    364:                        pipef = NULL;
                    365:                        npclose(obuf);
                    366:                }
                    367:                goto ret0;
                    368:        }
                    369:        if (intty && outtty && (cp = value("crt")) != NOSTR) {
                    370:                for (ip = msgvec, nlines = 0; *ip && ip-msgvec < msgCount; ip++)
                    371:                        nlines += message[*ip - 1].m_lines;
                    372:                if (nlines > atoi(cp)) {
                    373:                        char *pg = PG;
                    374:                        pg = (pg && *pg) ? pg : "cat";
                    375:                        if ((obuf = npopen(pg, "w")) == NULL) {
                    376:                                perror(pg);
                    377:                                obuf = stdout;
                    378:                        } else {
                    379:                                pipef = obuf;
                    380:                                sigint = sigset(SIGINT, SIG_IGN);
                    381:                                sigpipe = sigset(SIGPIPE, brokpipe);
                    382:                                setsigs++;
                    383:                        }
                    384:                }
                    385:        }
                    386:        for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
                    387:                mesg = *ip;
                    388:                touch(mesg);
                    389:                mp = &message[mesg-1];
                    390:                dot = mp;
                    391:                print(mp, obuf, doign);
                    392:        }
                    393:        if (obuf != stdout) {
                    394:                pipef = NULL;
                    395:                npclose(obuf);
                    396:        }
                    397: ret0:
                    398:        if (setsigs) {
                    399:                sigset(SIGPIPE, sigpipe);
                    400:                sigset(SIGINT, sigint);
                    401:        }
                    402:        return(0);
                    403: }
                    404: 
                    405: /*
                    406:  * Respond to a broken pipe signal --
                    407:  * probably caused by user quitting pg.
                    408:  */
                    409: static void
                    410: brokpipe()
                    411: {
                    412:        sigrelse(SIGPIPE);
                    413:        longjmp(pipestop, 1);
                    414: }
                    415: 
                    416: /*
                    417:  * Print the indicated message on standard output.
                    418:  */
                    419: 
                    420: static void
                    421: print(mp, obuf, doign)
                    422:        register struct message *mp;
                    423:        FILE *obuf;
                    424: {
                    425: 
                    426:        if (!doign || !isign("message"))
                    427:                fprintf(obuf, "Message %2d:\n", mp - &message[0] + 1);
                    428:        touch(mp - &message[0] + 1);
                    429: /*
                    430:  * in Area 10 world, no one has ordinary terminals.  Everyone has terminal emulators.
                    431:  * So don't worry about binary files.  Print 'em anyway.
                    432:        if (mp->m_text) {
                    433:                send(mp, obuf, doign);
                    434:        } else {
                    435:                fprintf(obuf, "\n%s\n", binmsg);
                    436:        }
                    437:  */
                    438:        send(mp, obuf, doign);
                    439: }
                    440: 
                    441: /*
                    442:  * Print the top so many lines of each desired message.
                    443:  * The number of lines is taken from the variable "toplines"
                    444:  * and defaults to 5.
                    445:  */
                    446: 
                    447: top(msgvec)
                    448:        int *msgvec;
                    449: {
                    450:        register int *ip;
                    451:        register struct message *mp;
                    452:        register int mesg;
                    453:        int topl, lineb;
                    454:        long c, lines;
                    455:        char *valtop, linebuf[LINESIZE];
                    456:        FILE *ibuf;
                    457: 
                    458:        topl = 5;
                    459:        valtop = value("toplines");
                    460:        if (valtop != NOSTR) {
                    461:                topl = atoi(valtop);
                    462:                if (topl < 0 || topl > 10000)
                    463:                        topl = 5;
                    464:        }
                    465:        lineb = 1;
                    466:        for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
                    467:                mesg = *ip;
                    468:                touch(mesg);
                    469:                mp = &message[mesg-1];
                    470:                dot = mp;
                    471:                if (value("quiet") == NOSTR)
                    472:                        printf("Message %d:\n", mesg);
                    473: /*
                    474:  * print even binary messages
                    475:  *
                    476:                if (mp->m_text) {
                    477: */
                    478:                        ibuf = setinput(mp);
                    479:                        c = mp->m_lines;
                    480:                        if (!lineb)
                    481:                                printf("\n");
                    482:                        for (lines = 0; lines < c && lines < topl; lines++) {
                    483:                                if (readline(ibuf, linebuf) <= 0)
                    484:                                        break;
                    485:                                puts(linebuf);
                    486:                                lineb = blankline(linebuf);
                    487:                        }
                    488: /*
                    489:                } else {
                    490:                        printf("\n%s\n", binmsg);
                    491:                }
                    492: */
                    493:        }
                    494:        return(0);
                    495: }
                    496: 
                    497: /*
                    498:  * Touch all the given messages so that they will
                    499:  * get mboxed.
                    500:  */
                    501: 
                    502: stouch(msgvec)
                    503:        int msgvec[];
                    504: {
                    505:        register int *ip;
                    506: 
                    507:        for (ip = msgvec; *ip != 0; ip++) {
                    508:                dot = &message[*ip-1];
                    509:                dot->m_flag |= MTOUCH;
                    510:                dot->m_flag &= ~MPRESERVE;
                    511:        }
                    512:        return(0);
                    513: }
                    514: 
                    515: /*
                    516:  * Make sure all passed messages get mboxed.
                    517:  */
                    518: 
                    519: mboxit(msgvec)
                    520:        int msgvec[];
                    521: {
                    522:        register int *ip;
                    523: 
                    524:        for (ip = msgvec; *ip != 0; ip++) {
                    525:                dot = &message[*ip-1];
                    526:                dot->m_flag |= MTOUCH|MBOX;
                    527:                dot->m_flag &= ~MPRESERVE;
                    528:        }
                    529:        return(0);
                    530: }
                    531: 
                    532: /*
                    533:  * List the folders the user currently has.
                    534:  */
                    535: folders()
                    536: {
                    537:        char dirname[BUFSIZ], cmd[BUFSIZ];
                    538: 
                    539:        if (getfold(dirname) < 0) {
                    540:                printf("No value set for \"folder\"\n");
                    541:                return(-1);
                    542:        }
                    543:        sprintf(cmd, "%s %s", LS, dirname);
                    544:        return(system(cmd));
                    545: }

unix.superglobalmegacorp.com

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