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