install with -s
[unix-history] / usr / src / usr.bin / mail / tty.c
... / ...
CommitLineData
1#ifndef lint
2static char sccsid[] = "@(#)tty.c 2.7 (Berkeley) %G%";
3#endif
4
5/*
6 * Mail -- a mail program
7 *
8 * Generally useful tty stuff.
9 */
10
11#include "rcv.h"
12
13static int c_erase; /* Current erase char */
14static int c_kill; /* Current kill char */
15static int hadcont; /* Saw continue signal */
16static jmp_buf rewrite; /* Place to go when continued */
17#ifndef TIOCSTI
18static int ttyset; /* We must now do erase/kill */
19#endif
20
21/*
22 * Read all relevant header fields.
23 */
24
25grabh(hp, gflags)
26 struct header *hp;
27{
28 struct sgttyb ttybuf;
29 int ttycont(), signull();
30#ifndef TIOCSTI
31 int (*savesigs[2])();
32#endif
33 int (*savecont)();
34 register int s;
35 int errs;
36
37# ifdef VMUNIX
38 savecont = sigset(SIGCONT, signull);
39# endif VMUNIX
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++)
54 if ((savesigs[s-SIGINT] = sigset(s, SIG_IGN)) == SIG_DFL)
55 sigset(s, SIG_DFL);
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 }
93# ifdef VMUNIX
94 sigset(SIGCONT, savecont);
95# endif VMUNIX
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++)
102 sigset(s, savesigs[s-SIGINT]);
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
114char *
115readtty(pr, src)
116 char pr[], src[];
117{
118 char ch, canonb[BUFSIZ];
119 int c, signull();
120 register char *cp, *cp2;
121
122 fputs(pr, stdout);
123 fflush(stdout);
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
136 cp = src == NOSTR ? "" : src;
137 while (c = *cp++) {
138 if (c == c_erase || c == c_kill) {
139 ch = '\\';
140 ioctl(0, TIOCSTI, &ch);
141 }
142 ch = c;
143 ioctl(0, TIOCSTI, &ch);
144 }
145 cp = canonb;
146 *cp = 0;
147#endif
148 cp2 = cp;
149 while (cp2 < canonb + BUFSIZ)
150 *cp2++ = 0;
151 cp2 = cp;
152 if (setjmp(rewrite))
153 goto redo;
154# ifdef VMUNIX
155 sigset(SIGCONT, ttycont);
156# endif VMUNIX
157 clearerr(stdin);
158 while (cp2 < canonb + BUFSIZ) {
159 c = getc(stdin);
160 if (c == EOF || c == '\n')
161 break;
162 *cp2++ = c;
163 }
164 *cp2 = 0;
165# ifdef VMUNIX
166 sigset(SIGCONT, signull);
167# endif VMUNIX
168 if (c == EOF && ferror(stdin) && hadcont) {
169redo:
170 hadcont = 0;
171 cp = strlen(canonb) > 0 ? canonb : NOSTR;
172 clearerr(stdin);
173 return(readtty(pr, cp));
174 }
175#ifndef TIOCSTI
176 if (cp == NOSTR || *cp == '\0')
177 return(src);
178 cp2 = cp;
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}
211
212# ifdef VMUNIX
213/*
214 * Receipt continuation.
215 */
216ttycont(s)
217{
218
219 hadcont++;
220 longjmp(rewrite, 1);
221}
222# endif VMUNIX
223
224/*
225 * Null routine to satisfy
226 * silly system bug that denies us holding SIGCONT
227 */
228signull(s)
229{}