|
|
1.1 root 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:
12: static int c_erase; /* Current erase char */
13: static int c_kill; /* Current kill char */
14: #ifndef TIOCSTI
15: static int ttyset; /* We must now do erase/kill */
16: #endif
17:
18: /*
19: * Read all relevant header fields.
20: */
21:
22: grabh(hp, gflags)
23: struct header *hp;
24: {
25: struct sgttyb ttybuf;
26: #ifndef TIOCSTI
27: int (*savesigs[2])();
28: #endif
29: register int s;
30: int errs;
31:
32: errs = 0;
33: #ifndef TIOCSTI
34: ttyset = 0;
35: #endif
36: if (gtty(fileno(stdin), &ttybuf) < 0) {
37: perror("gtty");
38: return(-1);
39: }
40: c_erase = ttybuf.sg_erase;
41: c_kill = ttybuf.sg_kill;
42: #ifndef TIOCSTI
43: ttybuf.sg_erase = 0;
44: ttybuf.sg_kill = 0;
45: for (s = SIGINT; s <= SIGQUIT; s++)
46: if ((savesigs[s-SIGINT] = signal(s, SIG_IGN)) == SIG_DFL)
47: signal(s, SIG_DFL);
48: #endif
49: if (gflags & GTO) {
50: #ifndef TIOCSTI
51: if (!ttyset && hp->h_to != NOSTR)
52: ttyset++, stty(fileno(stdin), &ttybuf);
53: #endif
54: hp->h_to = readtty("To: ", hp->h_to);
55: if (hp->h_to != NOSTR)
56: hp->h_seq++;
57: }
58: if (gflags & GSUBJECT) {
59: #ifndef TIOCSTI
60: if (!ttyset && hp->h_subject != NOSTR)
61: ttyset++, stty(fileno(stdin), &ttybuf);
62: #endif
63: hp->h_subject = readtty("Subject: ", hp->h_subject);
64: if (hp->h_subject != NOSTR)
65: hp->h_seq++;
66: }
67: if (gflags & GCC) {
68: #ifndef TIOCSTI
69: if (!ttyset && hp->h_cc != NOSTR)
70: ttyset++, stty(fileno(stdin), &ttybuf);
71: #endif
72: hp->h_cc = readtty("Cc: ", hp->h_cc);
73: if (hp->h_cc != NOSTR)
74: hp->h_seq++;
75: }
76: if (gflags & GBCC) {
77: #ifndef TIOCSTI
78: if (!ttyset && hp->h_bcc != NOSTR)
79: ttyset++, stty(fileno(stdin), &ttybuf);
80: #endif
81: hp->h_bcc = readtty("Bcc: ", hp->h_bcc);
82: if (hp->h_bcc != NOSTR)
83: hp->h_seq++;
84: }
85: #ifndef TIOCSTI
86: ttybuf.sg_erase = c_erase;
87: ttybuf.sg_kill = c_kill;
88: if (ttyset)
89: stty(fileno(stdin), &ttybuf);
90: for (s = SIGINT; s <= SIGQUIT; s++)
91: signal(s, savesigs[s-SIGINT]);
92: #endif
93: return(errs);
94: }
95:
96: /*
97: * Read up a header from standard input.
98: * The source string has the preliminary contents to
99: * be read.
100: *
101: */
102:
103: char *
104: readtty(pr, src)
105: char pr[], src[];
106: {
107: char canonb[BUFSIZ];
108: int c, ch;
109: register char *cp, *cp2;
110:
111: fputs(pr, stdout); fflush(stdout);
112: if (src != NOSTR && strlen(src) > BUFSIZ - 2) {
113: printf("too long to edit\n");
114: return(src);
115: }
116: #ifndef TIOCSTI
117: if (src != NOSTR)
118: cp = copy(src, canonb);
119: else
120: cp = copy("", canonb);
121: fputs(canonb, stdout);
122: fflush(stdout);
123: #else
124: for (cp = src; c = *cp; cp++) {
125: if (c == c_erase || c == c_kill) {
126: ch = '\\';
127: ioctl(0, TIOCSTI, &ch);
128: }
129: ioctl(0, TIOCSTI, &c);
130: }
131: cp = canonb;
132: #endif
133: cp2 = fgets(cp, BUFSIZ - (cp - canonb), stdin);
134: canonb[strlen(canonb) - 1] = '\0';
135: #ifndef TIOCSTI
136: if (cp2 == NOSTR || *cp2 == '\0')
137: return(src);
138: cp = cp2;
139: if (!ttyset)
140: return(strlen(canonb) > 0 ? savestr(canonb) : NOSTR);
141: while (*cp != '\0') {
142: c = *cp++;
143: if (c == c_erase) {
144: if (cp2 == canonb)
145: continue;
146: if (cp2[-1] == '\\') {
147: cp2[-1] = c;
148: continue;
149: }
150: cp2--;
151: continue;
152: }
153: if (c == c_kill) {
154: if (cp2 == canonb)
155: continue;
156: if (cp2[-1] == '\\') {
157: cp2[-1] = c;
158: continue;
159: }
160: cp2 = canonb;
161: continue;
162: }
163: *cp2++ = c;
164: }
165: *cp2 = '\0';
166: #endif
167: if (equal("", canonb))
168: return(NOSTR);
169: return(savestr(canonb));
170: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.