|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
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.
11: */
12:
13: #ifdef notdef
14: static char sccsid[] = "@(#)tty.c 5.5 (Berkeley) 2/18/88";
15: #endif /* notdef */
16:
17: /*
18: * Mail -- a mail program
19: *
20: * Generally useful tty stuff.
21: */
22:
23: #include "rcv.h"
24:
25: static int c_erase; /* Current erase char */
26: static int c_kill; /* Current kill char */
27: static int hadcont; /* Saw continue signal */
28: static jmp_buf rewrite; /* Place to go when continued */
29: #ifndef TIOCSTI
30: static int ttyset; /* We must now do erase/kill */
31: #endif
32:
33: /*
34: * Read all relevant header fields.
35: */
36:
37: grabh(hp, gflags)
38: struct header *hp;
39: {
40: struct sgttyb ttybuf;
41: #ifndef TIOCSTI
42: int (*saveint)(), (*savequit)();
43: #endif
44: int (*savecont)();
45: int errs;
46:
47: savecont = signal(SIGCONT, SIG_DFL);
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;
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);
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: }
102: signal(SIGCONT, savecont);
103: #ifndef TIOCSTI
104: ttybuf.sg_erase = c_erase;
105: ttybuf.sg_kill = c_kill;
106: if (ttyset)
107: stty(fileno(stdin), &ttybuf);
108: signal(SIGINT, saveint);
109: signal(SIGQUIT, savequit);
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:
121: char *
122: readtty(pr, src)
123: char pr[], src[];
124: {
125: char ch, canonb[BUFSIZ];
126: int c;
127: register char *cp, *cp2;
128: int ttycont();
129:
130: fputs(pr, stdout);
131: fflush(stdout);
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
144: cp = src == NOSTR ? "" : src;
145: while (c = *cp++) {
146: if (c == c_erase || c == c_kill) {
147: ch = '\\';
148: ioctl(0, TIOCSTI, &ch);
149: }
150: ch = c;
151: ioctl(0, TIOCSTI, &ch);
152: }
153: cp = canonb;
154: *cp = 0;
155: #endif
156: cp2 = cp;
157: while (cp2 < canonb + BUFSIZ)
158: *cp2++ = 0;
159: cp2 = cp;
160: if (setjmp(rewrite))
161: goto redo;
162: signal(SIGCONT, ttycont);
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: signal(SIGCONT, SIG_DFL);
172: if (c == EOF && ferror(stdin) && hadcont) {
173: redo:
174: hadcont = 0;
175: cp = strlen(canonb) > 0 ? canonb : NOSTR;
176: clearerr(stdin);
177: return(readtty(pr, cp));
178: }
179: #ifndef TIOCSTI
180: if (cp == NOSTR || *cp == '\0')
181: return(src);
182: cp2 = cp;
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: }
215:
216: /*
217: * Receipt continuation.
218: */
219: /*ARGSUSED*/
220: ttycont(s)
221: {
222: hadcont++;
223: longjmp(rewrite, 1);
224: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.