BSD 4_1c_2 release
[unix-history] / usr / src / ucb / Mail / tty.c
CommitLineData
80741a9f
KS
1#
2
3/*
4 * Mail -- a mail program
5 *
6 * Generally useful tty stuff.
7 */
8
9#include "rcv.h"
80741a9f 10
e804469b 11static char *SccsId = "@(#)tty.c 2.4 2/9/83";
80741a9f
KS
12
13static int c_erase; /* Current erase char */
14static int c_kill; /* Current kill char */
1b38f4e9
KS
15static int hadcont; /* Saw continue signal */
16static jmp_buf rewrite; /* Place to go when continued */
80741a9f
KS
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;
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
114char *
115readtty(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
1b38f4e9
KS
157 while (cp2 < canonb + BUFSIZ) {
158 c = getc(stdin);
159 if (c == EOF || c == '\n')
160 break;
161 *cp2++ = c;
162 }
163 *cp2 = 0;
ea394d88 164# ifdef VMUNIX
1b38f4e9 165 sigset(SIGCONT, signull);
ea394d88 166# endif VMUNIX
1b38f4e9
KS
167 if (c == EOF && ferror(stdin) && hadcont) {
168redo:
169 hadcont = 0;
170 cp = strlen(canonb) > 0 ? canonb : NOSTR;
171 clearerr(stdin);
172 return(readtty(pr, cp));
173 }
80741a9f 174#ifndef TIOCSTI
ea394d88 175 if (cp == NOSTR || *cp == '\0')
80741a9f 176 return(src);
ea394d88 177 cp2 = cp;
80741a9f
KS
178 if (!ttyset)
179 return(strlen(canonb) > 0 ? savestr(canonb) : NOSTR);
180 while (*cp != '\0') {
181 c = *cp++;
182 if (c == c_erase) {
183 if (cp2 == canonb)
184 continue;
185 if (cp2[-1] == '\\') {
186 cp2[-1] = c;
187 continue;
188 }
189 cp2--;
190 continue;
191 }
192 if (c == c_kill) {
193 if (cp2 == canonb)
194 continue;
195 if (cp2[-1] == '\\') {
196 cp2[-1] = c;
197 continue;
198 }
199 cp2 = canonb;
200 continue;
201 }
202 *cp2++ = c;
203 }
204 *cp2 = '\0';
205#endif
206 if (equal("", canonb))
207 return(NOSTR);
208 return(savestr(canonb));
209}
1b38f4e9 210
ea394d88 211# ifdef VMUNIX
1b38f4e9
KS
212/*
213 * Receipt continuation.
214 */
215ttycont(s)
216{
217
218 hadcont++;
219 sigrelse(SIGCONT);
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 */
228signull(s)
229{}