Commit | Line | Data |
---|---|---|
9552e6b8 DF |
1 | /* |
2 | * Copyright (c) 1980 Regents of the University of California. | |
0c5f72fb KB |
3 | * All rights reserved. |
4 | * | |
5 | * Redistribution and use in source and binary forms are permitted | |
acfc7e9b KB |
6 | * provided that the above copyright notice and this paragraph are |
7 | * duplicated in all such forms and that any documentation, | |
8 | * advertising materials, and other materials related to such | |
9 | * distribution and use acknowledge that the software was developed | |
10 | * by the University of California, Berkeley. The name of the | |
11 | * University may not be used to endorse or promote products derived | |
12 | * from this software without specific prior written permission. | |
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
14 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
15 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
9552e6b8 DF |
16 | */ |
17 | ||
acfc7e9b | 18 | #ifndef lint |
470c33f3 | 19 | static char sccsid[] = "@(#)collect.c 5.14 (Berkeley) %G%"; |
acfc7e9b | 20 | #endif /* not lint */ |
06300dd9 KS |
21 | |
22 | /* | |
23 | * Mail -- a mail program | |
24 | * | |
25 | * Collect input from standard input, handling | |
26 | * ~ escapes. | |
27 | */ | |
28 | ||
06300dd9 KS |
29 | #include "rcv.h" |
30 | #include <sys/stat.h> | |
31 | ||
32 | /* | |
33 | * Read a message from standard output and return a read file to it | |
34 | * or NULL on error. | |
35 | */ | |
36 | ||
37 | /* | |
38 | * The following hokiness with global variables is so that on | |
39 | * receipt of an interrupt signal, the partial message can be salted | |
828615a1 | 40 | * away on dead.letter. |
06300dd9 KS |
41 | */ |
42 | ||
828615a1 | 43 | static int (*saveint)(); /* Previous SIGINT value */ |
7feecf47 | 44 | static int (*savehup)(); /* Previous SIGHUP value */ |
2d55c063 | 45 | static int (*savecont)(); /* Previous SIGCONT value */ |
828615a1 | 46 | static FILE *collf; /* File for saving away */ |
06300dd9 KS |
47 | static int hadintr; /* Have seen one SIGINT so far */ |
48 | ||
49 | static jmp_buf coljmp; /* To get back to work */ | |
50 | ||
51 | FILE * | |
3d6f01e5 | 52 | collect(hp, printheaders) |
06300dd9 KS |
53 | struct header *hp; |
54 | { | |
d33aa50d | 55 | FILE *fbuf; |
828615a1 EW |
56 | int lc, cc, escape, eof; |
57 | int collrub(), intack(), collcont(); | |
06300dd9 KS |
58 | register int c, t; |
59 | char linebuf[LINESIZE], *cp; | |
60 | extern char tempMail[]; | |
4e161d3b | 61 | char getsub; |
828615a1 | 62 | int omask; |
06300dd9 KS |
63 | |
64 | noreset++; | |
828615a1 EW |
65 | collf = NULL; |
66 | ||
67 | /* | |
68 | * Start catching signals from here, but we're still die on interrupts | |
69 | * until we're in the main loop. | |
70 | */ | |
71 | omask = sigblock(sigmask(SIGINT) | sigmask(SIGHUP)); | |
72 | if ((saveint = signal(SIGINT, SIG_IGN)) != SIG_IGN) | |
73 | signal(SIGINT, value("ignore") != NOSTR ? intack : collrub); | |
74 | if ((savehup = signal(SIGHUP, SIG_IGN)) != SIG_IGN) | |
75 | signal(SIGHUP, collrub); | |
76 | savecont = signal(SIGCONT, SIG_DFL); | |
77 | if (setjmp(coljmp)) { | |
78 | remove(tempMail); | |
06300dd9 KS |
79 | goto err; |
80 | } | |
828615a1 EW |
81 | sigsetmask(omask & ~(sigmask(SIGINT) | sigmask(SIGHUP))); |
82 | ||
d33aa50d | 83 | if ((collf = fopen(tempMail, "w+")) == NULL) { |
06300dd9 | 84 | perror(tempMail); |
06300dd9 KS |
85 | goto err; |
86 | } | |
d33aa50d | 87 | unlink(tempMail); |
06300dd9 KS |
88 | |
89 | /* | |
90 | * If we are going to prompt for a subject, | |
91 | * refrain from printing a newline after | |
92 | * the headers (since some people mind). | |
93 | */ | |
06300dd9 | 94 | t = GTO|GSUBJECT|GCC|GNL; |
4e161d3b | 95 | getsub = 0; |
686f6134 EW |
96 | if (hp->h_subject == NOSTR && value("interactive") != NOSTR && |
97 | value("ask")) | |
4e161d3b | 98 | t &= ~GNL, getsub++; |
3d6f01e5 | 99 | if (printheaders) { |
06300dd9 KS |
100 | puthead(hp, stdout, t); |
101 | fflush(stdout); | |
102 | } | |
06300dd9 KS |
103 | if ((cp = value("escape")) != NOSTR) |
104 | escape = *cp; | |
686f6134 EW |
105 | else |
106 | escape = ESCAPE; | |
0fa68535 | 107 | eof = 0; |
828615a1 EW |
108 | hadintr = 0; |
109 | ||
828615a1 EW |
110 | if (!setjmp(coljmp)) { |
111 | signal(SIGCONT, collcont); | |
112 | if (getsub) | |
4e161d3b | 113 | grabh(hp, GSUBJECT); |
828615a1 EW |
114 | } else { |
115 | /* | |
116 | * Come here for printing the after-signal message. | |
117 | * Duplicate messages won't be printed because | |
118 | * the write is aborted if we get a SIGTTOU. | |
119 | */ | |
120 | cont: | |
121 | if (hadintr) { | |
122 | fflush(stdout); | |
123 | fprintf(stderr, | |
124 | "\n(Interrupt -- one more to kill letter)\n"); | |
125 | } else { | |
126 | printf("(continue)\n"); | |
127 | fflush(stdout); | |
4e161d3b | 128 | } |
828615a1 EW |
129 | } |
130 | for (;;) { | |
131 | if (readline(stdin, linebuf) < 0) { | |
686f6134 EW |
132 | if (value("interactive") != NOSTR && |
133 | value("ignoreeof") != NOSTR) { | |
0fa68535 KS |
134 | if (++eof > 35) |
135 | break; | |
828615a1 | 136 | printf("Use \".\" to terminate letter\n"); |
0fa68535 KS |
137 | continue; |
138 | } | |
06300dd9 | 139 | break; |
0fa68535 KS |
140 | } |
141 | eof = 0; | |
06300dd9 | 142 | hadintr = 0; |
686f6134 EW |
143 | if (linebuf[0] == '.' && linebuf[1] == '\0' && |
144 | value("interactive") != NOSTR && | |
b068a67e | 145 | (value("dot") != NOSTR || value("ignoreeof") != NOSTR)) |
06300dd9 | 146 | break; |
686f6134 | 147 | if (linebuf[0] != escape || value("interactive") == NOSTR) { |
d33aa50d | 148 | if (putline(collf, linebuf) < 0) |
06300dd9 KS |
149 | goto err; |
150 | continue; | |
151 | } | |
152 | c = linebuf[1]; | |
06300dd9 KS |
153 | switch (c) { |
154 | default: | |
155 | /* | |
156 | * On double escape, just send the single one. | |
157 | * Otherwise, it's an error. | |
158 | */ | |
06300dd9 | 159 | if (c == escape) { |
d33aa50d | 160 | if (putline(collf, &linebuf[1]) < 0) |
06300dd9 KS |
161 | goto err; |
162 | else | |
163 | break; | |
164 | } | |
165 | printf("Unknown tilde escape.\n"); | |
166 | break; | |
06300dd9 KS |
167 | case 'C': |
168 | /* | |
169 | * Dump core. | |
170 | */ | |
06300dd9 KS |
171 | core(); |
172 | break; | |
06300dd9 KS |
173 | case '!': |
174 | /* | |
175 | * Shell escape, send the balance of the | |
176 | * line to sh -c. | |
177 | */ | |
06300dd9 KS |
178 | shell(&linebuf[2]); |
179 | break; | |
06300dd9 | 180 | case ':': |
06300dd9 KS |
181 | /* |
182 | * Escape to command mode, but be nice! | |
183 | */ | |
343c874e | 184 | execute(&linebuf[2], 1); |
828615a1 | 185 | goto cont; |
06300dd9 KS |
186 | case '.': |
187 | /* | |
188 | * Simulate end of file on input. | |
189 | */ | |
828615a1 | 190 | goto out; |
06300dd9 | 191 | case 'q': |
06300dd9 KS |
192 | /* |
193 | * Force a quit of sending mail. | |
194 | * Act like an interrupt happened. | |
195 | */ | |
06300dd9 KS |
196 | hadintr++; |
197 | collrub(SIGINT); | |
198 | exit(1); | |
06300dd9 KS |
199 | case 'h': |
200 | /* | |
201 | * Grab a bunch of headers. | |
202 | */ | |
06300dd9 | 203 | grabh(hp, GTO|GSUBJECT|GCC|GBCC); |
828615a1 | 204 | goto cont; |
06300dd9 KS |
205 | case 't': |
206 | /* | |
207 | * Add to the To list. | |
208 | */ | |
3d6f01e5 | 209 | hp->h_to = cat(hp->h_to, extract(&linebuf[2], GTO)); |
06300dd9 | 210 | break; |
06300dd9 KS |
211 | case 's': |
212 | /* | |
213 | * Set the Subject list. | |
214 | */ | |
06300dd9 | 215 | cp = &linebuf[2]; |
828615a1 | 216 | while (isspace(*cp)) |
06300dd9 KS |
217 | cp++; |
218 | hp->h_subject = savestr(cp); | |
06300dd9 | 219 | break; |
06300dd9 KS |
220 | case 'c': |
221 | /* | |
222 | * Add to the CC list. | |
223 | */ | |
3d6f01e5 | 224 | hp->h_cc = cat(hp->h_cc, extract(&linebuf[2], GCC)); |
06300dd9 | 225 | break; |
06300dd9 KS |
226 | case 'b': |
227 | /* | |
228 | * Add stuff to blind carbon copies list. | |
229 | */ | |
3d6f01e5 | 230 | hp->h_bcc = cat(hp->h_bcc, extract(&linebuf[2], GBCC)); |
06300dd9 | 231 | break; |
06300dd9 | 232 | case 'd': |
828615a1 | 233 | strcpy(linebuf + 2, deadletter); |
06300dd9 | 234 | /* fall into . . . */ |
06300dd9 KS |
235 | case 'r': |
236 | /* | |
237 | * Invoke a file: | |
238 | * Search for the file name, | |
d33aa50d | 239 | * then open it and copy the contents to collf. |
06300dd9 | 240 | */ |
06300dd9 | 241 | cp = &linebuf[2]; |
828615a1 | 242 | while (isspace(*cp)) |
06300dd9 KS |
243 | cp++; |
244 | if (*cp == '\0') { | |
245 | printf("Interpolate what file?\n"); | |
246 | break; | |
247 | } | |
248 | cp = expand(cp); | |
249 | if (cp == NOSTR) | |
250 | break; | |
251 | if (isdir(cp)) { | |
828615a1 | 252 | printf("%s: Directory\n", cp); |
06300dd9 KS |
253 | break; |
254 | } | |
255 | if ((fbuf = fopen(cp, "r")) == NULL) { | |
256 | perror(cp); | |
257 | break; | |
258 | } | |
259 | printf("\"%s\" ", cp); | |
80187484 | 260 | fflush(stdout); |
06300dd9 KS |
261 | lc = 0; |
262 | cc = 0; | |
828615a1 | 263 | while (readline(fbuf, linebuf) >= 0) { |
06300dd9 | 264 | lc++; |
d33aa50d | 265 | if ((t = putline(collf, linebuf)) < 0) { |
06300dd9 KS |
266 | fclose(fbuf); |
267 | goto err; | |
268 | } | |
269 | cc += t; | |
270 | } | |
271 | fclose(fbuf); | |
272 | printf("%d/%d\n", lc, cc); | |
273 | break; | |
06300dd9 KS |
274 | case 'w': |
275 | /* | |
276 | * Write the message on a file. | |
277 | */ | |
06300dd9 | 278 | cp = &linebuf[2]; |
470c33f3 | 279 | while (*cp == ' ' || *cp == '\t') |
06300dd9 KS |
280 | cp++; |
281 | if (*cp == '\0') { | |
282 | fprintf(stderr, "Write what file!?\n"); | |
283 | break; | |
284 | } | |
285 | if ((cp = expand(cp)) == NOSTR) | |
286 | break; | |
d33aa50d EW |
287 | rewind(collf); |
288 | exwrite(cp, collf, 1); | |
06300dd9 | 289 | break; |
06300dd9 | 290 | case 'm': |
2de8fc95 | 291 | case 'M': |
06300dd9 | 292 | case 'f': |
2de8fc95 | 293 | case 'F': |
06300dd9 KS |
294 | /* |
295 | * Interpolate the named messages, if we | |
296 | * are in receiving mail mode. Does the | |
297 | * standard list processing garbage. | |
298 | * If ~f is given, we don't shift over. | |
299 | */ | |
06300dd9 KS |
300 | if (!rcvmode) { |
301 | printf("No messages to send from!?!\n"); | |
302 | break; | |
303 | } | |
470c33f3 | 304 | if (forward(linebuf + 2, collf, c) < 0) |
06300dd9 | 305 | goto err; |
828615a1 | 306 | goto cont; |
06300dd9 | 307 | case '?': |
06300dd9 | 308 | if ((fbuf = fopen(THELPFILE, "r")) == NULL) { |
e5cd0021 | 309 | perror(THELPFILE); |
06300dd9 KS |
310 | break; |
311 | } | |
4ee3e718 | 312 | while ((t = getc(fbuf)) != EOF) |
06300dd9 | 313 | putchar(t); |
06300dd9 KS |
314 | fclose(fbuf); |
315 | break; | |
06300dd9 KS |
316 | case 'p': |
317 | /* | |
318 | * Print out the current state of the | |
319 | * message without altering anything. | |
320 | */ | |
d33aa50d | 321 | rewind(collf); |
06300dd9 KS |
322 | printf("-------\nMessage contains:\n"); |
323 | puthead(hp, stdout, GTO|GSUBJECT|GCC|GBCC|GNL); | |
d33aa50d | 324 | while ((t = getc(collf)) != EOF) |
06300dd9 | 325 | putchar(t); |
828615a1 | 326 | goto cont; |
06300dd9 KS |
327 | case '|': |
328 | /* | |
329 | * Pipe message through command. | |
330 | * Collect output as new message. | |
331 | */ | |
d33aa50d EW |
332 | rewind(collf); |
333 | mespipe(collf, &linebuf[2]); | |
828615a1 | 334 | goto cont; |
06300dd9 KS |
335 | case 'v': |
336 | case 'e': | |
337 | /* | |
338 | * Edit the current message. | |
339 | * 'e' means to use EDITOR | |
340 | * 'v' means to use VISUAL | |
341 | */ | |
d33aa50d EW |
342 | rewind(collf); |
343 | mesedit(collf, c); | |
828615a1 | 344 | goto cont; |
06300dd9 KS |
345 | } |
346 | } | |
828615a1 | 347 | goto out; |
06300dd9 | 348 | err: |
d33aa50d EW |
349 | if (collf != NULL) { |
350 | fclose(collf); | |
351 | collf = NULL; | |
828615a1 EW |
352 | } |
353 | out: | |
d33aa50d EW |
354 | if (collf != NULL) |
355 | rewind(collf); | |
828615a1 EW |
356 | signal(SIGINT, saveint); |
357 | signal(SIGHUP, savehup); | |
358 | signal(SIGCONT, savecont); | |
359 | sigsetmask(omask); | |
f674e088 | 360 | noreset--; |
d33aa50d | 361 | return collf; |
06300dd9 KS |
362 | } |
363 | ||
364 | /* | |
365 | * Write a file, ex-like if f set. | |
366 | */ | |
367 | ||
828615a1 | 368 | exwrite(name, fp, f) |
06300dd9 | 369 | char name[]; |
828615a1 | 370 | FILE *fp; |
06300dd9 KS |
371 | { |
372 | register FILE *of; | |
373 | register int c; | |
374 | long cc; | |
375 | int lc; | |
376 | struct stat junk; | |
377 | ||
378 | if (f) { | |
379 | printf("\"%s\" ", name); | |
380 | fflush(stdout); | |
381 | } | |
6d1cdf8d | 382 | if (stat(name, &junk) >= 0 && (junk.st_mode & S_IFMT) == S_IFREG) { |
06300dd9 KS |
383 | if (!f) |
384 | fprintf(stderr, "%s: ", name); | |
828615a1 | 385 | fprintf(stderr, "File exists\n"); |
06300dd9 KS |
386 | return(-1); |
387 | } | |
388 | if ((of = fopen(name, "w")) == NULL) { | |
389 | perror(NOSTR); | |
390 | return(-1); | |
391 | } | |
392 | lc = 0; | |
393 | cc = 0; | |
828615a1 | 394 | while ((c = getc(fp)) != EOF) { |
06300dd9 KS |
395 | cc++; |
396 | if (c == '\n') | |
397 | lc++; | |
398 | putc(c, of); | |
399 | if (ferror(of)) { | |
400 | perror(name); | |
401 | fclose(of); | |
402 | return(-1); | |
403 | } | |
404 | } | |
405 | fclose(of); | |
406 | printf("%d/%ld\n", lc, cc); | |
407 | fflush(stdout); | |
408 | return(0); | |
409 | } | |
410 | ||
411 | /* | |
828615a1 | 412 | * Edit the message being collected on fp. |
06300dd9 KS |
413 | * On return, make the edit file the new temp file. |
414 | */ | |
828615a1 EW |
415 | mesedit(fp, c) |
416 | FILE *fp; | |
06300dd9 | 417 | { |
d33aa50d EW |
418 | int (*sigint)() = signal(SIGINT, SIG_IGN); |
419 | int (*sigcont)() = signal(SIGCONT, SIG_DFL); | |
420 | FILE *nf = run_editor(fp, (off_t)-1, c, 0); | |
06300dd9 | 421 | |
d33aa50d EW |
422 | if (nf != NULL) { |
423 | fseek(nf, (off_t)0, 2); | |
424 | collf = nf; | |
425 | fclose(fp); | |
06300dd9 | 426 | } |
d33aa50d EW |
427 | (void) signal(SIGINT, sigint); |
428 | (void) signal(SIGCONT, sigcont); | |
06300dd9 KS |
429 | } |
430 | ||
431 | /* | |
432 | * Pipe the message through the command. | |
433 | * Old message is on stdin of command; | |
434 | * New message collected from stdout. | |
435 | * Sh -c must return 0 to accept the new message. | |
436 | */ | |
828615a1 EW |
437 | mespipe(fp, cmd) |
438 | FILE *fp; | |
06300dd9 KS |
439 | char cmd[]; |
440 | { | |
d33aa50d EW |
441 | FILE *nf; |
442 | int (*sigint)() = signal(SIGINT, SIG_IGN); | |
443 | int (*sigcont)() = signal(SIGCONT, SIG_DFL); | |
001d60ad | 444 | extern char tempEdit[]; |
06300dd9 | 445 | |
828615a1 | 446 | if ((nf = fopen(tempEdit, "w+")) == NULL) { |
06300dd9 | 447 | perror(tempEdit); |
d33aa50d | 448 | goto out; |
06300dd9 | 449 | } |
d33aa50d EW |
450 | (void) unlink(tempEdit); |
451 | /* | |
452 | * stdin = current message. | |
453 | * stdout = new message. | |
454 | */ | |
455 | if (run_command(cmd, 0, fileno(fp), fileno(nf), NOSTR) < 0) { | |
456 | (void) fclose(nf); | |
457 | goto out; | |
06300dd9 | 458 | } |
828615a1 | 459 | if (fsize(nf) == 0) { |
06300dd9 | 460 | fprintf(stderr, "No bytes from \"%s\" !?\n", cmd); |
d33aa50d EW |
461 | (void) fclose(nf); |
462 | goto out; | |
06300dd9 | 463 | } |
06300dd9 KS |
464 | /* |
465 | * Take new files. | |
466 | */ | |
d33aa50d | 467 | (void) fseek(nf, 0L, 2); |
828615a1 | 468 | collf = nf; |
d33aa50d EW |
469 | (void) fclose(fp); |
470 | out: | |
471 | (void) signal(SIGINT, sigint); | |
472 | (void) signal(SIGCONT, sigcont); | |
06300dd9 KS |
473 | } |
474 | ||
475 | /* | |
476 | * Interpolate the named messages into the current | |
477 | * message, preceding each line with a tab. | |
478 | * Return a count of the number of characters now in | |
479 | * the message, or -1 if an error is encountered writing | |
480 | * the message temporary. The flag argument is 'm' if we | |
481 | * should shift over and 'f' if not. | |
482 | */ | |
828615a1 | 483 | forward(ms, fp, f) |
06300dd9 | 484 | char ms[]; |
828615a1 | 485 | FILE *fp; |
06300dd9 | 486 | { |
470c33f3 | 487 | register int *msgvec; |
06300dd9 | 488 | extern char tempMail[]; |
2de8fc95 EW |
489 | struct ignoretab *ig; |
490 | char *tabst; | |
06300dd9 KS |
491 | |
492 | msgvec = (int *) salloc((msgCount+1) * sizeof *msgvec); | |
493 | if (msgvec == (int *) NOSTR) | |
494 | return(0); | |
495 | if (getmsglist(ms, msgvec, 0) < 0) | |
496 | return(0); | |
470c33f3 | 497 | if (*msgvec == 0) { |
06300dd9 KS |
498 | *msgvec = first(0, MMNORM); |
499 | if (*msgvec == NULL) { | |
500 | printf("No appropriate messages\n"); | |
501 | return(0); | |
502 | } | |
503 | msgvec[1] = NULL; | |
504 | } | |
2de8fc95 EW |
505 | if (f == 'f' || f == 'F') |
506 | tabst = NOSTR; | |
507 | else if ((tabst = value("tabstr")) == NOSTR) | |
508 | tabst = "\t"; | |
509 | ig = isupper(f) ? NULL : ignore; | |
06300dd9 | 510 | printf("Interpolating:"); |
470c33f3 EW |
511 | for (; *msgvec != 0; msgvec++) { |
512 | struct message *mp = message + *msgvec - 1; | |
513 | ||
514 | touch(mp); | |
515 | printf(" %d", *msgvec); | |
516 | if (send(mp, fp, ig, tabst) < 0) { | |
2de8fc95 EW |
517 | perror(tempMail); |
518 | return(-1); | |
519 | } | |
06300dd9 KS |
520 | } |
521 | printf("\n"); | |
522 | return(0); | |
523 | } | |
524 | ||
2d55c063 KS |
525 | /* |
526 | * Print (continue) when continued after ^Z. | |
527 | */ | |
828615a1 | 528 | /*ARGSUSED*/ |
2d55c063 KS |
529 | collcont(s) |
530 | { | |
531 | ||
828615a1 EW |
532 | hadintr = 0; |
533 | longjmp(coljmp, 1); | |
2d55c063 KS |
534 | } |
535 | ||
06300dd9 KS |
536 | /* |
537 | * On interrupt, go here to save the partial | |
7feecf47 | 538 | * message on ~/dead.letter. |
06300dd9 KS |
539 | * Then restore signals and execute the normal |
540 | * signal routine. We only come here if signals | |
541 | * were previously set anyway. | |
542 | */ | |
06300dd9 KS |
543 | collrub(s) |
544 | { | |
545 | register FILE *dbuf; | |
546 | register int c; | |
547 | ||
7feecf47 | 548 | if (s == SIGINT && hadintr == 0) { |
828615a1 | 549 | hadintr = 1; |
06300dd9 KS |
550 | longjmp(coljmp, 1); |
551 | } | |
828615a1 EW |
552 | rewind(collf); |
553 | if (s == SIGINT && value("nosave") != NOSTR || fsize(collf) == 0) | |
06300dd9 KS |
554 | goto done; |
555 | if ((dbuf = fopen(deadletter, "w")) == NULL) | |
556 | goto done; | |
557 | chmod(deadletter, 0600); | |
828615a1 | 558 | while ((c = getc(collf)) != EOF) |
06300dd9 KS |
559 | putc(c, dbuf); |
560 | fclose(dbuf); | |
06300dd9 | 561 | done: |
828615a1 EW |
562 | fclose(collf); |
563 | signal(SIGINT, saveint); | |
564 | signal(SIGHUP, savehup); | |
565 | signal(SIGCONT, savecont); | |
7feecf47 KS |
566 | if (rcvmode) { |
567 | if (s == SIGHUP) | |
568 | hangup(SIGHUP); | |
569 | else | |
2d55c063 | 570 | stop(s); |
828615a1 | 571 | } else |
06300dd9 KS |
572 | exit(1); |
573 | } | |
574 | ||
575 | /* | |
576 | * Acknowledge an interrupt signal from the tty by typing an @ | |
577 | */ | |
828615a1 | 578 | /*ARGSUSED*/ |
06300dd9 KS |
579 | intack(s) |
580 | { | |
828615a1 | 581 | |
06300dd9 KS |
582 | puts("@"); |
583 | fflush(stdout); | |
584 | clearerr(stdin); | |
06300dd9 | 585 | } |