|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <errno.h> ! 3: #include <dk.h> ! 4: #include <sys/types.h> ! 5: #include <sys/stat.h> ! 6: #include <sys/filio.h> ! 7: #include <sys/ttyio.h> ! 8: #include <sys/stream.h> ! 9: #include <signal.h> ! 10: ! 11: /* ! 12: * program to run a command ! 13: * on another cpu on Datakit w/ transparent ioctls, ! 14: * sometimes. ! 15: */ ! 16: ! 17: #define msglen(mp) ((mp)->losize + ((mp)->hisize<<8)) ! 18: ! 19: int rem; /* remote file descriptor */ ! 20: extern int mesg_ld; ! 21: extern errno; ! 22: extern char *dkerror; ! 23: int nomesg; ! 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: setmsgl(mp, n) ! 55: register struct mesg *mp; ! 56: int n; ! 57: { ! 58: mp->losize = n; ! 59: mp->hisize = n >> 8; ! 60: } ! 61: ! 62: finish() ! 63: { ! 64: ! 65: if(ioctl(0, FIOLOOKLD, 0) == mesg_ld) { ! 66: ioctl(0, FIOPOPLD, 0); ! 67: ioctl(0, TIOCFLUSH, 0); ! 68: } ! 69: exit(0); ! 70: } ! 71: ! 72: main(argc, argv) ! 73: char **argv; ! 74: { ! 75: char *host, *cmd; ! 76: ! 77: host = cmd = basename(argv[0]); ! 78: if(strcmp(host, "rx")==0 || strcmp(host, "rexec")==0 ! 79: || strcmp(host, "nrx")==0){ ! 80: host=argv[1]; ! 81: argv++; ! 82: } ! 83: if(host==0){ ! 84: fprintf(stderr, "usage: %s host [command]\n", cmd); ! 85: exit(1); ! 86: } ! 87: if(argv[1]==0){ ! 88: execl("/usr/bin/ndcon", argv[1], argv[1], (char *)0); ! 89: perror("ndcon"); ! 90: exit(1); ! 91: } ! 92: rem = mesgexec(host, bldargs(&argv[1])); ! 93: if (rem<0) { ! 94: fprintf(stderr, "%s: call to %s failed: %s\n", cmd , host, dkerror); ! 95: exit(1); ! 96: } ! 97: setmesg(); ! 98: signal(SIGHUP, finish); ! 99: signal(SIGPIPE, SIG_IGN); ! 100: go(rem); ! 101: finish(); ! 102: /* NOTREACHED */ ! 103: } ! 104: ! 105: /* ! 106: * if standard input and output are the same, ! 107: * try to push the message line discipline ! 108: * otherwise we're in a pipeline and it's not safe ! 109: */ ! 110: setmesg() ! 111: { ! 112: struct stat st0, st1; ! 113: ! 114: if (fstat(0, &st0) < 0 || fstat(1, &st1) < 0 ! 115: || st0.st_dev != st1.st_dev || st0.st_ino != st1.st_ino) { ! 116: nomesg = 1; ! 117: return; ! 118: } ! 119: if(ioctl(0, FIOPUSHLD, &mesg_ld) < 0) ! 120: nomesg = 1; ! 121: } ! 122: ! 123: /* ! 124: * hack: ! 125: * until some message comes back from the remote, ! 126: * ignore local data ! 127: */ ! 128: go(fd) ! 129: { ! 130: int rbits, wbits, srbits; ! 131: int n; ! 132: char buf[4096+MSGHLEN]; ! 133: struct mesg *mp; ! 134: int first = 0; ! 135: ! 136: mp = (struct mesg *) buf; ! 137: wbits = 0; ! 138: srbits = (1<<0)|(1<<fd); ! 139: while(1){ ! 140: rbits = srbits; ! 141: if(select(20, &rbits, &wbits, 20000) < 0){ ! 142: if(errno != EINTR) ! 143: return; ! 144: continue; ! 145: } ! 146: if(rbits & 1){ ! 147: n = rdmesg(0, buf, sizeof(buf)); ! 148: if(n <= 0) { ! 149: srbits &=~ 1; ! 150: continue; ! 151: } ! 152: mp->magic = MSGMAGIC; /* temporary safety */ ! 153: if(write(fd, buf, n) != n) ! 154: return; ! 155: if(mp->type == M_FLUSH) ! 156: remflush(); ! 157: } ! 158: if(rbits & (1<<fd)){ ! 159: n = read(fd, buf, sizeof(buf)); ! 160: if(n <= 0) ! 161: return; ! 162: if(mp->type == M_HANGUP) ! 163: return; ! 164: if(mp->type == M_IOCTL){ ! 165: doioctl(buf, n); ! 166: } else { ! 167: mp->magic = MSGMAGIC; /* temp safety */ ! 168: if(wrmesg(1, buf, n) != n) ! 169: return; ! 170: } ! 171: } ! 172: } ! 173: } ! 174: ! 175: #define MAXEOF 10 ! 176: ! 177: rdmesg(f, buf, n) ! 178: char *buf; ! 179: { ! 180: register struct mesg *mp; ! 181: static int eof = 0; ! 182: ! 183: if (nomesg == 0) ! 184: return (read(f, buf, n)); ! 185: if (eof > MAXEOF) ! 186: return (0); ! 187: n = read(f, buf + MSGHLEN, n - (2 * MSGHLEN)); ! 188: if (n < 0) ! 189: return (n); ! 190: mp = (struct mesg *)buf; ! 191: if (n == 0) { ! 192: eof++; ! 193: mp->type = M_DELIM; ! 194: mp->magic = MSGMAGIC; ! 195: setmsgl(mp, 0); ! 196: return (MSGHLEN); ! 197: } ! 198: eof = 0; ! 199: setmsgl(buf, n); ! 200: mp->type = M_DATA; ! 201: mp->magic = MSGMAGIC; ! 202: mp = (struct mesg *)(buf + MSGHLEN + n); ! 203: mp->type = M_DELIM; ! 204: mp->magic = MSGMAGIC; ! 205: setmsgl(buf, 0); ! 206: return (n + 2*MSGHLEN); ! 207: } ! 208: ! 209: wrmesg(f, buf, n) ! 210: char *buf; ! 211: { ! 212: if (nomesg == 0) ! 213: return (write(f, buf, n)); ! 214: if (((struct mesg *)buf)->type != M_DATA) ! 215: return (n); /* toss it */ ! 216: if (write(f, buf + MSGHLEN, n - MSGHLEN) != n - MSGHLEN) ! 217: return (-1); ! 218: return (n); ! 219: } ! 220: ! 221: doioctl(buf, n) ! 222: char *buf; ! 223: { ! 224: struct mesg *mp; ! 225: struct iofoo{ ! 226: int cmd; ! 227: union{ ! 228: int i; ! 229: char errno; ! 230: struct insld insld; ! 231: } u; ! 232: } *iop; ! 233: int cmd, ld; ! 234: ! 235: iop = (struct iofoo *)(buf + MSGHLEN); ! 236: mp = (struct mesg *) buf; ! 237: if (nomesg) { ! 238: errno = ENOTTY; ! 239: goto bad; ! 240: } ! 241: cmd = iop->cmd; ! 242: n -= MSGHLEN; ! 243: n -= sizeof(iop->cmd); ! 244: switch(cmd){ ! 245: case FIOLOOKLD: ! 246: if(n > 0) ! 247: ld = iop->u.i; ! 248: else ! 249: ld = 0; ! 250: ld++; ! 251: if(ioctl(1, FIOLOOKLD, &ld) < 0) ! 252: goto bad; ! 253: iop->cmd = ld; ! 254: n = sizeof(iop->cmd); ! 255: break; ! 256: ! 257: case FIOPOPLD: ! 258: if(n > 0) ! 259: ld = iop->u.i; ! 260: else ! 261: ld = 0; ! 262: ld++; ! 263: if(ioctl(1, FIOPOPLD, &ld) < 0) ! 264: goto bad; ! 265: n = 0; ! 266: break; ! 267: ! 268: case FIOPUSHLD: ! 269: iop->u.insld.level = 0; ! 270: /* fall through... */ ! 271: case FIOINSLD: ! 272: iop->u.insld.level++; ! 273: if(ioctl(1, FIOINSLD, &(iop->u.insld)) < 0) ! 274: goto bad; ! 275: n = 0; ! 276: break; ! 277: ! 278: default: ! 279: mp->magic = MSGMAGIC; /* safety */ ! 280: write(1, buf, MSGHLEN + msglen(mp)); ! 281: return; ! 282: } ! 283: /* locally successful */ ! 284: mp->type = M_IOCACK; ! 285: mp->magic = MSGMAGIC; ! 286: setmsgl(mp, n); ! 287: write(rem, buf, MSGHLEN + msglen(mp)); ! 288: return; ! 289: bad: ! 290: mp->type = M_IOCNAK; ! 291: mp->magic = MSGMAGIC; ! 292: setmsgl(mp, sizeof(struct iofoo)); ! 293: iop->u.errno = errno; ! 294: n = write(rem, buf, MSGHLEN + msglen(mp)); ! 295: } ! 296: ! 297: remflush() ! 298: { ! 299: char buf[5000]; ! 300: struct mesg *mp; ! 301: int n; ! 302: ! 303: mp = (struct mesg *) buf; ! 304: mp->type = M_IOCTL; ! 305: mp->magic = MSGMAGIC; ! 306: setmsgl(mp, sizeof(int)); ! 307: write(rem, buf, MSGHLEN + msglen(mp)); ! 308: ! 309: while((n = read(rem, buf, sizeof(buf))) > 0){ ! 310: if(mp->type == M_IOCNAK || mp->type == M_IOCACK){ ! 311: return; ! 312: } ! 313: } ! 314: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.