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