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