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