|
|
1.1 ! root 1: #ident "@(#)cmd1.c 1.5 'attmail mail(1) command'" ! 2: #ident "@(#)mailx:cmd1.c 1.7.1.1" ! 3: /* Copyright (c) 1984 AT&T */ ! 4: /* All Rights Reserved */ ! 5: ! 6: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */ ! 7: /* The copyright notice above does not evidence any */ ! 8: /* actual or intended publication of such source code. */ ! 9: ! 10: #ident "@(#)mailx:cmd1.c 1.7" ! 11: ! 12: #include "rcv.h" ! 13: ! 14: /* ! 15: * mailx -- a modified version of a University of California at Berkeley ! 16: * mail program ! 17: * ! 18: * User commands. ! 19: */ ! 20: ! 21: static void brokpipe(); ! 22: static char *dispname(); ! 23: static void print(); ! 24: static int screensize(); ! 25: static int type1(); ! 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 curscreen = 0, oldscreensize = 0; ! 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: curscreen = (n-1)/size; ! 45: if (curscreen < 0) ! 46: curscreen = 0; ! 47: mp = &message[curscreen * 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: if (Hflag) ! 57: mp = message; ! 58: for (; mp < &message[msgCount]; mp++) { ! 59: mesg++; ! 60: if (mp->m_flag & MDELETED) ! 61: continue; ! 62: if (flag++ >= size && !Hflag) ! 63: break; ! 64: printhead(mesg); ! 65: sreset(); ! 66: } ! 67: if (flag == 0) { ! 68: printf("No more mail.\n"); ! 69: return(1); ! 70: } ! 71: return(0); ! 72: } ! 73: ! 74: /* ! 75: * Scroll to the next/previous screen ! 76: */ ! 77: ! 78: scroll(arg) ! 79: char arg[]; ! 80: { ! 81: register int s, size; ! 82: int cur[1]; ! 83: ! 84: cur[0] = 0; ! 85: size = screensize(); ! 86: s = curscreen; ! 87: switch (*arg) { ! 88: case 0: ! 89: case '+': ! 90: s++; ! 91: if (s * size > msgCount) { ! 92: printf("On last screenful of messages\n"); ! 93: return(0); ! 94: } ! 95: curscreen = s; ! 96: break; ! 97: ! 98: case '-': ! 99: if (--s < 0) { ! 100: printf("On first screenful of messages\n"); ! 101: return(0); ! 102: } ! 103: curscreen = s; ! 104: break; ! 105: ! 106: default: ! 107: printf("Unrecognized scrolling command \"%s\"\n", arg); ! 108: return(1); ! 109: } ! 110: return(headers(cur)); ! 111: } ! 112: ! 113: /* ! 114: * Compute what the screen size should be. ! 115: * We use the following algorithm: ! 116: * If user specifies with screen option, use that. ! 117: * If baud rate < 1200, use 5 ! 118: * If baud rate = 1200, use 10 ! 119: * If baud rate > 1200, use 20 ! 120: * the variable 'baud' has screensize encoded into it ! 121: */ ! 122: static int ! 123: screensize() ! 124: { ! 125: register char *cp; ! 126: register int newscreensize, tmp; ! 127: ! 128: cp = value("screen"); ! 129: newscreensize = ((cp != NOSTR) && ((tmp = atoi(cp)) > 0)) ? tmp : baud; ! 130: /* renormalize the value of curscreen */ ! 131: if (newscreensize != oldscreensize) { ! 132: curscreen = curscreen * oldscreensize / newscreensize; ! 133: oldscreensize = newscreensize; ! 134: } ! 135: return(newscreensize); ! 136: } ! 137: ! 138: /* ! 139: * Print out the headlines for each message ! 140: * in the passed message list. ! 141: */ ! 142: ! 143: from(msgvec) ! 144: int *msgvec; ! 145: { ! 146: register int *ip; ! 147: ! 148: for (ip = msgvec; *ip != NULL; ip++) { ! 149: printhead(*ip); ! 150: sreset(); ! 151: } ! 152: if (--ip >= msgvec) ! 153: dot = &message[*ip - 1]; ! 154: return(0); ! 155: } ! 156: ! 157: /* ! 158: * Print out the header of a specific message. ! 159: * This is a slight improvement to the standard one. ! 160: */ ! 161: ! 162: void ! 163: printhead(mesg) ! 164: { ! 165: struct message *mp; ! 166: FILE *ibuf; ! 167: char headline[LINESIZE], *subjline, dispc, curind; ! 168: char *fromline; ! 169: char pbuf[LINESIZE]; ! 170: char name[LINESIZE]; ! 171: struct headline hl; ! 172: register char *cp; ! 173: int showto; ! 174: ! 175: mp = &message[mesg-1]; ! 176: ibuf = setinput(mp); ! 177: readline(ibuf, headline); ! 178: if ((subjline = hfield("subject", mp, addone)) == NOSTR ! 179: && (subjline = hfield("subj", mp, addone)) == NOSTR ! 180: && (subjline = hfield("message-status", mp, addone)) == NOSTR) ! 181: subjline = ""; ! 182: ! 183: curind = (!Hflag && dot == mp) ? '>' : ' '; ! 184: dispc = ' '; ! 185: showto = 0; ! 186: if ((mp->m_flag & (MREAD|MNEW)) == (MREAD|MNEW)) ! 187: dispc = 'R'; ! 188: if ((mp->m_flag & (MREAD|MNEW)) == MREAD) ! 189: dispc = 'O'; ! 190: if ((mp->m_flag & (MREAD|MNEW)) == MNEW) ! 191: dispc = 'N'; ! 192: if ((mp->m_flag & (MREAD|MNEW)) == 0) ! 193: dispc = 'U'; ! 194: if (mp->m_flag & MSAVED) ! 195: dispc = 'S'; ! 196: if (mp->m_flag & MPRESERVE) ! 197: dispc = 'H'; ! 198: if (mp->m_flag & MBOX) ! 199: dispc = 'M'; ! 200: parse(headline, &hl, pbuf); ! 201: ! 202: /* ! 203: * Netnews interface? ! 204: */ ! 205: ! 206: if (newsflg) { ! 207: if ( (fromline=hfield("newsgroups",mp,addone)) == NOSTR /* A */ ! 208: && (fromline=hfield("article-id",mp,addone)) == NOSTR ) /* B */ ! 209: fromline = "<>"; ! 210: else ! 211: for(cp=fromline; *cp; cp++) { /* limit length */ ! 212: if( any(*cp, " ,\n")){ ! 213: *cp = '\0'; ! 214: break; ! 215: } ! 216: } ! 217: /* ! 218: * else regular. ! 219: */ ! 220: ! 221: } else { ! 222: fromline = nameof(mp); ! 223: if (value("showto") && samebody(myname, skin(fromline)) ! 224: && (cp = hfield("to", mp, addto))) { ! 225: showto = 1; ! 226: yankword(cp, fromline = name, docomma(cp)); ! 227: } ! 228: fromline = dispname(fromline); ! 229: } ! 230: printf("%c%c%3d ", curind, dispc, mesg); ! 231: if (showto) ! 232: printf("To %-15.15s ", fromline); ! 233: else ! 234: printf("%-18.18s ", fromline); ! 235: if (mp->m_text) { ! 236: printf("%16.16s %4ld/%-5ld %-.25s\n", ! 237: hl.l_date, mp->m_lines, mp->m_size, subjline); ! 238: } else { ! 239: printf("%16.16s binary/%-5ld %-.25s\n", hl.l_date, mp->m_size, subjline); ! 240: } ! 241: } ! 242: ! 243: /* ! 244: * Return the full name from an RFC-822 header line ! 245: * or the last two (or one) component of the address. ! 246: */ ! 247: ! 248: static char * ! 249: dispname(hdr) ! 250: char *hdr; ! 251: { ! 252: char *cp, *cp2; ! 253: ! 254: if (hdr == 0) ! 255: return 0; ! 256: if (cp = strchr(hdr, '<')) { ! 257: /* if name field is of the form ! 258: Any Name <addr-spec> ! 259: return Any Name. If it's ! 260: "Any Name" <addr-spec> ! 261: return Any Name (strip off quotes). ! 262: Otherwise, return addr-spec ! 263: */ ! 264: if (cp == hdr) { /* adb */ ! 265: if (cp = strrchr(hdr, '>')) /* adb */ ! 266: *cp = 0; /* adb */ ! 267: } /* adb */ ! 268: else if (*hdr == '"' && (cp = strrchr(++hdr, '"'))) { /* adb */ ! 269: *cp = 0; /* adb */ ! 270: } /* adb */ ! 271: else *cp = 0; /* adb */ ! 272: return hdr; ! 273: } else if (cp = strchr(hdr, '(')) { ! 274: hdr = ++cp; ! 275: if (cp = strchr(hdr, '+')) ! 276: *cp = 0; ! 277: if (cp = strrchr(hdr, ')')) ! 278: *cp = 0; ! 279: return hdr; ! 280: } ! 281: cp = skin(hdr); ! 282: if (cp2 = strrchr(cp, '!')) { ! 283: while (cp2 >= cp && *--cp2 != '!'); ! 284: cp = ++cp2; ! 285: } ! 286: return cp; ! 287: } ! 288: ! 289: /* ! 290: * Print out the value of dot. ! 291: */ ! 292: ! 293: pdot() ! 294: { ! 295: printf("%d\n", dot - &message[0] + 1); ! 296: return(0); ! 297: } ! 298: ! 299: /* ! 300: * Print out all the possible commands. ! 301: */ ! 302: ! 303: pcmdlist() ! 304: { ! 305: register struct cmd *cp; ! 306: register int cc; ! 307: ! 308: printf("Commands are:\n"); ! 309: for (cc = 0, cp = cmdtab; cp->c_name != NULL; cp++) { ! 310: cc += strlen(cp->c_name) + 2; ! 311: if (cc > 72) { ! 312: printf("\n"); ! 313: cc = strlen(cp->c_name) + 2; ! 314: } ! 315: if ((cp+1)->c_name != NOSTR) ! 316: printf("%s, ", cp->c_name); ! 317: else ! 318: printf("%s\n", cp->c_name); ! 319: } ! 320: return(0); ! 321: } ! 322: ! 323: /* ! 324: * Type out messages, honor ignored fields. ! 325: */ ! 326: type(msgvec) ! 327: int *msgvec; ! 328: { ! 329: ! 330: return(type1(msgvec, 1)); ! 331: } ! 332: ! 333: /* ! 334: * Type out messages, even printing ignored fields. ! 335: */ ! 336: Type(msgvec) ! 337: int *msgvec; ! 338: { ! 339: ! 340: return(type1(msgvec, 0)); ! 341: } ! 342: ! 343: /* ! 344: * Type out the messages requested. ! 345: */ ! 346: static jmp_buf pipestop; ! 347: ! 348: static int ! 349: type1(msgvec, doign) ! 350: int *msgvec; ! 351: { ! 352: register *ip; ! 353: register struct message *mp; ! 354: register int mesg; ! 355: register char *cp; ! 356: long nlines; ! 357: FILE *obuf; ! 358: void (*sigint)(), (*sigpipe)(); ! 359: int setsigs = 0; ! 360: ! 361: obuf = stdout; ! 362: if (setjmp(pipestop)) { ! 363: if (obuf != stdout) { ! 364: pipef = NULL; ! 365: npclose(obuf); ! 366: } ! 367: goto ret0; ! 368: } ! 369: if (intty && outtty && (cp = value("crt")) != NOSTR) { ! 370: for (ip = msgvec, nlines = 0; *ip && ip-msgvec < msgCount; ip++) ! 371: nlines += message[*ip - 1].m_lines; ! 372: if (nlines > atoi(cp)) { ! 373: char *pg = PG; ! 374: pg = (pg && *pg) ? pg : "cat"; ! 375: if ((obuf = npopen(pg, "w")) == NULL) { ! 376: perror(pg); ! 377: obuf = stdout; ! 378: } else { ! 379: pipef = obuf; ! 380: sigint = sigset(SIGINT, SIG_IGN); ! 381: sigpipe = sigset(SIGPIPE, brokpipe); ! 382: setsigs++; ! 383: } ! 384: } ! 385: } ! 386: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { ! 387: mesg = *ip; ! 388: touch(mesg); ! 389: mp = &message[mesg-1]; ! 390: dot = mp; ! 391: print(mp, obuf, doign); ! 392: } ! 393: if (obuf != stdout) { ! 394: pipef = NULL; ! 395: npclose(obuf); ! 396: } ! 397: ret0: ! 398: if (setsigs) { ! 399: sigset(SIGPIPE, sigpipe); ! 400: sigset(SIGINT, sigint); ! 401: } ! 402: return(0); ! 403: } ! 404: ! 405: /* ! 406: * Respond to a broken pipe signal -- ! 407: * probably caused by user quitting pg. ! 408: */ ! 409: static void ! 410: brokpipe() ! 411: { ! 412: sigrelse(SIGPIPE); ! 413: longjmp(pipestop, 1); ! 414: } ! 415: ! 416: /* ! 417: * Print the indicated message on standard output. ! 418: */ ! 419: ! 420: static void ! 421: print(mp, obuf, doign) ! 422: register struct message *mp; ! 423: FILE *obuf; ! 424: { ! 425: ! 426: if (!doign || !isign("message")) ! 427: fprintf(obuf, "Message %2d:\n", mp - &message[0] + 1); ! 428: touch(mp - &message[0] + 1); ! 429: /* ! 430: * in Area 10 world, no one has ordinary terminals. Everyone has terminal emulators. ! 431: * So don't worry about binary files. Print 'em anyway. ! 432: if (mp->m_text) { ! 433: send(mp, obuf, doign); ! 434: } else { ! 435: fprintf(obuf, "\n%s\n", binmsg); ! 436: } ! 437: */ ! 438: send(mp, obuf, doign); ! 439: } ! 440: ! 441: /* ! 442: * Print the top so many lines of each desired message. ! 443: * The number of lines is taken from the variable "toplines" ! 444: * and defaults to 5. ! 445: */ ! 446: ! 447: top(msgvec) ! 448: int *msgvec; ! 449: { ! 450: register int *ip; ! 451: register struct message *mp; ! 452: register int mesg; ! 453: int topl, lineb; ! 454: long c, lines; ! 455: char *valtop, linebuf[LINESIZE]; ! 456: FILE *ibuf; ! 457: ! 458: topl = 5; ! 459: valtop = value("toplines"); ! 460: if (valtop != NOSTR) { ! 461: topl = atoi(valtop); ! 462: if (topl < 0 || topl > 10000) ! 463: topl = 5; ! 464: } ! 465: lineb = 1; ! 466: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { ! 467: mesg = *ip; ! 468: touch(mesg); ! 469: mp = &message[mesg-1]; ! 470: dot = mp; ! 471: if (value("quiet") == NOSTR) ! 472: printf("Message %d:\n", mesg); ! 473: /* ! 474: * print even binary messages ! 475: * ! 476: if (mp->m_text) { ! 477: */ ! 478: ibuf = setinput(mp); ! 479: c = mp->m_lines; ! 480: if (!lineb) ! 481: printf("\n"); ! 482: for (lines = 0; lines < c && lines < topl; lines++) { ! 483: if (readline(ibuf, linebuf) <= 0) ! 484: break; ! 485: puts(linebuf); ! 486: lineb = blankline(linebuf); ! 487: } ! 488: /* ! 489: } else { ! 490: printf("\n%s\n", binmsg); ! 491: } ! 492: */ ! 493: } ! 494: return(0); ! 495: } ! 496: ! 497: /* ! 498: * Touch all the given messages so that they will ! 499: * get mboxed. ! 500: */ ! 501: ! 502: stouch(msgvec) ! 503: int msgvec[]; ! 504: { ! 505: register int *ip; ! 506: ! 507: for (ip = msgvec; *ip != 0; ip++) { ! 508: dot = &message[*ip-1]; ! 509: dot->m_flag |= MTOUCH; ! 510: dot->m_flag &= ~MPRESERVE; ! 511: } ! 512: return(0); ! 513: } ! 514: ! 515: /* ! 516: * Make sure all passed messages get mboxed. ! 517: */ ! 518: ! 519: mboxit(msgvec) ! 520: int msgvec[]; ! 521: { ! 522: register int *ip; ! 523: ! 524: for (ip = msgvec; *ip != 0; ip++) { ! 525: dot = &message[*ip-1]; ! 526: dot->m_flag |= MTOUCH|MBOX; ! 527: dot->m_flag &= ~MPRESERVE; ! 528: } ! 529: return(0); ! 530: } ! 531: ! 532: /* ! 533: * List the folders the user currently has. ! 534: */ ! 535: folders() ! 536: { ! 537: char dirname[BUFSIZ], cmd[BUFSIZ]; ! 538: ! 539: if (getfold(dirname) < 0) { ! 540: printf("No value set for \"folder\"\n"); ! 541: return(-1); ! 542: } ! 543: sprintf(cmd, "%s %s", LS, dirname); ! 544: return(system(cmd)); ! 545: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.