# 2.11BSD#431 - /usr/src/ucb/Mail/cmd1.c

##### Functions

    More              X
    Type              X
    brokpipe          X
    folders           X
    from              X
    headers           X
    mboxit            X
    more              X
    pcmdlist          X
    pdot              X
    printhead         X
    screensize        X
    scroll            X
    stouch            X
    top               X
    type              X
    type1             X

##### Variables

    pipestop          X

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

#### Defined functions

More defined in line 252; used 3 times

- in /usr/src/ucb/Mail/cmdtab.c line 53, 77-78(2)

Type defined in line 272; used 3 times

- in /usr/src/ucb/Mail/cmdtab.c line 53, 62-63(2)

brokpipe defined in line 341; used 2 times

- in line 292, 313

folders defined in line 427; used 2 times

- in /usr/src/ucb/Mail/cmdtab.c line 53, 94

from defined in line 146; used 2 times

- in /usr/src/ucb/Mail/cmdtab.c line 48, 91

headers defined in line 53; used 4 times

- in line 125
- in /usr/src/ucb/Mail/cmdtab.c line 47, 97
- in /usr/src/ucb/Mail/lex.c line 554

mboxit defined in line 411; used 2 times

- in /usr/src/ucb/Mail/cmdtab.c line 52, 74

more defined in line 243; used 3 times

- in /usr/src/ucb/Mail/cmdtab.c line 53, 75-76(2)

pcmdlist defined in line 219; used 2 times

- in /usr/src/ucb/Mail/cmdtab.c line 48, 107

pdot defined in line 209; used 2 times

- in /usr/src/ucb/Mail/cmdtab.c line 47, 99

printhead defined in line 163; used 2 times

- in line 81, 152

screensize defined in line 131; used 2 times

- in line 60, 100

scroll defined in line 93; used 2 times

- in /usr/src/ucb/Mail/cmdtab.c line 51, 96

stouch defined in line 394; used 2 times

- in /usr/src/ucb/Mail/cmdtab.c line 50, 66

top defined in line 353; used 2 times

- in /usr/src/ucb/Mail/cmdtab.c line 50, 65

type defined in line 262; used 6 times

- in /usr/src/ucb/Mail/cmd2.c line 124, 290
- in /usr/src/ucb/Mail/cmdtab.c line 46, 60-61(2)
- in /usr/src/ucb/Mail/lex.c line 421

type1 defined in line 284; used 4 times

- in line 246, 256, 266, 276

#### Defined variables

pipestop defined in line 282; used 2 times

- in line 295, 344

sccsid defined in line 35; never used
screen defined in line 51; used 7 times

- in line 63-66(4), 101, 110, 118

Last modified: 1993-02-14 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1007 |