added call to inithost() if GETHOST is defined
[unix-history] / usr / src / usr.bin / 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
6c85fa2a 11static char *SccsId = "@(#)tty.c 2.3 %G%";
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{
118 char canonb[BUFSIZ];
1b38f4e9 119 int c, ch, 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 }
142 ioctl(0, TIOCSTI, &c);
143 }
144 cp = canonb;
419b1e01 145 *cp = 0;
80741a9f 146#endif
1b38f4e9
KS
147 cp2 = cp;
148 while (cp2 < canonb + BUFSIZ)
149 *cp2++ = 0;
150 cp2 = cp;
151 if (setjmp(rewrite))
152 goto redo;
ea394d88 153# ifdef VMUNIX
1b38f4e9 154 sigset(SIGCONT, ttycont);
ea394d88 155# endif VMUNIX
1b38f4e9
KS
156 while (cp2 < canonb + BUFSIZ) {
157 c = getc(stdin);
158 if (c == EOF || c == '\n')
159 break;
160 *cp2++ = c;
161 }
162 *cp2 = 0;
ea394d88 163# ifdef VMUNIX
1b38f4e9 164 sigset(SIGCONT, signull);
ea394d88 165# endif VMUNIX
1b38f4e9
KS
166 if (c == EOF && ferror(stdin) && hadcont) {
167redo:
168 hadcont = 0;
169 cp = strlen(canonb) > 0 ? canonb : NOSTR;
170 clearerr(stdin);
171 return(readtty(pr, cp));
172 }
80741a9f 173#ifndef TIOCSTI
ea394d88 174 if (cp == NOSTR || *cp == '\0')
80741a9f 175 return(src);
ea394d88 176 cp2 = cp;
80741a9f
KS
177 if (!ttyset)
178 return(strlen(canonb) > 0 ? savestr(canonb) : NOSTR);
179 while (*cp != '\0') {
180 c = *cp++;
181 if (c == c_erase) {
182 if (cp2 == canonb)
183 continue;
184 if (cp2[-1] == '\\') {
185 cp2[-1] = c;
186 continue;
187 }
188 cp2--;
189 continue;
190 }
191 if (c == c_kill) {
192 if (cp2 == canonb)
193 continue;
194 if (cp2[-1] == '\\') {
195 cp2[-1] = c;
196 continue;
197 }
198 cp2 = canonb;
199 continue;
200 }
201 *cp2++ = c;
202 }
203 *cp2 = '\0';
204#endif
205 if (equal("", canonb))
206 return(NOSTR);
207 return(savestr(canonb));
208}
1b38f4e9 209
ea394d88 210# ifdef VMUNIX
1b38f4e9
KS
211/*
212 * Receipt continuation.
213 */
214ttycont(s)
215{
216
217 hadcont++;
218 sigrelse(SIGCONT);
219 longjmp(rewrite, 1);
220}
ea394d88 221# endif VMUNIX
1b38f4e9
KS
222
223/*
224 * Null routine to satisfy
225 * silly system bug that denies us holding SIGCONT
226 */
227signull(s)
228{}