|
|
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 (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: ioctl ((r.r_file <= 2)?r.r_file:0, TIOCSETP, &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: ioctl ((r.r_file <= 2)?r.r_file:0, TIOCSETP, &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.