xref: /original-bsd/usr.bin/mail/tty.c (revision 552e81d8)
1 #
2 
3 /*
4  * Mail -- a mail program
5  *
6  * Generally useful tty stuff.
7  */
8 
9 #include "rcv.h"
10 #include <sgtty.h>
11 
12 static char *SccsId = "@(#)tty.c	1.1 10/08/80";
13 
14 static	int	c_erase;		/* Current erase char */
15 static	int	c_kill;			/* Current kill char */
16 #ifndef TIOCSTI
17 static	int	ttyset;			/* We must now do erase/kill */
18 #endif
19 
20 /*
21  * Read all relevant header fields.
22  */
23 
24 grabh(hp, gflags)
25 	struct header *hp;
26 {
27 	struct sgttyb ttybuf;
28 #ifndef TIOCSTI
29 	int (*savesigs[2])();
30 #endif
31 	register int s;
32 	int errs;
33 
34 	errs = 0;
35 #ifndef TIOCSTI
36 	ttyset = 0;
37 #endif
38 	if (gtty(fileno(stdin), &ttybuf) < 0) {
39 		perror("gtty");
40 		return(-1);
41 	}
42 	c_erase = ttybuf.sg_erase;
43 	c_kill = ttybuf.sg_kill;
44 #ifndef TIOCSTI
45 	ttybuf.sg_erase = 0;
46 	ttybuf.sg_kill = 0;
47 	for (s = SIGINT; s <= SIGQUIT; s++)
48 		if ((savesigs[s-SIGINT] = signal(s, SIG_IGN)) == SIG_DFL)
49 			signal(s, SIG_DFL);
50 #endif
51 	if (gflags & GTO) {
52 #ifndef TIOCSTI
53 		if (!ttyset && hp->h_to != NOSTR)
54 			ttyset++, stty(fileno(stdin), &ttybuf);
55 #endif
56 		hp->h_to = readtty("To: ", hp->h_to);
57 		if (hp->h_to != NOSTR)
58 			hp->h_seq++;
59 	}
60 	if (gflags & GSUBJECT) {
61 #ifndef TIOCSTI
62 		if (!ttyset && hp->h_subject != NOSTR)
63 			ttyset++, stty(fileno(stdin), &ttybuf);
64 #endif
65 		hp->h_subject = readtty("Subject: ", hp->h_subject);
66 		if (hp->h_subject != NOSTR)
67 			hp->h_seq++;
68 	}
69 	if (gflags & GCC) {
70 #ifndef TIOCSTI
71 		if (!ttyset && hp->h_cc != NOSTR)
72 			ttyset++, stty(fileno(stdin), &ttybuf);
73 #endif
74 		hp->h_cc = readtty("Cc: ", hp->h_cc);
75 		if (hp->h_cc != NOSTR)
76 			hp->h_seq++;
77 	}
78 	if (gflags & GBCC) {
79 #ifndef TIOCSTI
80 		if (!ttyset && hp->h_bcc != NOSTR)
81 			ttyset++, stty(fileno(stdin), &ttybuf);
82 #endif
83 		hp->h_bcc = readtty("Bcc: ", hp->h_bcc);
84 		if (hp->h_bcc != NOSTR)
85 			hp->h_seq++;
86 	}
87 #ifndef TIOCSTI
88 	ttybuf.sg_erase = c_erase;
89 	ttybuf.sg_kill = c_kill;
90 	if (ttyset)
91 		stty(fileno(stdin), &ttybuf);
92 	for (s = SIGINT; s <= SIGQUIT; s++)
93 		signal(s, savesigs[s-SIGINT]);
94 #endif
95 	return(errs);
96 }
97 
98 /*
99  * Read up a header from standard input.
100  * The source string has the preliminary contents to
101  * be read.
102  *
103  */
104 
105 char *
106 readtty(pr, src)
107 	char pr[], src[];
108 {
109 	char canonb[BUFSIZ];
110 	int c, ch;
111 	register char *cp, *cp2;
112 
113 	fputs(pr, stdout); fflush(stdout);
114 	if (src != NOSTR && strlen(src) > BUFSIZ - 2) {
115 		printf("too long to edit\n");
116 		return(src);
117 	}
118 #ifndef TIOCSTI
119 	if (src != NOSTR)
120 		cp = copy(src, canonb);
121 	else
122 		cp = copy("", canonb);
123 	fputs(canonb, stdout);
124 	fflush(stdout);
125 #else
126 	for (cp = src; c = *cp; cp++) {
127 		if (c == c_erase || c == c_kill) {
128 			ch = '\\';
129 			ioctl(0, TIOCSTI, &ch);
130 		}
131 		ioctl(0, TIOCSTI, &c);
132 	}
133 	cp = canonb;
134 #endif
135 	cp2 = fgets(cp, BUFSIZ - (cp - canonb), stdin);
136 	canonb[strlen(canonb) - 1] = '\0';
137 #ifndef TIOCSTI
138 	if (cp2 == NOSTR || *cp2 == '\0')
139 		return(src);
140 	cp = cp2;
141 	if (!ttyset)
142 		return(strlen(canonb) > 0 ? savestr(canonb) : NOSTR);
143 	while (*cp != '\0') {
144 		c = *cp++;
145 		if (c == c_erase) {
146 			if (cp2 == canonb)
147 				continue;
148 			if (cp2[-1] == '\\') {
149 				cp2[-1] = c;
150 				continue;
151 			}
152 			cp2--;
153 			continue;
154 		}
155 		if (c == c_kill) {
156 			if (cp2 == canonb)
157 				continue;
158 			if (cp2[-1] == '\\') {
159 				cp2[-1] = c;
160 				continue;
161 			}
162 			cp2 = canonb;
163 			continue;
164 		}
165 		*cp2++ = c;
166 	}
167 	*cp2 = '\0';
168 #endif
169 	if (equal("", canonb))
170 		return(NOSTR);
171 	return(savestr(canonb));
172 }
173