use shell="" instead of shell=none for no shell,
[unix-history] / usr / src / usr.bin / mail / tty.c
CommitLineData
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
14static 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
25static int c_erase; /* Current erase char */
26static int c_kill; /* Current kill char */
1b38f4e9
KS
27static int hadcont; /* Saw continue signal */
28static jmp_buf rewrite; /* Place to go when continued */
80741a9f
KS
29#ifndef TIOCSTI
30static int ttyset; /* We must now do erase/kill */
31#endif
32
33/*
34 * Read all relevant header fields.
35 */
36
37grabh(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
121char *
122readtty(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) {
173redo:
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
220ttycont(s)
221{
1b38f4e9 222 hadcont++;
1b38f4e9
KS
223 longjmp(rewrite, 1);
224}