|
|
1.1 root 1: /*
2: * Perform Standard I/O functions for
3: * a remote process using the dkxqt protocol
4: */
5: static char SCCSID[] = "@(#)dkxstdio.c 2.1 DKHOST 84/08/10";
6:
7: #include "remfio.h"
8: #include <errno.h>
9: #include <signal.h>
10: #include "sysexits.h"
11: #include <setjmp.h>
12: #include <sys/ttyio.h>
13: #include "Vtermio.h"
14:
15: #define F_SGTTYB "bbbbs"
16: #define F_TERMIO "ssssbbbbbbbbb"
17: #define FL_SGTTYB 6
18: #define FL_TERMIO 17
19:
20: static char sb[REMSIZE], rb[REMSIZE];
21:
22: static struct rem_req r;
23: static struct rem_reply s;
24:
25: extern int dkverbose;
26: extern int errno ;
27:
28: #define BSIZE 1024
29:
30: static char buf[BSIZE];
31:
32: static union {
33: struct sgttyb ioctl_sgttyb ;
34: struct Vtermio ioctl_termio ;
35: } ioctl_buf ;
36:
37: static short sig;
38: static short uSIG;
39: static int exitcode;
40:
41: static jmp_buf wayout;
42: static struct sgttyb origterm;
43: struct sgttyb newterm ;
44: static int otfd;
45: static int eofmark;
46:
47: extern dtSIG(), dtuSIG();
48:
49: dkxstdio(fd)
50: {
51: register int n;
52: int (*intwas)(), (*quitwas)(), (*usr1was)();
53:
54: exitcode = -EX_IOERR; /* in case other side hangs up unexpectedly */
55:
56: eofmark = 0;
57:
58: if((intwas = signal(SIGINT, SIG_IGN)) != SIG_IGN)
59: signal(SIGINT, dtSIG);
60: if((quitwas = signal(SIGQUIT, SIG_IGN)) != SIG_IGN)
61: signal(SIGQUIT, dtSIG);
62:
63:
64: otfd = -1;
65:
66:
67: for(n = 0; n < 3; n++)
68: if (ioctl (n, TIOCGETP, &origterm) == 0) {
69: otfd = n;
70: break;
71: }
72:
73: if(setjmp(wayout)){
74: if(otfd >= 0)
75: ioctl (otfd, TIOCSETP, &origterm) ;
76:
77:
78: signal(SIGQUIT, quitwas);
79: signal(SIGINT, intwas);
80: return(exitcode);
81: }
82:
83: while (1) {
84: errno = 0 ;
85: uSIG = 0 ;
86: if ((read(fd, rb, REMSIZE) != REMSIZE) && (errno == 0)) {
87: if (sig == 0)
88: longjmp(wayout, 1);
89: else
90: errno = EINTR ;
91: }
92: if (errno == 0) {
93: dkfcanon(F_REMREQ, rb, &r) ;
94: switch(r.r_type) {
95: case RREAD:
96: dtread(fd) ;
97: break ;
98: case RWRITE:
99: dtwrite(fd) ;
100: break ;
101: case RIOCTL:
102: dtioctl(fd) ;
103: if(eofmark)
104: longjmp(wayout, 1);
105: break ;
106: case RCANCEL:
107: break ;
108: default:
109: s.s_length = 0 ;
110: s.s_error = EINVAL ;
111: s.s_type = r.r_type ;
112: dktcanon(F_REMREPLY, &s, sb) ;
113: write(fd, sb, REMSIZE) ;
114: }
115: } else if (sig) {
116: dtssig(fd) ;
117: } else {
118: if(dkverbose)
119: perror("dkxstdio: dk read") ;
120: exitcode = -EX_PROTOCOL;
121: longjmp(wayout, 1);
122: }
123: }
124: }
125:
126: static
127: dtread(fd)
128: {
129: register int rfd, temp;
130: register unsigned len, rlen;
131:
132: errno = 0 ;
133: len = r.r_var.rread.r_count ;
134: if (len > BSIZE)
135: len = BSIZE ;
136: rfd = (r.r_file < 3) ? r.r_file : 0;
137: rlen = read(rfd, buf, len);
138: if (sig)
139: errno = EINTR ;
140: temp = errno ;
141: if ((int) rlen == -1)
142: rlen = 0 ;
143: if (sig)
144: dtssig(fd) ;
145: s.s_length = rlen ;
146: s.s_type = RREAD ;
147: s.s_error = temp ;
148: if (rlen == len && len != r.r_var.rread.r_count && temp == 0)
149: s.s_resid = r.r_var.rread.r_count - len ;
150: else
151: s.s_resid = 0 ;
152: dktcanon(F_REMREPLY, &s, sb) ;
153: write(fd, sb, REMSIZE) ;
154: if (rlen)
155: write(fd, buf, rlen) ;
156: }
157:
158: static
159: dtwrite(fd)
160: {
161: register int rfd, temp;
162: register unsigned len, rlen;
163: unsigned slen;
164:
165: slen = r.r_length ;
166: while (len = r.r_length) {
167: errno = 0 ;
168: if (len > BSIZE)
169: len = BSIZE ;
170: rlen = read(fd, buf, len) ;
171: if (rlen != len) {
172: if(dkverbose)
173: perror("dtwrite: dk read error") ;
174: exitcode = -EX_PROTOCOL;
175: longjmp(wayout, 1);
176: }
177: r.r_length -= len ;
178: rfd = (r.r_file < 3) ? r.r_file : 1;
179: write(rfd, buf, len);
180: if (sig) {
181: dtssig(fd) ;
182: dtdiscard(fd, r.r_length) ;
183: r.r_length = 0 ;
184: }
185: }
186: s.s_length = 0 ;
187: s.s_type = RWRITE ;
188: s.s_error = 0 ;
189: s.s_count = slen ;
190: dktcanon(F_REMREPLY, &s, sb) ;
191: write(fd, sb, REMSIZE) ;
192: }
193:
194: static
195: dtioctl(fd)
196: {
197: short need ;
198: short give ;
199: int narg ;
200: char * fmt ;
201: short fmtl ;
202:
203: fmtl = need = give = 0 ;
204: narg = r.r_var.rioctl.r_arg ;
205: switch (r.r_var.rioctl.r_cmd) {
206: case TCSETAF:
207: case TCSETAW:
208: case TCSETA:
209: need = sizeof (struct Vtermio) ;
210: fmt = F_TERMIO ;
211: fmtl = FL_TERMIO ;
212: break ;
213: case TIOCSETP:
214: need = sizeof(struct sgttyb) ;
215: fmt = F_SGTTYB ;
216: fmtl = FL_SGTTYB ;
217: break ;
218: case TCGETA:
219: give = sizeof(struct Vtermio) ;
220: fmt = F_TERMIO ;
221: fmtl = FL_TERMIO ;
222: break ;
223: case TIOCGETP:
224: give = sizeof(struct sgttyb) ;
225: fmt = F_SGTTYB ;
226: fmtl = FL_SGTTYB ;
227: break ;
228: case (('D'<<8)|'T'):
229: exitcode = narg;
230: eofmark++;
231: }
232: if (need || give)
233: narg = (int)&ioctl_buf ;
234: if (need > r.r_length) {
235: dtdiscard(fd, r.r_length) ;
236: s.s_length = fmtl ;
237: s.s_type = RIOCTL ;
238: s.s_error = 0 ;
239: s.s_count = need ;
240: s.s_resid = fmtl ;
241: dktcanon(F_REMREPLY, &s, sb) ;
242: write(fd, sb, REMSIZE) ;
243: if (fmtl) {
244: write(fd, fmt, fmtl) ;
245: }
246: return ;
247: }
248: if (need) {
249: read(fd, &ioctl_buf, need) ;
250: dkfcanon(fmt, &ioctl_buf, &ioctl_buf) ;
251: }
252: dtdiscard(fd, r.r_length - need) ;
253: errno = 0 ;
254: if(!eofmark) {
255: ioctl ((r.r_file <= 2)?r.r_file:0, TIOCGETP, &newterm) ;
256: switch(r.r_var.rioctl.r_cmd) {
257: case TCSETAF:
258: case TCSETAW:
259: case TCSETA:
260: if (ioctl_buf.ioctl_termio.c_lflag & V__ECHO)
261: newterm.sg_flags |= ECHO ;
262: else
263: newterm.sg_flags &= ~ECHO ;
264: if (ioctl_buf.ioctl_termio.c_lflag & V__ICANON)
265: newterm.sg_flags &= ~CBREAK ;
266: else
267: newterm.sg_flags |= CBREAK;
268: ioctl ((r.r_file <= 2)?r.r_file:0, TIOCSETP, &newterm) ;
269: break ;
270: case TIOCSETP:
271: if (ioctl_buf.ioctl_sgttyb.sg_flags & VO_ECHO)
272: newterm.sg_flags |= ECHO ;
273: else
274: newterm.sg_flags &= ~ECHO ;
275: ioctl ((r.r_file <= 2)?r.r_file:0, TIOCSETP, &newterm) ;
276: break ;
277: case TIOCGETP:
278: ioctl_buf.ioctl_sgttyb.sg_ispeed = newterm.sg_ispeed ;
279: ioctl_buf.ioctl_sgttyb.sg_ospeed = newterm.sg_ospeed ;
280: ioctl_buf.ioctl_sgttyb.sg_erase = newterm.sg_erase ;
281: ioctl_buf.ioctl_sgttyb.sg_kill = newterm.sg_kill ;
282: ioctl_buf.ioctl_sgttyb.sg_flags = VO_ECHO|VO_EVENP ;
283: if ((newterm.sg_flags & ECHO) == 0)
284: ioctl_buf.ioctl_sgttyb.sg_flags &= ~VO_ECHO ;
285: break ;
286: case TCGETA:
287: ioctl_buf.ioctl_termio.c_iflag = V__BRKINT|V__IGNPAR|V__ISTRIP|V__ICRNL|V__IXON|V__IXANY ;
288: ioctl_buf.ioctl_termio.c_oflag = V__OPOST|V__ONLCR|V__TAB3 ;
289: ioctl_buf.ioctl_termio.c_cflag = V__B9600|V__CS7|V__CREAD|V__PARENB ;
290: ioctl_buf.ioctl_termio.c_lflag = 0;
291: if ((newterm.sg_flags & CBREAK) == 0)
292: ioctl_buf.ioctl_termio.c_lflag = V__ISIG|V__ICANON;
293: if (newterm.sg_flags & ECHO)
294: ioctl_buf.ioctl_termio.c_lflag |= V__ECHO|V__ECHOK;
295: break ;
296: case (('X'<<8)|0):
297: errno = EINVAL ;
298: break ;
299: }
300: }
301: s.s_length = give + fmtl ;
302: s.s_type = RIOCTL ;
303: s.s_error = errno ;
304: s.s_count = 0 ;
305: s.s_resid = fmtl ;
306: dktcanon(F_REMREPLY, &s, sb) ;
307: write(fd, sb, REMSIZE) ;
308: if (fmtl) {
309: write(fd, fmt, fmtl) ;
310: }
311: if (give) {
312: dktcanon(fmt, &ioctl_buf, &ioctl_buf) ;
313: write(fd, &ioctl_buf, give) ;
314: }
315: }
316:
317: static
318: dtdiscard(fd, len)
319: unsigned len ;
320: {
321: register unsigned rlen ;
322:
323: while (len) {
324: rlen = (len > BSIZE)? BSIZE : len ;
325: errno = 0 ;
326: rlen = read(fd, buf, rlen) ;
327: len -= rlen ;
328: }
329: }
330:
331: static
332: dtssig(fd)
333: {
334: if (sig) {
335: s.s_length = 0 ;
336: s.s_type = RSIGNAL ;
337: s.s_error = sig ;
338: sig = 0 ;
339: dktcanon(F_REMREPLY, &s, sb) ;
340: write(fd, sb, REMSIZE) ;
341: }
342: }
343:
344: static
345: dtSIG(signo)
346: {
347: static long lasttime;
348: long now, time();
349:
350: sig = signo ;
351: signal(signo, dtSIG) ;
352: if(signo == SIGQUIT){
353: time(&now);
354: if((now - lasttime) < 2){
355: exitcode = -EX_NOINPUT;
356: longjmp(wayout, 1);
357: }
358: lasttime = now;
359: }
360: }
361:
362: static
363: dtuSIG(signo)
364: {
365: uSIG++ ;
366: signal(signo, dtuSIG) ;
367: }
368:
369: xprint(buf, len)
370: register char *buf ;
371: {
372: while (len) {
373: printf("%o ", *buf++&0377) ;
374: len-- ;
375: }
376: printf("\n") ;
377: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.