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 KB |
18 | #ifndef lint |
19 | static char sccsid[] = "@(#)tty.c 5.7 (Berkeley) %G%"; | |
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 KS |
32 | static int hadcont; /* Saw continue signal */ |
33 | static jmp_buf rewrite; /* Place to go when continued */ | |
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; | |
46 | #ifndef TIOCSTI | |
828615a1 | 47 | int (*saveint)(), (*savequit)(); |
80741a9f | 48 | #endif |
1b38f4e9 | 49 | int (*savecont)(); |
80741a9f KS |
50 | int errs; |
51 | ||
828615a1 | 52 | savecont = signal(SIGCONT, SIG_DFL); |
80741a9f KS |
53 | errs = 0; |
54 | #ifndef TIOCSTI | |
55 | ttyset = 0; | |
56 | #endif | |
57 | if (gtty(fileno(stdin), &ttybuf) < 0) { | |
58 | perror("gtty"); | |
59 | return(-1); | |
60 | } | |
61 | c_erase = ttybuf.sg_erase; | |
62 | c_kill = ttybuf.sg_kill; | |
63 | #ifndef TIOCSTI | |
64 | ttybuf.sg_erase = 0; | |
65 | ttybuf.sg_kill = 0; | |
828615a1 EW |
66 | if ((saveint = signal(SIGINT, SIG_IGN)) == SIG_DFL) |
67 | signal(SIGINT, SIG_DFL); | |
68 | if ((savequit = signal(SIGQUIT, SIG_IGN)) == SIG_DFL) | |
69 | signal(SIGQUIT, SIG_DFL); | |
80741a9f KS |
70 | #endif |
71 | if (gflags & GTO) { | |
72 | #ifndef TIOCSTI | |
3d6f01e5 | 73 | if (!ttyset && hp->h_to != NIL) |
80741a9f KS |
74 | ttyset++, stty(fileno(stdin), &ttybuf); |
75 | #endif | |
3d6f01e5 EW |
76 | hp->h_to = |
77 | extract(readtty("To: ", detract(hp->h_to, 0)), GTO); | |
80741a9f KS |
78 | } |
79 | if (gflags & GSUBJECT) { | |
80 | #ifndef TIOCSTI | |
81 | if (!ttyset && hp->h_subject != NOSTR) | |
82 | ttyset++, stty(fileno(stdin), &ttybuf); | |
83 | #endif | |
84 | hp->h_subject = readtty("Subject: ", hp->h_subject); | |
80741a9f KS |
85 | } |
86 | if (gflags & GCC) { | |
87 | #ifndef TIOCSTI | |
3d6f01e5 | 88 | if (!ttyset && hp->h_cc != NIL) |
80741a9f KS |
89 | ttyset++, stty(fileno(stdin), &ttybuf); |
90 | #endif | |
3d6f01e5 EW |
91 | hp->h_cc = |
92 | extract(readtty("Cc: ", detract(hp->h_cc, 0)), GCC); | |
80741a9f KS |
93 | } |
94 | if (gflags & GBCC) { | |
95 | #ifndef TIOCSTI | |
3d6f01e5 | 96 | if (!ttyset && hp->h_bcc != NIL) |
80741a9f KS |
97 | ttyset++, stty(fileno(stdin), &ttybuf); |
98 | #endif | |
3d6f01e5 EW |
99 | hp->h_bcc = |
100 | extract(readtty("Bcc: ", detract(hp->h_bcc, 0)), GBCC); | |
80741a9f | 101 | } |
828615a1 | 102 | signal(SIGCONT, savecont); |
80741a9f KS |
103 | #ifndef TIOCSTI |
104 | ttybuf.sg_erase = c_erase; | |
105 | ttybuf.sg_kill = c_kill; | |
106 | if (ttyset) | |
107 | stty(fileno(stdin), &ttybuf); | |
828615a1 EW |
108 | signal(SIGINT, saveint); |
109 | signal(SIGQUIT, savequit); | |
80741a9f KS |
110 | #endif |
111 | return(errs); | |
112 | } | |
113 | ||
114 | /* | |
115 | * Read up a header from standard input. | |
116 | * The source string has the preliminary contents to | |
117 | * be read. | |
118 | * | |
119 | */ | |
120 | ||
121 | char * | |
122 | readtty(pr, src) | |
123 | char pr[], src[]; | |
124 | { | |
338c4a5d | 125 | char ch, canonb[BUFSIZ]; |
828615a1 | 126 | int c; |
80741a9f | 127 | register char *cp, *cp2; |
001d60ad | 128 | int ttycont(); |
80741a9f | 129 | |
1b38f4e9 KS |
130 | fputs(pr, stdout); |
131 | fflush(stdout); | |
80741a9f KS |
132 | if (src != NOSTR && strlen(src) > BUFSIZ - 2) { |
133 | printf("too long to edit\n"); | |
134 | return(src); | |
135 | } | |
136 | #ifndef TIOCSTI | |
137 | if (src != NOSTR) | |
138 | cp = copy(src, canonb); | |
139 | else | |
140 | cp = copy("", canonb); | |
141 | fputs(canonb, stdout); | |
142 | fflush(stdout); | |
143 | #else | |
1b38f4e9 KS |
144 | cp = src == NOSTR ? "" : src; |
145 | while (c = *cp++) { | |
80741a9f KS |
146 | if (c == c_erase || c == c_kill) { |
147 | ch = '\\'; | |
148 | ioctl(0, TIOCSTI, &ch); | |
149 | } | |
338c4a5d SL |
150 | ch = c; |
151 | ioctl(0, TIOCSTI, &ch); | |
80741a9f KS |
152 | } |
153 | cp = canonb; | |
419b1e01 | 154 | *cp = 0; |
80741a9f | 155 | #endif |
1b38f4e9 KS |
156 | cp2 = cp; |
157 | while (cp2 < canonb + BUFSIZ) | |
158 | *cp2++ = 0; | |
159 | cp2 = cp; | |
160 | if (setjmp(rewrite)) | |
161 | goto redo; | |
828615a1 | 162 | signal(SIGCONT, ttycont); |
7bfe8da7 | 163 | clearerr(stdin); |
1b38f4e9 KS |
164 | while (cp2 < canonb + BUFSIZ) { |
165 | c = getc(stdin); | |
166 | if (c == EOF || c == '\n') | |
167 | break; | |
168 | *cp2++ = c; | |
169 | } | |
170 | *cp2 = 0; | |
828615a1 | 171 | signal(SIGCONT, SIG_DFL); |
1b38f4e9 KS |
172 | if (c == EOF && ferror(stdin) && hadcont) { |
173 | redo: | |
174 | hadcont = 0; | |
175 | cp = strlen(canonb) > 0 ? canonb : NOSTR; | |
176 | clearerr(stdin); | |
177 | return(readtty(pr, cp)); | |
178 | } | |
80741a9f | 179 | #ifndef TIOCSTI |
ea394d88 | 180 | if (cp == NOSTR || *cp == '\0') |
80741a9f | 181 | return(src); |
ea394d88 | 182 | cp2 = cp; |
80741a9f KS |
183 | if (!ttyset) |
184 | return(strlen(canonb) > 0 ? savestr(canonb) : NOSTR); | |
185 | while (*cp != '\0') { | |
186 | c = *cp++; | |
187 | if (c == c_erase) { | |
188 | if (cp2 == canonb) | |
189 | continue; | |
190 | if (cp2[-1] == '\\') { | |
191 | cp2[-1] = c; | |
192 | continue; | |
193 | } | |
194 | cp2--; | |
195 | continue; | |
196 | } | |
197 | if (c == c_kill) { | |
198 | if (cp2 == canonb) | |
199 | continue; | |
200 | if (cp2[-1] == '\\') { | |
201 | cp2[-1] = c; | |
202 | continue; | |
203 | } | |
204 | cp2 = canonb; | |
205 | continue; | |
206 | } | |
207 | *cp2++ = c; | |
208 | } | |
209 | *cp2 = '\0'; | |
210 | #endif | |
211 | if (equal("", canonb)) | |
212 | return(NOSTR); | |
213 | return(savestr(canonb)); | |
214 | } | |
1b38f4e9 KS |
215 | |
216 | /* | |
217 | * Receipt continuation. | |
218 | */ | |
828615a1 | 219 | /*ARGSUSED*/ |
1b38f4e9 KS |
220 | ttycont(s) |
221 | { | |
1b38f4e9 | 222 | hadcont++; |
1b38f4e9 KS |
223 | longjmp(rewrite, 1); |
224 | } |