Commit | Line | Data |
---|---|---|
761330fe 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. | |
761330fe DF |
16 | */ |
17 | ||
acfc7e9b | 18 | #ifndef lint |
e44ee2f8 | 19 | static char sccsid[] = "@(#)tty.c 5.8 (Berkeley) %G%"; |
acfc7e9b | 20 | #endif /* not lint */ |
80741a9f KS |
21 | |
22 | /* | |
23 | * Mail -- a mail program | |
24 | * | |
25 | * Generally useful tty stuff. | |
26 | */ | |
27 | ||
28 | #include "rcv.h" | |
80741a9f | 29 | |
80741a9f KS |
30 | static int c_erase; /* Current erase char */ |
31 | static int c_kill; /* Current kill char */ | |
1b38f4e9 | 32 | static jmp_buf rewrite; /* Place to go when continued */ |
e44ee2f8 | 33 | static jmp_buf intjmp; /* Place to go when interrupted */ |
80741a9f KS |
34 | #ifndef TIOCSTI |
35 | static int ttyset; /* We must now do erase/kill */ | |
36 | #endif | |
37 | ||
38 | /* | |
39 | * Read all relevant header fields. | |
40 | */ | |
41 | ||
42 | grabh(hp, gflags) | |
43 | struct header *hp; | |
44 | { | |
45 | struct sgttyb ttybuf; | |
e44ee2f8 | 46 | int (*saveint)(); |
80741a9f | 47 | #ifndef TIOCSTI |
e44ee2f8 | 48 | int (*savequit)(); |
80741a9f | 49 | #endif |
e44ee2f8 EW |
50 | int (*savetstp)(); |
51 | int (*savettou)(); | |
52 | int (*savettin)(); | |
80741a9f | 53 | int errs; |
e44ee2f8 | 54 | int ttyint(); |
80741a9f | 55 | |
e44ee2f8 EW |
56 | savetstp = signal(SIGTSTP, SIG_DFL); |
57 | savettou = signal(SIGTTOU, SIG_DFL); | |
58 | savettin = signal(SIGTTIN, SIG_DFL); | |
80741a9f KS |
59 | errs = 0; |
60 | #ifndef TIOCSTI | |
61 | ttyset = 0; | |
62 | #endif | |
63 | if (gtty(fileno(stdin), &ttybuf) < 0) { | |
64 | perror("gtty"); | |
65 | return(-1); | |
66 | } | |
67 | c_erase = ttybuf.sg_erase; | |
68 | c_kill = ttybuf.sg_kill; | |
69 | #ifndef TIOCSTI | |
70 | ttybuf.sg_erase = 0; | |
71 | ttybuf.sg_kill = 0; | |
828615a1 EW |
72 | if ((saveint = signal(SIGINT, SIG_IGN)) == SIG_DFL) |
73 | signal(SIGINT, SIG_DFL); | |
74 | if ((savequit = signal(SIGQUIT, SIG_IGN)) == SIG_DFL) | |
75 | signal(SIGQUIT, SIG_DFL); | |
e44ee2f8 EW |
76 | #else |
77 | if (setjmp(intjmp)) | |
78 | goto out; | |
79 | saveint = signal(SIGINT, ttyint); | |
80741a9f KS |
80 | #endif |
81 | if (gflags & GTO) { | |
82 | #ifndef TIOCSTI | |
3d6f01e5 | 83 | if (!ttyset && hp->h_to != NIL) |
80741a9f KS |
84 | ttyset++, stty(fileno(stdin), &ttybuf); |
85 | #endif | |
3d6f01e5 EW |
86 | hp->h_to = |
87 | extract(readtty("To: ", detract(hp->h_to, 0)), GTO); | |
80741a9f KS |
88 | } |
89 | if (gflags & GSUBJECT) { | |
90 | #ifndef TIOCSTI | |
91 | if (!ttyset && hp->h_subject != NOSTR) | |
92 | ttyset++, stty(fileno(stdin), &ttybuf); | |
93 | #endif | |
94 | hp->h_subject = readtty("Subject: ", hp->h_subject); | |
80741a9f KS |
95 | } |
96 | if (gflags & GCC) { | |
97 | #ifndef TIOCSTI | |
3d6f01e5 | 98 | if (!ttyset && hp->h_cc != NIL) |
80741a9f KS |
99 | ttyset++, stty(fileno(stdin), &ttybuf); |
100 | #endif | |
3d6f01e5 EW |
101 | hp->h_cc = |
102 | extract(readtty("Cc: ", detract(hp->h_cc, 0)), GCC); | |
80741a9f KS |
103 | } |
104 | if (gflags & GBCC) { | |
105 | #ifndef TIOCSTI | |
3d6f01e5 | 106 | if (!ttyset && hp->h_bcc != NIL) |
80741a9f KS |
107 | ttyset++, stty(fileno(stdin), &ttybuf); |
108 | #endif | |
3d6f01e5 EW |
109 | hp->h_bcc = |
110 | extract(readtty("Bcc: ", detract(hp->h_bcc, 0)), GBCC); | |
80741a9f | 111 | } |
e44ee2f8 EW |
112 | out: |
113 | signal(SIGTSTP, savetstp); | |
114 | signal(SIGTTOU, savettou); | |
115 | signal(SIGTTIN, savettin); | |
80741a9f KS |
116 | #ifndef TIOCSTI |
117 | ttybuf.sg_erase = c_erase; | |
118 | ttybuf.sg_kill = c_kill; | |
119 | if (ttyset) | |
120 | stty(fileno(stdin), &ttybuf); | |
828615a1 | 121 | signal(SIGQUIT, savequit); |
80741a9f | 122 | #endif |
e44ee2f8 | 123 | signal(SIGINT, saveint); |
80741a9f KS |
124 | return(errs); |
125 | } | |
126 | ||
127 | /* | |
128 | * Read up a header from standard input. | |
129 | * The source string has the preliminary contents to | |
130 | * be read. | |
131 | * | |
132 | */ | |
133 | ||
134 | char * | |
135 | readtty(pr, src) | |
136 | char pr[], src[]; | |
137 | { | |
338c4a5d | 138 | char ch, canonb[BUFSIZ]; |
828615a1 | 139 | int c; |
80741a9f | 140 | register char *cp, *cp2; |
e44ee2f8 | 141 | int ttystop(); |
80741a9f | 142 | |
1b38f4e9 KS |
143 | fputs(pr, stdout); |
144 | fflush(stdout); | |
80741a9f KS |
145 | if (src != NOSTR && strlen(src) > BUFSIZ - 2) { |
146 | printf("too long to edit\n"); | |
147 | return(src); | |
148 | } | |
149 | #ifndef TIOCSTI | |
150 | if (src != NOSTR) | |
151 | cp = copy(src, canonb); | |
152 | else | |
153 | cp = copy("", canonb); | |
154 | fputs(canonb, stdout); | |
155 | fflush(stdout); | |
156 | #else | |
1b38f4e9 KS |
157 | cp = src == NOSTR ? "" : src; |
158 | while (c = *cp++) { | |
80741a9f KS |
159 | if (c == c_erase || c == c_kill) { |
160 | ch = '\\'; | |
161 | ioctl(0, TIOCSTI, &ch); | |
162 | } | |
338c4a5d SL |
163 | ch = c; |
164 | ioctl(0, TIOCSTI, &ch); | |
80741a9f KS |
165 | } |
166 | cp = canonb; | |
419b1e01 | 167 | *cp = 0; |
80741a9f | 168 | #endif |
1b38f4e9 KS |
169 | cp2 = cp; |
170 | while (cp2 < canonb + BUFSIZ) | |
171 | *cp2++ = 0; | |
172 | cp2 = cp; | |
173 | if (setjmp(rewrite)) | |
174 | goto redo; | |
e44ee2f8 EW |
175 | signal(SIGTSTP, ttystop); |
176 | signal(SIGTTOU, ttystop); | |
177 | signal(SIGTTIN, ttystop); | |
7bfe8da7 | 178 | clearerr(stdin); |
1b38f4e9 KS |
179 | while (cp2 < canonb + BUFSIZ) { |
180 | c = getc(stdin); | |
181 | if (c == EOF || c == '\n') | |
182 | break; | |
183 | *cp2++ = c; | |
184 | } | |
185 | *cp2 = 0; | |
e44ee2f8 EW |
186 | signal(SIGTSTP, SIG_DFL); |
187 | signal(SIGTTOU, SIG_DFL); | |
188 | signal(SIGTTIN, SIG_DFL); | |
189 | if (c == EOF && ferror(stdin)) { | |
1b38f4e9 | 190 | redo: |
1b38f4e9 KS |
191 | cp = strlen(canonb) > 0 ? canonb : NOSTR; |
192 | clearerr(stdin); | |
193 | return(readtty(pr, cp)); | |
194 | } | |
80741a9f | 195 | #ifndef TIOCSTI |
ea394d88 | 196 | if (cp == NOSTR || *cp == '\0') |
80741a9f | 197 | return(src); |
ea394d88 | 198 | cp2 = cp; |
80741a9f KS |
199 | if (!ttyset) |
200 | return(strlen(canonb) > 0 ? savestr(canonb) : NOSTR); | |
201 | while (*cp != '\0') { | |
202 | c = *cp++; | |
203 | if (c == c_erase) { | |
204 | if (cp2 == canonb) | |
205 | continue; | |
206 | if (cp2[-1] == '\\') { | |
207 | cp2[-1] = c; | |
208 | continue; | |
209 | } | |
210 | cp2--; | |
211 | continue; | |
212 | } | |
213 | if (c == c_kill) { | |
214 | if (cp2 == canonb) | |
215 | continue; | |
216 | if (cp2[-1] == '\\') { | |
217 | cp2[-1] = c; | |
218 | continue; | |
219 | } | |
220 | cp2 = canonb; | |
221 | continue; | |
222 | } | |
223 | *cp2++ = c; | |
224 | } | |
225 | *cp2 = '\0'; | |
226 | #endif | |
227 | if (equal("", canonb)) | |
228 | return(NOSTR); | |
229 | return(savestr(canonb)); | |
230 | } | |
1b38f4e9 KS |
231 | |
232 | /* | |
233 | * Receipt continuation. | |
234 | */ | |
e44ee2f8 | 235 | ttystop(s) |
1b38f4e9 | 236 | { |
e44ee2f8 EW |
237 | int (*old_action)() = signal(s, SIG_DFL); |
238 | ||
239 | sigsetmask(sigblock(0) & ~sigmask(s)); | |
240 | kill(0, s); | |
241 | sigblock(sigmask(s)); | |
242 | signal(s, old_action); | |
1b38f4e9 KS |
243 | longjmp(rewrite, 1); |
244 | } | |
e44ee2f8 EW |
245 | |
246 | /*ARGSUSED*/ | |
247 | ttyint(s) | |
248 | { | |
249 | ||
250 | longjmp(intjmp, 1); | |
251 | } |