|
|
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/ioctl.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 (gtty(n, &origterm) == 0) {
69: otfd = n;
70: break;
71: }
72:
73: if(setjmp(wayout)){
74: if(otfd >= 0)
75: stty(otfd, &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: gtty((r.r_file <= 2)?r.r_file:0, &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: stty((r.r_file <= 2)?r.r_file:0, &newterm) ;
265: break ;
266: case TIOCSETP:
267: if (ioctl_buf.ioctl_sgttyb.sg_flags & VO_ECHO)
268: newterm.sg_flags |= ECHO ;
269: else
270: newterm.sg_flags &= ~ECHO ;
271: stty((r.r_file <= 2)?r.r_file:0, &newterm) ;
272: break ;
273: case TIOCGETP:
274: ioctl_buf.ioctl_sgttyb.sg_ispeed = newterm.sg_ispeed ;
275: ioctl_buf.ioctl_sgttyb.sg_ospeed = newterm.sg_ospeed ;
276: ioctl_buf.ioctl_sgttyb.sg_erase = newterm.sg_erase ;
277: ioctl_buf.ioctl_sgttyb.sg_kill = newterm.sg_kill ;
278: ioctl_buf.ioctl_sgttyb.sg_flags = VO_ECHO|VO_EVENP ;
279: if ((newterm.sg_flags & ECHO) == 0)
280: ioctl_buf.ioctl_sgttyb.sg_flags &= ~VO_ECHO ;
281: break ;
282: case TCGETA:
283: ioctl_buf.ioctl_termio.c_iflag = V__BRKINT|V__IGNPAR|V__ISTRIP|V__ICRNL|V__IXON|V__IXANY ;
284: ioctl_buf.ioctl_termio.c_oflag = V__OPOST|V__ONLCR|V__TAB3 ;
285: ioctl_buf.ioctl_termio.c_cflag = V__B9600|V__CS7|V__CREAD|V__PARENB ;
286: ioctl_buf.ioctl_termio.c_lflag = V__ISIG|V__ICANON ;
287: if (newterm.sg_flags & ECHO)
288: ioctl_buf.ioctl_termio.c_lflag |= V__ECHO|V__ECHOK ;
289: break ;
290: case (('X'<<8)|0):
291: errno = EINVAL ;
292: break ;
293: }
294: }
295: s.s_length = give + fmtl ;
296: s.s_type = RIOCTL ;
297: s.s_error = errno ;
298: s.s_count = 0 ;
299: s.s_resid = fmtl ;
300: dktcanon(F_REMREPLY, &s, sb) ;
301: write(fd, sb, REMSIZE) ;
302: if (fmtl) {
303: write(fd, fmt, fmtl) ;
304: }
305: if (give) {
306: dktcanon(fmt, &ioctl_buf, &ioctl_buf) ;
307: write(fd, &ioctl_buf, give) ;
308: }
309: }
310:
311: static
312: dtdiscard(fd, len)
313: unsigned len ;
314: {
315: register unsigned rlen ;
316:
317: while (len) {
318: rlen = (len > BSIZE)? BSIZE : len ;
319: errno = 0 ;
320: rlen = read(fd, buf, rlen) ;
321: len -= rlen ;
322: }
323: }
324:
325: static
326: dtssig(fd)
327: {
328: if (sig) {
329: s.s_length = 0 ;
330: s.s_type = RSIGNAL ;
331: s.s_error = sig ;
332: sig = 0 ;
333: dktcanon(F_REMREPLY, &s, sb) ;
334: write(fd, sb, REMSIZE) ;
335: }
336: }
337:
338: static
339: dtSIG(signo)
340: {
341: static long lasttime;
342: long now, time();
343:
344: sig = signo ;
345: signal(signo, dtSIG) ;
346: if(signo == SIGQUIT){
347: time(&now);
348: if((now - lasttime) < 2){
349: exitcode = -EX_NOINPUT;
350: longjmp(wayout, 1);
351: }
352: lasttime = now;
353: }
354: }
355:
356: static
357: dtuSIG(signo)
358: {
359: uSIG++ ;
360: signal(signo, dtuSIG) ;
361: }
362:
363: xprint(buf, len)
364: register char *buf ;
365: {
366: while (len) {
367: printf("%o ", *buf++&0377) ;
368: len-- ;
369: }
370: printf("\n") ;
371: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.