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