|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.