|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <errno.h> ! 3: #include <dk.h> ! 4: #include <sgtty.h> ! 5: #include <sys/stream.h> ! 6: #include <signal.h> ! 7: ! 8: /* ! 9: * program to run a command ! 10: * on another cpu on Datakit w/ tranarent ioctls ! 11: */ ! 12: ! 13: int rem; /* remote file descriptor */ ! 14: extern int mesg_ld; ! 15: extern errno; ! 16: extern char *dkerror; ! 17: ! 18: struct mesg{ ! 19: short type; ! 20: short size; ! 21: }; ! 22: ! 23: char *std = "-"; ! 24: ! 25: #define MAXCHARS 8192 ! 26: char args[MAXCHARS]; ! 27: ! 28: char *bldargs(argv) ! 29: register char *argv[]; ! 30: { ! 31: register char *s=args, *t; ! 32: while(t= *argv++){ /* assignment = */ ! 33: while(*s = *t++) ! 34: if(s++ >= &args[MAXCHARS-1]){ ! 35: fprintf(stderr, "rx: arg list too long\n"); ! 36: exit(1); ! 37: } ! 38: *s++=' '; ! 39: } ! 40: s[-1]='\0'; ! 41: return(args); ! 42: } ! 43: ! 44: char * ! 45: basename(s) ! 46: register char *s; ! 47: { ! 48: register char *t; ! 49: extern char *rindex(); ! 50: t=rindex(s, '/'); ! 51: return(t? t+1 : s); ! 52: } ! 53: ! 54: hupcatch() ! 55: { ! 56: ! 57: if(ioctl(0, FIOLOOKLD, 0) == mesg_ld) ! 58: ioctl(0, FIOPOPLD, 0); ! 59: exit(0); ! 60: } ! 61: ! 62: main(argc, argv) ! 63: char **argv; ! 64: { ! 65: char *host, *cmd; ! 66: ! 67: host = cmd = basename(argv[0]); ! 68: if(strcmp(host, "rx")==0 || strcmp(host, "rexec")==0 ! 69: || strcmp(host, "nrx")==0){ ! 70: host=argv[1]; ! 71: argv++; ! 72: } ! 73: if(host==0){ ! 74: fprintf(stderr, "usage: %s host [command]\n", cmd); ! 75: exit(1); ! 76: } ! 77: if(argv[1]==0){ ! 78: fprintf(stderr, "%s: cannot dcon\n", cmd); ! 79: exit(1); ! 80: } ! 81: rem = mesgexec(host, bldargs(&argv[1])); ! 82: if (rem<0) { ! 83: fprintf(stderr, "%s: call to %s failed: %s\n", cmd , host, dkerror); ! 84: exit(1); ! 85: } ! 86: if(ioctl(0, FIOPUSHLD, &mesg_ld) < 0){ ! 87: fprintf(stderr, "%s: can't push mesg_ld\n", cmd); ! 88: exit(1); ! 89: } ! 90: signal(SIGHUP, hupcatch); ! 91: signal(SIGPIPE, SIG_IGN); ! 92: ! 93: go(rem); ! 94: ! 95: hupcatch(); ! 96: /* NOTREACHED */ ! 97: } ! 98: ! 99: go(fd) ! 100: { ! 101: int rbits, wbits, n; ! 102: char buf[4096+sizeof(struct mesg)]; ! 103: struct mesg *mp; ! 104: ! 105: mp = (struct mesg *) buf; ! 106: wbits = 0; ! 107: while(1){ ! 108: rbits = 1 | (1<<fd); ! 109: if(select(20, &rbits, &wbits, 20000) < 0){ ! 110: if(errno != EINTR) ! 111: return; ! 112: continue; ! 113: } ! 114: if(rbits & 1){ ! 115: n = read(0, buf, sizeof(buf)); ! 116: if(n <= 0) ! 117: return; ! 118: if(write(fd, buf, n) != n) ! 119: return; ! 120: if(mp->type == M_FLUSH) ! 121: remflush(); ! 122: } ! 123: if(rbits & (1<<fd)){ ! 124: n = read(fd, buf, sizeof(buf)); ! 125: if(n <= 0) ! 126: return; ! 127: if(mp->type == M_HANGUP) ! 128: return; ! 129: if(mp->type == M_IOCTL){ ! 130: doioctl(buf, n); ! 131: } else { ! 132: if(write(1, buf, n) != n) ! 133: return; ! 134: } ! 135: } ! 136: } ! 137: } ! 138: ! 139: doioctl(buf, n) ! 140: char *buf; ! 141: { ! 142: struct mesg *mp; ! 143: struct iofoo{ ! 144: int cmd; ! 145: union{ ! 146: int i; ! 147: char errno; ! 148: struct insld insld; ! 149: } u; ! 150: } *iop; ! 151: int cmd, ld; ! 152: ! 153: iop = (struct iofoo *)(buf + sizeof(struct mesg)); ! 154: mp = (struct mesg *) buf; ! 155: ! 156: cmd = iop->cmd; ! 157: n -= sizeof(struct mesg); ! 158: n -= sizeof(iop->cmd); ! 159: switch(cmd){ ! 160: case FIOLOOKLD: ! 161: if(n > 0) ! 162: ld = iop->u.i; ! 163: else ! 164: ld = 0; ! 165: ld++; ! 166: if(ioctl(1, FIOLOOKLD, &ld) < 0) ! 167: goto bad; ! 168: iop->cmd = ld; ! 169: n = sizeof(iop->cmd); ! 170: break; ! 171: ! 172: case FIOPOPLD: ! 173: if(n > 0) ! 174: ld = iop->u.i; ! 175: else ! 176: ld = 0; ! 177: ld++; ! 178: if(ioctl(1, FIOPOPLD, &ld) < 0) ! 179: goto bad; ! 180: n = 0; ! 181: break; ! 182: ! 183: case FIOPUSHLD: ! 184: iop->u.insld.level = 0; ! 185: /* fall through... */ ! 186: case FIOINSLD: ! 187: iop->u.insld.level++; ! 188: if(ioctl(1, FIOINSLD, &(iop->u.insld)) < 0) ! 189: goto bad; ! 190: n = 0; ! 191: break; ! 192: ! 193: default: ! 194: write(1, buf, sizeof(struct mesg) + mp->size); ! 195: return; ! 196: } ! 197: /* locally successful */ ! 198: mp->type = M_IOCACK; ! 199: mp->size = n; ! 200: write(rem, buf, sizeof(struct mesg) + mp->size); ! 201: return; ! 202: bad: ! 203: mp->type = M_IOCNAK; ! 204: mp->size = sizeof(struct iofoo); ! 205: iop->u.errno = errno; ! 206: write(rem, buf, sizeof(struct mesg) + mp->size); ! 207: } ! 208: ! 209: remflush() ! 210: { ! 211: char buf[5000]; ! 212: struct mesg *mp; ! 213: int n; ! 214: ! 215: mp = (struct mesg *) buf; ! 216: mp->type = M_IOCTL; ! 217: mp->size = sizeof(int); ! 218: write(rem, buf, mp->size + sizeof(struct mesg)); ! 219: ! 220: while((n = read(rem, buf, sizeof(buf))) > 0){ ! 221: if(mp->type == M_IOCNAK || mp->type == M_IOCACK){ ! 222: return; ! 223: } ! 224: } ! 225: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.