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

Defined functions

More defined in line 289; used 3 times
Type defined in line 309; used 3 times
brokpipe defined in line 382; used 3 times
folders defined in line 488; used 2 times
from defined in line 173; used 2 times
headers defined in line 27; used 4 times
local defined in line 68; used 2 times
mboxit defined in line 472; used 2 times
more defined in line 280; used 3 times
pcmdlist defined in line 256; used 2 times
pdot defined in line 246; used 2 times
print defined in line 394; used 1 times
printhead defined in line 192; used 2 times
screensize defined in line 142; used 2 times
scroll defined in line 99; used 2 times
stouch defined in line 455; used 2 times
top defined in line 411; used 2 times
type defined in line 299; used 6 times
type1 defined in line 321; used 4 times

Defined variables

pipestop defined in line 319; used 2 times
sccsid defined in line 8; never used
screen defined in line 25; used 7 times
Last modified: 1985-09-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1173
Valid CSS Valid XHTML 1.0 Strict