|
|
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 = "@(#)collect.c 5.2 (Berkeley) 6/21/85"; ! 9: #endif not lint ! 10: ! 11: /* ! 12: * Mail -- a mail program ! 13: * ! 14: * Collect input from standard input, handling ! 15: * ~ escapes. ! 16: */ ! 17: ! 18: #include "rcv.h" ! 19: #include <sys/stat.h> ! 20: ! 21: /* ! 22: * Read a message from standard output and return a read file to it ! 23: * or NULL on error. ! 24: */ ! 25: ! 26: /* ! 27: * The following hokiness with global variables is so that on ! 28: * receipt of an interrupt signal, the partial message can be salted ! 29: * away on dead.letter. The output file must be available to flush, ! 30: * and the input to read. Several open files could be saved all through ! 31: * Mail if stdio allowed simultaneous read/write access. ! 32: */ ! 33: ! 34: static int (*savesig)(); /* Previous SIGINT value */ ! 35: static int (*savehup)(); /* Previous SIGHUP value */ ! 36: # ifdef VMUNIX ! 37: static int (*savecont)(); /* Previous SIGCONT value */ ! 38: # endif VMUNIX ! 39: static FILE *newi; /* File for saving away */ ! 40: static FILE *newo; /* Output side of same */ ! 41: static int hf; /* Ignore interrups */ ! 42: static int hadintr; /* Have seen one SIGINT so far */ ! 43: ! 44: static jmp_buf coljmp; /* To get back to work */ ! 45: ! 46: FILE * ! 47: collect(hp) ! 48: struct header *hp; ! 49: { ! 50: FILE *ibuf, *fbuf, *obuf; ! 51: int lc, cc, escape, collrub(), intack(), collhup, collcont(), eof; ! 52: register int c, t; ! 53: char linebuf[LINESIZE], *cp; ! 54: extern char tempMail[]; ! 55: int notify(); ! 56: extern collintsig(), collhupsig(); ! 57: char getsub; ! 58: ! 59: noreset++; ! 60: ibuf = obuf = NULL; ! 61: if (value("ignore") != NOSTR) ! 62: hf = 1; ! 63: else ! 64: hf = 0; ! 65: hadintr = 0; ! 66: # ifdef VMUNIX ! 67: if ((savesig = sigset(SIGINT, SIG_IGN)) != SIG_IGN) ! 68: sigset(SIGINT, hf ? intack : collrub), sigblock(sigmask(SIGINT)); ! 69: if ((savehup = sigset(SIGHUP, SIG_IGN)) != SIG_IGN) ! 70: sigset(SIGHUP, collrub), sigblock(sigmask(SIGHUP)); ! 71: savecont = sigset(SIGCONT, collcont); ! 72: # else VMUNIX ! 73: savesig = signal(SIGINT, SIG_IGN); ! 74: savehup = signal(SIGHUP, SIG_IGN); ! 75: # endif VMUNIX ! 76: newi = NULL; ! 77: newo = NULL; ! 78: if ((obuf = fopen(tempMail, "w")) == NULL) { ! 79: perror(tempMail); ! 80: goto err; ! 81: } ! 82: newo = obuf; ! 83: if ((ibuf = fopen(tempMail, "r")) == NULL) { ! 84: perror(tempMail); ! 85: newo = NULL; ! 86: fclose(obuf); ! 87: goto err; ! 88: } ! 89: newi = ibuf; ! 90: remove(tempMail); ! 91: ! 92: /* ! 93: * If we are going to prompt for a subject, ! 94: * refrain from printing a newline after ! 95: * the headers (since some people mind). ! 96: */ ! 97: ! 98: t = GTO|GSUBJECT|GCC|GNL; ! 99: getsub = 0; ! 100: if (intty && sflag == NOSTR && hp->h_subject == NOSTR && value("ask")) ! 101: t &= ~GNL, getsub++; ! 102: if (hp->h_seq != 0) { ! 103: puthead(hp, stdout, t); ! 104: fflush(stdout); ! 105: } ! 106: escape = ESCAPE; ! 107: if ((cp = value("escape")) != NOSTR) ! 108: escape = *cp; ! 109: eof = 0; ! 110: for (;;) { ! 111: int omask = sigblock(0) &~ (sigmask(SIGINT)|sigmask(SIGHUP)); ! 112: ! 113: setjmp(coljmp); ! 114: # ifdef VMUNIX ! 115: sigsetmask(omask); ! 116: # else VMUNIX ! 117: if (savesig != SIG_IGN) ! 118: signal(SIGINT, hf ? intack : collintsig); ! 119: if (savehup != SIG_IGN) ! 120: signal(SIGHUP, collhupsig); ! 121: # endif VMUNIX ! 122: fflush(stdout); ! 123: if (getsub) { ! 124: grabh(hp, GSUBJECT); ! 125: getsub = 0; ! 126: continue; ! 127: } ! 128: if (readline(stdin, linebuf) <= 0) { ! 129: if (intty && value("ignoreeof") != NOSTR) { ! 130: if (++eof > 35) ! 131: break; ! 132: printf("Use \".\" to terminate letter\n", ! 133: escape); ! 134: continue; ! 135: } ! 136: break; ! 137: } ! 138: eof = 0; ! 139: hadintr = 0; ! 140: if (intty && equal(".", linebuf) && ! 141: (value("dot") != NOSTR || value("ignoreeof") != NOSTR)) ! 142: break; ! 143: if (linebuf[0] != escape || rflag != NOSTR) { ! 144: if ((t = putline(obuf, linebuf)) < 0) ! 145: goto err; ! 146: continue; ! 147: } ! 148: c = linebuf[1]; ! 149: switch (c) { ! 150: default: ! 151: /* ! 152: * On double escape, just send the single one. ! 153: * Otherwise, it's an error. ! 154: */ ! 155: ! 156: if (c == escape) { ! 157: if (putline(obuf, &linebuf[1]) < 0) ! 158: goto err; ! 159: else ! 160: break; ! 161: } ! 162: printf("Unknown tilde escape.\n"); ! 163: break; ! 164: ! 165: case 'C': ! 166: /* ! 167: * Dump core. ! 168: */ ! 169: ! 170: core(); ! 171: break; ! 172: ! 173: case '!': ! 174: /* ! 175: * Shell escape, send the balance of the ! 176: * line to sh -c. ! 177: */ ! 178: ! 179: shell(&linebuf[2]); ! 180: break; ! 181: ! 182: case ':': ! 183: case '_': ! 184: /* ! 185: * Escape to command mode, but be nice! ! 186: */ ! 187: ! 188: execute(&linebuf[2], 1); ! 189: printf("(continue)\n"); ! 190: break; ! 191: ! 192: case '.': ! 193: /* ! 194: * Simulate end of file on input. ! 195: */ ! 196: goto eofl; ! 197: ! 198: case 'q': ! 199: case 'Q': ! 200: /* ! 201: * Force a quit of sending mail. ! 202: * Act like an interrupt happened. ! 203: */ ! 204: ! 205: hadintr++; ! 206: collrub(SIGINT); ! 207: exit(1); ! 208: ! 209: case 'h': ! 210: /* ! 211: * Grab a bunch of headers. ! 212: */ ! 213: if (!intty || !outtty) { ! 214: printf("~h: no can do!?\n"); ! 215: break; ! 216: } ! 217: grabh(hp, GTO|GSUBJECT|GCC|GBCC); ! 218: printf("(continue)\n"); ! 219: break; ! 220: ! 221: case 't': ! 222: /* ! 223: * Add to the To list. ! 224: */ ! 225: ! 226: hp->h_to = addto(hp->h_to, &linebuf[2]); ! 227: hp->h_seq++; ! 228: break; ! 229: ! 230: case 's': ! 231: /* ! 232: * Set the Subject list. ! 233: */ ! 234: ! 235: cp = &linebuf[2]; ! 236: while (any(*cp, " \t")) ! 237: cp++; ! 238: hp->h_subject = savestr(cp); ! 239: hp->h_seq++; ! 240: break; ! 241: ! 242: case 'c': ! 243: /* ! 244: * Add to the CC list. ! 245: */ ! 246: ! 247: hp->h_cc = addto(hp->h_cc, &linebuf[2]); ! 248: hp->h_seq++; ! 249: break; ! 250: ! 251: case 'b': ! 252: /* ! 253: * Add stuff to blind carbon copies list. ! 254: */ ! 255: hp->h_bcc = addto(hp->h_bcc, &linebuf[2]); ! 256: hp->h_seq++; ! 257: break; ! 258: ! 259: case 'd': ! 260: copy(deadletter, &linebuf[2]); ! 261: /* fall into . . . */ ! 262: ! 263: case 'r': ! 264: /* ! 265: * Invoke a file: ! 266: * Search for the file name, ! 267: * then open it and copy the contents to obuf. ! 268: */ ! 269: ! 270: cp = &linebuf[2]; ! 271: while (any(*cp, " \t")) ! 272: cp++; ! 273: if (*cp == '\0') { ! 274: printf("Interpolate what file?\n"); ! 275: break; ! 276: } ! 277: cp = expand(cp); ! 278: if (cp == NOSTR) ! 279: break; ! 280: if (isdir(cp)) { ! 281: printf("%s: directory\n"); ! 282: break; ! 283: } ! 284: if ((fbuf = fopen(cp, "r")) == NULL) { ! 285: perror(cp); ! 286: break; ! 287: } ! 288: printf("\"%s\" ", cp); ! 289: fflush(stdout); ! 290: lc = 0; ! 291: cc = 0; ! 292: while (readline(fbuf, linebuf) > 0) { ! 293: lc++; ! 294: if ((t = putline(obuf, linebuf)) < 0) { ! 295: fclose(fbuf); ! 296: goto err; ! 297: } ! 298: cc += t; ! 299: } ! 300: fclose(fbuf); ! 301: printf("%d/%d\n", lc, cc); ! 302: break; ! 303: ! 304: case 'w': ! 305: /* ! 306: * Write the message on a file. ! 307: */ ! 308: ! 309: cp = &linebuf[2]; ! 310: while (any(*cp, " \t")) ! 311: cp++; ! 312: if (*cp == '\0') { ! 313: fprintf(stderr, "Write what file!?\n"); ! 314: break; ! 315: } ! 316: if ((cp = expand(cp)) == NOSTR) ! 317: break; ! 318: fflush(obuf); ! 319: rewind(ibuf); ! 320: exwrite(cp, ibuf, 1); ! 321: break; ! 322: ! 323: case 'm': ! 324: case 'f': ! 325: /* ! 326: * Interpolate the named messages, if we ! 327: * are in receiving mail mode. Does the ! 328: * standard list processing garbage. ! 329: * If ~f is given, we don't shift over. ! 330: */ ! 331: ! 332: if (!rcvmode) { ! 333: printf("No messages to send from!?!\n"); ! 334: break; ! 335: } ! 336: cp = &linebuf[2]; ! 337: while (any(*cp, " \t")) ! 338: cp++; ! 339: if (forward(cp, obuf, c) < 0) ! 340: goto err; ! 341: printf("(continue)\n"); ! 342: break; ! 343: ! 344: case '?': ! 345: if ((fbuf = fopen(THELPFILE, "r")) == NULL) { ! 346: perror(THELPFILE); ! 347: break; ! 348: } ! 349: t = getc(fbuf); ! 350: while (t != -1) { ! 351: putchar(t); ! 352: t = getc(fbuf); ! 353: } ! 354: fclose(fbuf); ! 355: break; ! 356: ! 357: case 'p': ! 358: /* ! 359: * Print out the current state of the ! 360: * message without altering anything. ! 361: */ ! 362: ! 363: fflush(obuf); ! 364: rewind(ibuf); ! 365: printf("-------\nMessage contains:\n"); ! 366: puthead(hp, stdout, GTO|GSUBJECT|GCC|GBCC|GNL); ! 367: t = getc(ibuf); ! 368: while (t != EOF) { ! 369: putchar(t); ! 370: t = getc(ibuf); ! 371: } ! 372: printf("(continue)\n"); ! 373: break; ! 374: ! 375: case '^': ! 376: case '|': ! 377: /* ! 378: * Pipe message through command. ! 379: * Collect output as new message. ! 380: */ ! 381: ! 382: obuf = mespipe(ibuf, obuf, &linebuf[2]); ! 383: newo = obuf; ! 384: ibuf = newi; ! 385: newi = ibuf; ! 386: printf("(continue)\n"); ! 387: break; ! 388: ! 389: case 'v': ! 390: case 'e': ! 391: /* ! 392: * Edit the current message. ! 393: * 'e' means to use EDITOR ! 394: * 'v' means to use VISUAL ! 395: */ ! 396: ! 397: if ((obuf = mesedit(ibuf, obuf, c)) == NULL) ! 398: goto err; ! 399: newo = obuf; ! 400: ibuf = newi; ! 401: printf("(continue)\n"); ! 402: break; ! 403: } ! 404: } ! 405: eofl: ! 406: fclose(obuf); ! 407: rewind(ibuf); ! 408: sigset(SIGINT, savesig); ! 409: sigset(SIGHUP, savehup); ! 410: # ifdef VMUNIX ! 411: sigset(SIGCONT, savecont); ! 412: sigsetmask(0); ! 413: # endif VMUNIX ! 414: noreset = 0; ! 415: return(ibuf); ! 416: ! 417: err: ! 418: if (ibuf != NULL) ! 419: fclose(ibuf); ! 420: if (obuf != NULL) ! 421: fclose(obuf); ! 422: sigset(SIGINT, savesig); ! 423: sigset(SIGHUP, savehup); ! 424: # ifdef VMUNIX ! 425: sigset(SIGCONT, savecont); ! 426: sigsetmask(0); ! 427: # endif VMUNIX ! 428: noreset = 0; ! 429: return(NULL); ! 430: } ! 431: ! 432: /* ! 433: * Non destructively interrogate the value of the given signal. ! 434: */ ! 435: ! 436: psig(n) ! 437: { ! 438: register (*wassig)(); ! 439: ! 440: wassig = sigset(n, SIG_IGN); ! 441: sigset(n, wassig); ! 442: return((int) wassig); ! 443: } ! 444: ! 445: /* ! 446: * Write a file, ex-like if f set. ! 447: */ ! 448: ! 449: exwrite(name, ibuf, f) ! 450: char name[]; ! 451: FILE *ibuf; ! 452: { ! 453: register FILE *of; ! 454: register int c; ! 455: long cc; ! 456: int lc; ! 457: struct stat junk; ! 458: ! 459: if (f) { ! 460: printf("\"%s\" ", name); ! 461: fflush(stdout); ! 462: } ! 463: if (stat(name, &junk) >= 0 && (junk.st_mode & S_IFMT) == S_IFREG) { ! 464: if (!f) ! 465: fprintf(stderr, "%s: ", name); ! 466: fprintf(stderr, "File exists\n", name); ! 467: return(-1); ! 468: } ! 469: if ((of = fopen(name, "w")) == NULL) { ! 470: perror(NOSTR); ! 471: return(-1); ! 472: } ! 473: lc = 0; ! 474: cc = 0; ! 475: while ((c = getc(ibuf)) != EOF) { ! 476: cc++; ! 477: if (c == '\n') ! 478: lc++; ! 479: putc(c, of); ! 480: if (ferror(of)) { ! 481: perror(name); ! 482: fclose(of); ! 483: return(-1); ! 484: } ! 485: } ! 486: fclose(of); ! 487: printf("%d/%ld\n", lc, cc); ! 488: fflush(stdout); ! 489: return(0); ! 490: } ! 491: ! 492: /* ! 493: * Edit the message being collected on ibuf and obuf. ! 494: * Write the message out onto some poorly-named temp file ! 495: * and point an editor at it. ! 496: * ! 497: * On return, make the edit file the new temp file. ! 498: */ ! 499: ! 500: FILE * ! 501: mesedit(ibuf, obuf, c) ! 502: FILE *ibuf, *obuf; ! 503: { ! 504: int pid, s; ! 505: FILE *fbuf; ! 506: register int t; ! 507: int (*sig)(), (*scont)(), signull(); ! 508: struct stat sbuf; ! 509: extern char tempMail[], tempEdit[]; ! 510: register char *edit; ! 511: ! 512: sig = sigset(SIGINT, SIG_IGN); ! 513: # ifdef VMUNIX ! 514: scont = sigset(SIGCONT, signull); ! 515: # endif VMUNIX ! 516: if (stat(tempEdit, &sbuf) >= 0) { ! 517: printf("%s: file exists\n", tempEdit); ! 518: goto out; ! 519: } ! 520: close(creat(tempEdit, 0600)); ! 521: if ((fbuf = fopen(tempEdit, "w")) == NULL) { ! 522: perror(tempEdit); ! 523: goto out; ! 524: } ! 525: fflush(obuf); ! 526: rewind(ibuf); ! 527: t = getc(ibuf); ! 528: while (t != EOF) { ! 529: putc(t, fbuf); ! 530: t = getc(ibuf); ! 531: } ! 532: fflush(fbuf); ! 533: if (ferror(fbuf)) { ! 534: perror(tempEdit); ! 535: remove(tempEdit); ! 536: goto fix; ! 537: } ! 538: fclose(fbuf); ! 539: if ((edit = value(c == 'e' ? "EDITOR" : "VISUAL")) == NOSTR) ! 540: edit = c == 'e' ? EDITOR : VISUAL; ! 541: pid = vfork(); ! 542: if (pid == 0) { ! 543: sigchild(); ! 544: if (sig != SIG_IGN) ! 545: sigsys(SIGINT, SIG_DFL); ! 546: execl(edit, edit, tempEdit, 0); ! 547: perror(edit); ! 548: _exit(1); ! 549: } ! 550: if (pid == -1) { ! 551: perror("fork"); ! 552: remove(tempEdit); ! 553: goto out; ! 554: } ! 555: while (wait(&s) != pid) ! 556: ; ! 557: if ((s & 0377) != 0) { ! 558: printf("Fatal error in \"%s\"\n", edit); ! 559: remove(tempEdit); ! 560: goto out; ! 561: } ! 562: ! 563: /* ! 564: * Now switch to new file. ! 565: */ ! 566: ! 567: if ((fbuf = fopen(tempEdit, "a")) == NULL) { ! 568: perror(tempEdit); ! 569: remove(tempEdit); ! 570: goto out; ! 571: } ! 572: if ((ibuf = fopen(tempEdit, "r")) == NULL) { ! 573: perror(tempEdit); ! 574: fclose(fbuf); ! 575: remove(tempEdit); ! 576: goto out; ! 577: } ! 578: remove(tempEdit); ! 579: fclose(obuf); ! 580: fclose(newi); ! 581: obuf = fbuf; ! 582: goto out; ! 583: fix: ! 584: perror(tempEdit); ! 585: out: ! 586: # ifdef VMUNIX ! 587: sigset(SIGCONT, scont); ! 588: # endif VMUNIX ! 589: sigset(SIGINT, sig); ! 590: newi = ibuf; ! 591: return(obuf); ! 592: } ! 593: ! 594: /* ! 595: * Pipe the message through the command. ! 596: * Old message is on stdin of command; ! 597: * New message collected from stdout. ! 598: * Sh -c must return 0 to accept the new message. ! 599: */ ! 600: ! 601: FILE * ! 602: mespipe(ibuf, obuf, cmd) ! 603: FILE *ibuf, *obuf; ! 604: char cmd[]; ! 605: { ! 606: register FILE *ni, *no; ! 607: int pid, s; ! 608: int (*savesig)(); ! 609: char *Shell; ! 610: ! 611: newi = ibuf; ! 612: if ((no = fopen(tempEdit, "w")) == NULL) { ! 613: perror(tempEdit); ! 614: return(obuf); ! 615: } ! 616: if ((ni = fopen(tempEdit, "r")) == NULL) { ! 617: perror(tempEdit); ! 618: fclose(no); ! 619: remove(tempEdit); ! 620: return(obuf); ! 621: } ! 622: remove(tempEdit); ! 623: savesig = sigset(SIGINT, SIG_IGN); ! 624: fflush(obuf); ! 625: rewind(ibuf); ! 626: if ((Shell = value("SHELL")) == NULL) ! 627: Shell = "/bin/sh"; ! 628: if ((pid = vfork()) == -1) { ! 629: perror("fork"); ! 630: goto err; ! 631: } ! 632: if (pid == 0) { ! 633: /* ! 634: * stdin = current message. ! 635: * stdout = new message. ! 636: */ ! 637: ! 638: sigchild(); ! 639: close(0); ! 640: dup(fileno(ibuf)); ! 641: close(1); ! 642: dup(fileno(no)); ! 643: for (s = 4; s < 15; s++) ! 644: close(s); ! 645: execl(Shell, Shell, "-c", cmd, 0); ! 646: perror(Shell); ! 647: _exit(1); ! 648: } ! 649: while (wait(&s) != pid) ! 650: ; ! 651: if (s != 0 || pid == -1) { ! 652: fprintf(stderr, "\"%s\" failed!?\n", cmd); ! 653: goto err; ! 654: } ! 655: if (fsize(ni) == 0) { ! 656: fprintf(stderr, "No bytes from \"%s\" !?\n", cmd); ! 657: goto err; ! 658: } ! 659: ! 660: /* ! 661: * Take new files. ! 662: */ ! 663: ! 664: newi = ni; ! 665: fclose(ibuf); ! 666: fclose(obuf); ! 667: sigset(SIGINT, savesig); ! 668: return(no); ! 669: ! 670: err: ! 671: fclose(no); ! 672: fclose(ni); ! 673: sigset(SIGINT, savesig); ! 674: return(obuf); ! 675: } ! 676: ! 677: /* ! 678: * Interpolate the named messages into the current ! 679: * message, preceding each line with a tab. ! 680: * Return a count of the number of characters now in ! 681: * the message, or -1 if an error is encountered writing ! 682: * the message temporary. The flag argument is 'm' if we ! 683: * should shift over and 'f' if not. ! 684: */ ! 685: forward(ms, obuf, f) ! 686: char ms[]; ! 687: FILE *obuf; ! 688: { ! 689: register int *msgvec, *ip; ! 690: extern char tempMail[]; ! 691: ! 692: msgvec = (int *) salloc((msgCount+1) * sizeof *msgvec); ! 693: if (msgvec == (int *) NOSTR) ! 694: return(0); ! 695: if (getmsglist(ms, msgvec, 0) < 0) ! 696: return(0); ! 697: if (*msgvec == NULL) { ! 698: *msgvec = first(0, MMNORM); ! 699: if (*msgvec == NULL) { ! 700: printf("No appropriate messages\n"); ! 701: return(0); ! 702: } ! 703: msgvec[1] = NULL; ! 704: } ! 705: printf("Interpolating:"); ! 706: for (ip = msgvec; *ip != NULL; ip++) { ! 707: touch(*ip); ! 708: printf(" %d", *ip); ! 709: if (f == 'm') { ! 710: if (transmit(&message[*ip-1], obuf) < 0L) { ! 711: perror(tempMail); ! 712: return(-1); ! 713: } ! 714: } else ! 715: if (send(&message[*ip-1], obuf, 0) < 0) { ! 716: perror(tempMail); ! 717: return(-1); ! 718: } ! 719: } ! 720: printf("\n"); ! 721: return(0); ! 722: } ! 723: ! 724: /* ! 725: * Send message described by the passed pointer to the ! 726: * passed output buffer. Insert a tab in front of each ! 727: * line. Return a count of the characters sent, or -1 ! 728: * on error. ! 729: */ ! 730: ! 731: long ! 732: transmit(mailp, obuf) ! 733: struct message *mailp; ! 734: FILE *obuf; ! 735: { ! 736: register struct message *mp; ! 737: register int ch; ! 738: long c, n; ! 739: int bol; ! 740: FILE *ibuf; ! 741: ! 742: mp = mailp; ! 743: ibuf = setinput(mp); ! 744: c = mp->m_size; ! 745: n = c; ! 746: bol = 1; ! 747: while (c-- > 0L) { ! 748: if (bol) { ! 749: bol = 0; ! 750: putc('\t', obuf); ! 751: n++; ! 752: if (ferror(obuf)) { ! 753: perror("/tmp"); ! 754: return(-1L); ! 755: } ! 756: } ! 757: ch = getc(ibuf); ! 758: if (ch == '\n') ! 759: bol++; ! 760: putc(ch, obuf); ! 761: if (ferror(obuf)) { ! 762: perror("/tmp"); ! 763: return(-1L); ! 764: } ! 765: } ! 766: return(n); ! 767: } ! 768: ! 769: /* ! 770: * Print (continue) when continued after ^Z. ! 771: */ ! 772: collcont(s) ! 773: { ! 774: ! 775: printf("(continue)\n"); ! 776: fflush(stdout); ! 777: } ! 778: ! 779: /* ! 780: * On interrupt, go here to save the partial ! 781: * message on ~/dead.letter. ! 782: * Then restore signals and execute the normal ! 783: * signal routine. We only come here if signals ! 784: * were previously set anyway. ! 785: */ ! 786: ! 787: # ifndef VMUNIX ! 788: collintsig() ! 789: { ! 790: signal(SIGINT, SIG_IGN); ! 791: collrub(SIGINT); ! 792: } ! 793: ! 794: collhupsig() ! 795: { ! 796: signal(SIGHUP, SIG_IGN); ! 797: collrub(SIGHUP); ! 798: } ! 799: # endif VMUNIX ! 800: ! 801: collrub(s) ! 802: { ! 803: register FILE *dbuf; ! 804: register int c; ! 805: ! 806: if (s == SIGINT && hadintr == 0) { ! 807: hadintr++; ! 808: fflush(stdout); ! 809: fprintf(stderr, "\n(Interrupt -- one more to kill letter)\n"); ! 810: longjmp(coljmp, 1); ! 811: } ! 812: fclose(newo); ! 813: rewind(newi); ! 814: if (s == SIGINT && value("nosave") != NOSTR || fsize(newi) == 0) ! 815: goto done; ! 816: if ((dbuf = fopen(deadletter, "w")) == NULL) ! 817: goto done; ! 818: chmod(deadletter, 0600); ! 819: while ((c = getc(newi)) != EOF) ! 820: putc(c, dbuf); ! 821: fclose(dbuf); ! 822: ! 823: done: ! 824: fclose(newi); ! 825: sigset(SIGINT, savesig); ! 826: sigset(SIGHUP, savehup); ! 827: # ifdef VMUNIX ! 828: sigset(SIGCONT, savecont); ! 829: # endif VMUNIX ! 830: if (rcvmode) { ! 831: if (s == SIGHUP) ! 832: hangup(SIGHUP); ! 833: else ! 834: stop(s); ! 835: } ! 836: else ! 837: exit(1); ! 838: } ! 839: ! 840: /* ! 841: * Acknowledge an interrupt signal from the tty by typing an @ ! 842: */ ! 843: ! 844: intack(s) ! 845: { ! 846: ! 847: puts("@"); ! 848: fflush(stdout); ! 849: clearerr(stdin); ! 850: } ! 851: ! 852: /* ! 853: * Add a string to the end of a header entry field. ! 854: */ ! 855: ! 856: char * ! 857: addto(hf, news) ! 858: char hf[], news[]; ! 859: { ! 860: register char *cp, *cp2, *linebuf; ! 861: ! 862: if (hf == NOSTR) ! 863: hf = ""; ! 864: if (*news == '\0') ! 865: return(hf); ! 866: linebuf = salloc(strlen(hf) + strlen(news) + 2); ! 867: for (cp = hf; any(*cp, " \t"); cp++) ! 868: ; ! 869: for (cp2 = linebuf; *cp;) ! 870: *cp2++ = *cp++; ! 871: *cp2++ = ' '; ! 872: for (cp = news; any(*cp, " \t"); cp++) ! 873: ; ! 874: while (*cp != '\0') ! 875: *cp2++ = *cp++; ! 876: *cp2 = '\0'; ! 877: return(linebuf); ! 878: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.