[BACK]Return to cmd1.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mail

Annotation of src/usr.bin/mail/cmd1.c, Revision 1.1

1.1     ! deraadt     1: /*-
        !             2:  * Copyright (c) 1980, 1993
        !             3:  *     The Regents of the University of California.  All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms, with or without
        !             6:  * modification, are permitted provided that the following conditions
        !             7:  * are met:
        !             8:  * 1. Redistributions of source code must retain the above copyright
        !             9:  *    notice, this list of conditions and the following disclaimer.
        !            10:  * 2. Redistributions in binary form must reproduce the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer in the
        !            12:  *    documentation and/or other materials provided with the distribution.
        !            13:  * 3. All advertising materials mentioning features or use of this software
        !            14:  *    must display the following acknowledgement:
        !            15:  *     This product includes software developed by the University of
        !            16:  *     California, Berkeley and its contributors.
        !            17:  * 4. Neither the name of the University nor the names of its contributors
        !            18:  *    may be used to endorse or promote products derived from this software
        !            19:  *    without specific prior written permission.
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            31:  * SUCH DAMAGE.
        !            32:  */
        !            33:
        !            34: #ifndef lint
        !            35: static char sccsid[] = "from: @(#)cmd1.c       8.1 (Berkeley) 6/6/93";
        !            36: static char rcsid[] = "$Id: cmd1.c,v 1.3 1994/06/29 05:09:07 deraadt Exp $";
        !            37: #endif /* not lint */
        !            38:
        !            39: #include "rcv.h"
        !            40: #include "extern.h"
        !            41:
        !            42: /*
        !            43:  * Mail -- a mail program
        !            44:  *
        !            45:  * User commands.
        !            46:  */
        !            47:
        !            48: /*
        !            49:  * Print the current active headings.
        !            50:  * Don't change dot if invoker didn't give an argument.
        !            51:  */
        !            52:
        !            53: static int screen;
        !            54:
        !            55: int
        !            56: headers(msgvec)
        !            57:        int *msgvec;
        !            58: {
        !            59:        register int n, mesg, flag;
        !            60:        register struct message *mp;
        !            61:        int size;
        !            62:
        !            63:        size = screensize();
        !            64:        n = msgvec[0];
        !            65:        if (n != 0)
        !            66:                screen = (n-1)/size;
        !            67:        if (screen < 0)
        !            68:                screen = 0;
        !            69:        mp = &message[screen * size];
        !            70:        if (mp >= &message[msgCount])
        !            71:                mp = &message[msgCount - size];
        !            72:        if (mp < &message[0])
        !            73:                mp = &message[0];
        !            74:        flag = 0;
        !            75:        mesg = mp - &message[0];
        !            76:        if (dot != &message[n-1])
        !            77:                dot = mp;
        !            78:        for (; mp < &message[msgCount]; mp++) {
        !            79:                mesg++;
        !            80:                if (mp->m_flag & MDELETED)
        !            81:                        continue;
        !            82:                if (flag++ >= size)
        !            83:                        break;
        !            84:                printhead(mesg);
        !            85:        }
        !            86:        if (flag == 0) {
        !            87:                printf("No more mail.\n");
        !            88:                return(1);
        !            89:        }
        !            90:        return(0);
        !            91: }
        !            92:
        !            93: /*
        !            94:  * Scroll to the next/previous screen
        !            95:  */
        !            96: int
        !            97: scroll(arg)
        !            98:        char arg[];
        !            99: {
        !           100:        register int s, size;
        !           101:        int cur[1];
        !           102:
        !           103:        cur[0] = 0;
        !           104:        size = screensize();
        !           105:        s = screen;
        !           106:        switch (*arg) {
        !           107:        case 0:
        !           108:        case '+':
        !           109:                s++;
        !           110:                if (s * size > msgCount) {
        !           111:                        printf("On last screenful of messages\n");
        !           112:                        return(0);
        !           113:                }
        !           114:                screen = s;
        !           115:                break;
        !           116:
        !           117:        case '-':
        !           118:                if (--s < 0) {
        !           119:                        printf("On first screenful of messages\n");
        !           120:                        return(0);
        !           121:                }
        !           122:                screen = s;
        !           123:                break;
        !           124:
        !           125:        default:
        !           126:                printf("Unrecognized scrolling command \"%s\"\n", arg);
        !           127:                return(1);
        !           128:        }
        !           129:        return(headers(cur));
        !           130: }
        !           131:
        !           132: /*
        !           133:  * Compute screen size.
        !           134:  */
        !           135: int
        !           136: screensize()
        !           137: {
        !           138:        int s;
        !           139:        char *cp;
        !           140:
        !           141:        if ((cp = value("screen")) != NOSTR && (s = atoi(cp)) > 0)
        !           142:                return s;
        !           143:        return screenheight - 4;
        !           144: }
        !           145:
        !           146: /*
        !           147:  * Print out the headlines for each message
        !           148:  * in the passed message list.
        !           149:  */
        !           150: int
        !           151: from(msgvec)
        !           152:        int *msgvec;
        !           153: {
        !           154:        register int *ip;
        !           155:
        !           156:        for (ip = msgvec; *ip != NULL; ip++)
        !           157:                printhead(*ip);
        !           158:        if (--ip >= msgvec)
        !           159:                dot = &message[*ip - 1];
        !           160:        return(0);
        !           161: }
        !           162:
        !           163: /*
        !           164:  * Print out the header of a specific message.
        !           165:  * This is a slight improvement to the standard one.
        !           166:  */
        !           167: void
        !           168: printhead(mesg)
        !           169:        int mesg;
        !           170: {
        !           171:        struct message *mp;
        !           172:        char headline[LINESIZE], wcount[LINESIZE], *subjline, dispc, curind;
        !           173:        char pbuf[BUFSIZ];
        !           174:        struct headline hl;
        !           175:        int subjlen;
        !           176:        char *name;
        !           177:
        !           178:        mp = &message[mesg-1];
        !           179:        (void) readline(setinput(mp), headline, LINESIZE);
        !           180:        if ((subjline = hfield("subject", mp)) == NOSTR)
        !           181:                subjline = hfield("subj", mp);
        !           182:        /*
        !           183:         * Bletch!
        !           184:         */
        !           185:        curind = dot == mp ? '>' : ' ';
        !           186:        dispc = ' ';
        !           187:        if (mp->m_flag & MSAVED)
        !           188:                dispc = '*';
        !           189:        if (mp->m_flag & MPRESERVE)
        !           190:                dispc = 'P';
        !           191:        if ((mp->m_flag & (MREAD|MNEW)) == MNEW)
        !           192:                dispc = 'N';
        !           193:        if ((mp->m_flag & (MREAD|MNEW)) == 0)
        !           194:                dispc = 'U';
        !           195:        if (mp->m_flag & MBOX)
        !           196:                dispc = 'M';
        !           197:        parse(headline, &hl, pbuf);
        !           198:        sprintf(wcount, "%3d/%-5ld", mp->m_lines, mp->m_size);
        !           199:        subjlen = screenwidth - 50 - strlen(wcount);
        !           200:        name = value("show-rcpt") != NOSTR ?
        !           201:                skin(hfield("to", mp)) : nameof(mp, 0);
        !           202:        if (subjline == NOSTR || subjlen < 0)           /* pretty pathetic */
        !           203:                printf("%c%c%3d %-20.20s  %16.16s %s\n",
        !           204:                        curind, dispc, mesg, name, hl.l_date, wcount);
        !           205:        else
        !           206:                printf("%c%c%3d %-20.20s  %16.16s %s \"%.*s\"\n",
        !           207:                        curind, dispc, mesg, name, hl.l_date, wcount,
        !           208:                        subjlen, subjline);
        !           209: }
        !           210:
        !           211: /*
        !           212:  * Print out the value of dot.
        !           213:  */
        !           214: int
        !           215: pdot()
        !           216: {
        !           217:        printf("%d\n", dot - &message[0] + 1);
        !           218:        return(0);
        !           219: }
        !           220:
        !           221: /*
        !           222:  * Print out all the possible commands.
        !           223:  */
        !           224: int
        !           225: pcmdlist()
        !           226: {
        !           227:        register struct cmd *cp;
        !           228:        register int cc;
        !           229:        extern struct cmd cmdtab[];
        !           230:
        !           231:        printf("Commands are:\n");
        !           232:        for (cc = 0, cp = cmdtab; cp->c_name != NULL; cp++) {
        !           233:                cc += strlen(cp->c_name) + 2;
        !           234:                if (cc > 72) {
        !           235:                        printf("\n");
        !           236:                        cc = strlen(cp->c_name) + 2;
        !           237:                }
        !           238:                if ((cp+1)->c_name != NOSTR)
        !           239:                        printf("%s, ", cp->c_name);
        !           240:                else
        !           241:                        printf("%s\n", cp->c_name);
        !           242:        }
        !           243:        return(0);
        !           244: }
        !           245:
        !           246: /*
        !           247:  * Paginate messages, honor ignored fields.
        !           248:  */
        !           249: int
        !           250: more(msgvec)
        !           251:        int *msgvec;
        !           252: {
        !           253:        return (type1(msgvec, 1, 1));
        !           254: }
        !           255:
        !           256: /*
        !           257:  * Paginate messages, even printing ignored fields.
        !           258:  */
        !           259: int
        !           260: More(msgvec)
        !           261:        int *msgvec;
        !           262: {
        !           263:
        !           264:        return (type1(msgvec, 0, 1));
        !           265: }
        !           266:
        !           267: /*
        !           268:  * Type out messages, honor ignored fields.
        !           269:  */
        !           270: int
        !           271: type(msgvec)
        !           272:        int *msgvec;
        !           273: {
        !           274:
        !           275:        return(type1(msgvec, 1, 0));
        !           276: }
        !           277:
        !           278: /*
        !           279:  * Type out messages, even printing ignored fields.
        !           280:  */
        !           281: int
        !           282: Type(msgvec)
        !           283:        int *msgvec;
        !           284: {
        !           285:
        !           286:        return(type1(msgvec, 0, 0));
        !           287: }
        !           288:
        !           289: /*
        !           290:  * Type out the messages requested.
        !           291:  */
        !           292: jmp_buf        pipestop;
        !           293: int
        !           294: type1(msgvec, doign, page)
        !           295:        int *msgvec;
        !           296:        int doign, page;
        !           297: {
        !           298:        register *ip;
        !           299:        register struct message *mp;
        !           300:        register char *cp;
        !           301:        int nlines;
        !           302:        FILE *obuf;
        !           303:
        !           304:        obuf = stdout;
        !           305:        if (setjmp(pipestop))
        !           306:                goto close_pipe;
        !           307:        if (value("interactive") != NOSTR &&
        !           308:            (page || (cp = value("crt")) != NOSTR)) {
        !           309:                nlines = 0;
        !           310:                if (!page) {
        !           311:                        for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++)
        !           312:                                nlines += message[*ip - 1].m_lines;
        !           313:                }
        !           314:                if (page || nlines > (*cp ? atoi(cp) : realscreenheight)) {
        !           315:                        cp = value("PAGER");
        !           316:                        if (cp == NULL || *cp == '\0')
        !           317:                                cp = _PATH_MORE;
        !           318:                        obuf = Popen(cp, "w");
        !           319:                        if (obuf == NULL) {
        !           320:                                perror(cp);
        !           321:                                obuf = stdout;
        !           322:                        } else
        !           323:                                signal(SIGPIPE, brokpipe);
        !           324:                }
        !           325:        }
        !           326:        for (ip = msgvec; *ip && ip - msgvec < msgCount; ip++) {
        !           327:                mp = &message[*ip - 1];
        !           328:                touch(mp);
        !           329:                dot = mp;
        !           330:                if (value("quiet") == NOSTR)
        !           331:                        fprintf(obuf, "Message %d:\n", *ip);
        !           332:                (void) send(mp, obuf, doign ? ignore : 0, NOSTR);
        !           333:        }
        !           334: close_pipe:
        !           335:        if (obuf != stdout) {
        !           336:                /*
        !           337:                 * Ignore SIGPIPE so it can't cause a duplicate close.
        !           338:                 */
        !           339:                signal(SIGPIPE, SIG_IGN);
        !           340:                Pclose(obuf);
        !           341:                signal(SIGPIPE, SIG_DFL);
        !           342:        }
        !           343:        return(0);
        !           344: }
        !           345:
        !           346: /*
        !           347:  * Respond to a broken pipe signal --
        !           348:  * probably caused by quitting more.
        !           349:  */
        !           350: void
        !           351: brokpipe(signo)
        !           352:        int signo;
        !           353: {
        !           354:        longjmp(pipestop, 1);
        !           355: }
        !           356:
        !           357: /*
        !           358:  * Print the top so many lines of each desired message.
        !           359:  * The number of lines is taken from the variable "toplines"
        !           360:  * and defaults to 5.
        !           361:  */
        !           362: int
        !           363: top(msgvec)
        !           364:        int *msgvec;
        !           365: {
        !           366:        register int *ip;
        !           367:        register struct message *mp;
        !           368:        int c, topl, lines, lineb;
        !           369:        char *valtop, linebuf[LINESIZE];
        !           370:        FILE *ibuf;
        !           371:
        !           372:        topl = 5;
        !           373:        valtop = value("toplines");
        !           374:        if (valtop != NOSTR) {
        !           375:                topl = atoi(valtop);
        !           376:                if (topl < 0 || topl > 10000)
        !           377:                        topl = 5;
        !           378:        }
        !           379:        lineb = 1;
        !           380:        for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
        !           381:                mp = &message[*ip - 1];
        !           382:                touch(mp);
        !           383:                dot = mp;
        !           384:                if (value("quiet") == NOSTR)
        !           385:                        printf("Message %d:\n", *ip);
        !           386:                ibuf = setinput(mp);
        !           387:                c = mp->m_lines;
        !           388:                if (!lineb)
        !           389:                        printf("\n");
        !           390:                for (lines = 0; lines < c && lines <= topl; lines++) {
        !           391:                        if (readline(ibuf, linebuf, LINESIZE) < 0)
        !           392:                                break;
        !           393:                        puts(linebuf);
        !           394:                        lineb = blankline(linebuf);
        !           395:                }
        !           396:        }
        !           397:        return(0);
        !           398: }
        !           399:
        !           400: /*
        !           401:  * Touch all the given messages so that they will
        !           402:  * get mboxed.
        !           403:  */
        !           404: int
        !           405: stouch(msgvec)
        !           406:        int msgvec[];
        !           407: {
        !           408:        register int *ip;
        !           409:
        !           410:        for (ip = msgvec; *ip != 0; ip++) {
        !           411:                dot = &message[*ip-1];
        !           412:                dot->m_flag |= MTOUCH;
        !           413:                dot->m_flag &= ~MPRESERVE;
        !           414:        }
        !           415:        return(0);
        !           416: }
        !           417:
        !           418: /*
        !           419:  * Make sure all passed messages get mboxed.
        !           420:  */
        !           421: int
        !           422: mboxit(msgvec)
        !           423:        int msgvec[];
        !           424: {
        !           425:        register int *ip;
        !           426:
        !           427:        for (ip = msgvec; *ip != 0; ip++) {
        !           428:                dot = &message[*ip-1];
        !           429:                dot->m_flag |= MTOUCH|MBOX;
        !           430:                dot->m_flag &= ~MPRESERVE;
        !           431:        }
        !           432:        return(0);
        !           433: }
        !           434:
        !           435: /*
        !           436:  * List the folders the user currently has.
        !           437:  */
        !           438: int
        !           439: folders()
        !           440: {
        !           441:        char dirname[BUFSIZ];
        !           442:        char *cmd;
        !           443:
        !           444:        if (getfold(dirname) < 0) {
        !           445:                printf("No value set for \"folder\"\n");
        !           446:                return 1;
        !           447:        }
        !           448:        if ((cmd = value("LISTER")) == NOSTR)
        !           449:                cmd = "ls";
        !           450:        (void) run_command(cmd, 0, -1, -1, dirname, NOSTR, NOSTR);
        !           451:        return 0;
        !           452: }