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
Type defined in line 272; used 3 times
brokpipe defined in line 341; used 2 times
folders defined in line 427; used 2 times
from defined in line 146; used 2 times
headers defined in line 53; used 4 times
mboxit defined in line 411; used 2 times
more defined in line 243; used 3 times
pcmdlist defined in line 219; used 2 times
pdot defined in line 209; used 2 times
printhead defined in line 163; used 2 times
screensize defined in line 131; used 2 times
scroll defined in line 93; used 2 times
stouch defined in line 394; used 2 times
top defined in line 353; used 2 times
type defined in line 262; used 6 times
type1 defined in line 284; used 4 times

Defined variables

pipestop defined in line 282; used 2 times
sccsid defined in line 35; never used
screen defined in line 51; used 7 times
Last modified: 1993-02-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3227
Valid CSS Valid XHTML 1.0 Strict