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 | |
6 | * provided that this notice is preserved and that due credit is given | |
7 | * to the University of California at Berkeley. The name of the University | |
8 | * may not be used to endorse or promote products derived from this | |
9 | * software without specific prior written permission. This software | |
10 | * is provided ``as is'' without express or implied warranty. | |
761330fe DF |
11 | */ |
12 | ||
0c5f72fb KB |
13 | #ifdef notdef |
14 | static char sccsid[] = "@(#)tty.c 5.5 (Berkeley) %G%"; | |
15 | #endif /* notdef */ | |
80741a9f KS |
16 | |
17 | /* | |
18 | * Mail -- a mail program | |
19 | * | |
20 | * Generally useful tty stuff. | |
21 | */ | |
22 | ||
23 | #include "rcv.h" | |
80741a9f | 24 | |
80741a9f KS |
25 | static int c_erase; /* Current erase char */ |
26 | static int c_kill; /* Current kill char */ | |
1b38f4e9 KS |
27 | static int hadcont; /* Saw continue signal */ |
28 | static jmp_buf rewrite; /* Place to go when continued */ | |
80741a9f KS |
29 | #ifndef TIOCSTI |
30 | static int ttyset; /* We must now do erase/kill */ | |
31 | #endif | |
32 | ||
33 | /* | |
34 | * Read all relevant header fields. | |
35 | */ | |
36 | ||
37 | grabh(hp, gflags) | |
38 | struct header *hp; | |
39 | { | |
40 | struct sgttyb ttybuf; | |
41 | #ifndef TIOCSTI | |
828615a1 | 42 | int (*saveint)(), (*savequit)(); |
80741a9f | 43 | #endif |
1b38f4e9 | 44 | int (*savecont)(); |
80741a9f KS |
45 | int errs; |
46 | ||
828615a1 | 47 | savecont = signal(SIGCONT, SIG_DFL); |
80741a9f KS |
48 | errs = 0; |
49 | #ifndef TIOCSTI | |
50 | ttyset = 0; | |
51 | #endif | |
52 | if (gtty(fileno(stdin), &ttybuf) < 0) { | |
53 | perror("gtty"); | |
54 | return(-1); | |
55 | } | |
56 | c_erase = ttybuf.sg_erase; | |
57 | c_kill = ttybuf.sg_kill; | |
58 | #ifndef TIOCSTI | |
59 | ttybuf.sg_erase = 0; | |
60 | ttybuf.sg_kill = 0; | |
828615a1 EW |
61 | if ((saveint = signal(SIGINT, SIG_IGN)) == SIG_DFL) |
62 | signal(SIGINT, SIG_DFL); | |
63 | if ((savequit = signal(SIGQUIT, SIG_IGN)) == SIG_DFL) | |
64 | signal(SIGQUIT, SIG_DFL); | |
80741a9f KS |
65 | #endif |
66 | if (gflags & GTO) { | |
67 | #ifndef TIOCSTI | |
68 | if (!ttyset && hp->h_to != NOSTR) | |
69 | ttyset++, stty(fileno(stdin), &ttybuf); | |
70 | #endif | |
71 | hp->h_to = readtty("To: ", hp->h_to); | |
72 | if (hp->h_to != NOSTR) | |
73 | hp->h_seq++; | |
74 | } | |
75 | if (gflags & GSUBJECT) { | |
76 | #ifndef TIOCSTI | |
77 | if (!ttyset && hp->h_subject != NOSTR) | |
78 | ttyset++, stty(fileno(stdin), &ttybuf); | |
79 | #endif | |
80 | hp->h_subject = readtty("Subject: ", hp->h_subject); | |
81 | if (hp->h_subject != NOSTR) | |
82 | hp->h_seq++; | |
83 | } | |
84 | if (gflags & GCC) { | |
85 | #ifndef TIOCSTI | |
86 | if (!ttyset && hp->h_cc != NOSTR) | |
87 | ttyset++, stty(fileno(stdin), &ttybuf); | |
88 | #endif | |
89 | hp->h_cc = readtty("Cc: ", hp->h_cc); | |
90 | if (hp->h_cc != NOSTR) | |
91 | hp->h_seq++; | |
92 | } | |
93 | if (gflags & GBCC) { | |
94 | #ifndef TIOCSTI | |
95 | if (!ttyset && hp->h_bcc != NOSTR) | |
96 | ttyset++, stty(fileno(stdin), &ttybuf); | |
97 | #endif | |
98 | hp->h_bcc = readtty("Bcc: ", hp->h_bcc); | |
99 | if (hp->h_bcc != NOSTR) | |
100 | hp->h_seq++; | |
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 | } |