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