Commit | Line | Data |
---|---|---|
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 | 12 | static char *SccsId = "@(#)tty.c 1.2 %G%"; |
80741a9f KS |
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; | |
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 | } |