more careful about clobbering the supposed newline at the end of the string
[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"
10#include <sgtty.h>
11
419b1e01 12static char *SccsId = "@(#)tty.c 1.2 %G%";
80741a9f
KS
13
14static int c_erase; /* Current erase char */
15static int c_kill; /* Current kill char */
16#ifndef TIOCSTI
17static int ttyset; /* We must now do erase/kill */
18#endif
19
20/*
21 * Read all relevant header fields.
22 */
23
24grabh(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
105char *
106readtty(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;
419b1e01 134 *cp = 0;
80741a9f
KS
135#endif
136 cp2 = fgets(cp, BUFSIZ - (cp - canonb), stdin);
419b1e01
KS
137 cp = index(canonb, '\n');
138 if (cp != NOSTR)
139 *cp = 0;
80741a9f
KS
140#ifndef TIOCSTI
141 if (cp2 == NOSTR || *cp2 == '\0')
142 return(src);
143 cp = cp2;
144 if (!ttyset)
145 return(strlen(canonb) > 0 ? savestr(canonb) : NOSTR);
146 while (*cp != '\0') {
147 c = *cp++;
148 if (c == c_erase) {
149 if (cp2 == canonb)
150 continue;
151 if (cp2[-1] == '\\') {
152 cp2[-1] = c;
153 continue;
154 }
155 cp2--;
156 continue;
157 }
158 if (c == c_kill) {
159 if (cp2 == canonb)
160 continue;
161 if (cp2[-1] == '\\') {
162 cp2[-1] = c;
163 continue;
164 }
165 cp2 = canonb;
166 continue;
167 }
168 *cp2++ = c;
169 }
170 *cp2 = '\0';
171#endif
172 if (equal("", canonb))
173 return(NOSTR);
174 return(savestr(canonb));
175}