1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: static char *sccsid = "@(#)tty.c 5.2 (Berkeley) 6/21/85";
9: #endif not lint
10:
11: /*
12: * Mail -- a mail program
13: *
14: * Generally useful tty stuff.
15: */
16:
17: #include "rcv.h"
18:
19: static int c_erase; /* Current erase char */
20: static int c_kill; /* Current kill char */
21: static int hadcont; /* Saw continue signal */
22: static jmp_buf rewrite; /* Place to go when continued */
23: #ifndef TIOCSTI
24: static int ttyset; /* We must now do erase/kill */
25: #endif
26:
27: /*
28: * Read all relevant header fields.
29: */
30:
31: grabh(hp, gflags)
32: struct header *hp;
33: {
34: struct sgttyb ttybuf;
35: int ttycont(), signull();
36: #ifndef TIOCSTI
37: int (*savesigs[2])();
38: #endif
39: int (*savecont)();
40: register int s;
41: int errs;
42:
43: # ifdef VMUNIX
44: savecont = sigset(SIGCONT, signull);
45: # endif VMUNIX
46: errs = 0;
47: #ifndef TIOCSTI
48: ttyset = 0;
49: #endif
50: if (gtty(fileno(stdin), &ttybuf) < 0) {
51: perror("gtty");
52: return(-1);
53: }
54: c_erase = ttybuf.sg_erase;
55: c_kill = ttybuf.sg_kill;
56: #ifndef TIOCSTI
57: ttybuf.sg_erase = 0;
58: ttybuf.sg_kill = 0;
59: for (s = SIGINT; s <= SIGQUIT; s++)
60: if ((savesigs[s-SIGINT] = sigset(s, SIG_IGN)) == SIG_DFL)
61: sigset(s, SIG_DFL);
62: #endif
63: if (gflags & GTO) {
64: #ifndef TIOCSTI
65: if (!ttyset && hp->h_to != NOSTR)
66: ttyset++, stty(fileno(stdin), &ttybuf);
67: #endif
68: hp->h_to = readtty("To: ", hp->h_to);
69: if (hp->h_to != NOSTR)
70: hp->h_seq++;
71: }
72: if (gflags & GSUBJECT) {
73: #ifndef TIOCSTI
74: if (!ttyset && hp->h_subject != NOSTR)
75: ttyset++, stty(fileno(stdin), &ttybuf);
76: #endif
77: hp->h_subject = readtty("Subject: ", hp->h_subject);
78: if (hp->h_subject != NOSTR)
79: hp->h_seq++;
80: }
81: if (gflags & GCC) {
82: #ifndef TIOCSTI
83: if (!ttyset && hp->h_cc != NOSTR)
84: ttyset++, stty(fileno(stdin), &ttybuf);
85: #endif
86: hp->h_cc = readtty("Cc: ", hp->h_cc);
87: if (hp->h_cc != NOSTR)
88: hp->h_seq++;
89: }
90: if (gflags & GBCC) {
91: #ifndef TIOCSTI
92: if (!ttyset && hp->h_bcc != NOSTR)
93: ttyset++, stty(fileno(stdin), &ttybuf);
94: #endif
95: hp->h_bcc = readtty("Bcc: ", hp->h_bcc);
96: if (hp->h_bcc != NOSTR)
97: hp->h_seq++;
98: }
99: # ifdef VMUNIX
100: sigset(SIGCONT, savecont);
101: # endif VMUNIX
102: #ifndef TIOCSTI
103: ttybuf.sg_erase = c_erase;
104: ttybuf.sg_kill = c_kill;
105: if (ttyset)
106: stty(fileno(stdin), &ttybuf);
107: for (s = SIGINT; s <= SIGQUIT; s++)
108: sigset(s, savesigs[s-SIGINT]);
109: #endif
110: return(errs);
111: }
112:
113: /*
114: * Read up a header from standard input.
115: * The source string has the preliminary contents to
116: * be read.
117: *
118: */
119:
120: char *
121: readtty(pr, src)
122: char pr[], src[];
123: {
124: char ch, canonb[BUFSIZ];
125: int c, signull();
126: register char *cp, *cp2;
127:
128: fputs(pr, stdout);
129: fflush(stdout);
130: if (src != NOSTR && strlen(src) > BUFSIZ - 2) {
131: printf("too long to edit\n");
132: return(src);
133: }
134: #ifndef TIOCSTI
135: if (src != NOSTR)
136: cp = copy(src, canonb);
137: else
138: cp = copy("", canonb);
139: fputs(canonb, stdout);
140: fflush(stdout);
141: #else
142: cp = src == NOSTR ? "" : src;
143: while (c = *cp++) {
144: if (c == c_erase || c == c_kill) {
145: ch = '\\';
146: ioctl(0, TIOCSTI, &ch);
147: }
148: ch = c;
149: ioctl(0, TIOCSTI, &ch);
150: }
151: cp = canonb;
152: *cp = 0;
153: #endif
154: cp2 = cp;
155: while (cp2 < canonb + BUFSIZ)
156: *cp2++ = 0;
157: cp2 = cp;
158: if (setjmp(rewrite))
159: goto redo;
160: # ifdef VMUNIX
161: sigset(SIGCONT, ttycont);
162: # endif VMUNIX
163: clearerr(stdin);
164: while (cp2 < canonb + BUFSIZ) {
165: c = getc(stdin);
166: if (c == EOF || c == '\n')
167: break;
168: *cp2++ = c;
169: }
170: *cp2 = 0;
171: # ifdef VMUNIX
172: sigset(SIGCONT, signull);
173: # endif VMUNIX
174: if (c == EOF && ferror(stdin) && hadcont) {
175: redo:
176: hadcont = 0;
177: cp = strlen(canonb) > 0 ? canonb : NOSTR;
178: clearerr(stdin);
179: return(readtty(pr, cp));
180: }
181: #ifndef TIOCSTI
182: if (cp == NOSTR || *cp == '\0')
183: return(src);
184: cp2 = cp;
185: if (!ttyset)
186: return(strlen(canonb) > 0 ? savestr(canonb) : NOSTR);
187: while (*cp != '\0') {
188: c = *cp++;
189: if (c == c_erase) {
190: if (cp2 == canonb)
191: continue;
192: if (cp2[-1] == '\\') {
193: cp2[-1] = c;
194: continue;
195: }
196: cp2--;
197: continue;
198: }
199: if (c == c_kill) {
200: if (cp2 == canonb)
201: continue;
202: if (cp2[-1] == '\\') {
203: cp2[-1] = c;
204: continue;
205: }
206: cp2 = canonb;
207: continue;
208: }
209: *cp2++ = c;
210: }
211: *cp2 = '\0';
212: #endif
213: if (equal("", canonb))
214: return(NOSTR);
215: return(savestr(canonb));
216: }
217:
218: # ifdef VMUNIX
219: /*
220: * Receipt continuation.
221: */
222: ttycont(s)
223: {
224:
225: hadcont++;
226: longjmp(rewrite, 1);
227: }
228: # endif VMUNIX
229:
230: /*
231: * Null routine to satisfy
232: * silly system bug that denies us holding SIGCONT
233: */
234: signull(s)
235: {}
Defined functions
grabh
defined in line
31; used 3 times
Defined variables
sccsid
defined in line
8;
never used
ttyset
defined in line
24; used 11 times