|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <ipc.h> ! 3: #include <sgtty.h> ! 4: #include <sys/stream.h> ! 5: #include <errno.h> ! 6: #include <signal.h> ! 7: #include <sys/stat.h> ! 8: #include <libc.h> ! 9: ! 10: /* ! 11: * program to connect to ! 12: * another cpu on Datakit w/ transparent ioctls ! 13: */ ! 14: ! 15: int rem= -1; /* remote file descriptor */ ! 16: extern int mesg_ld; ! 17: struct sgttyb sgbuf; ! 18: struct tchars tcbuf; ! 19: int ttyrem=0; /* true if tty ld is remote */ ! 20: char *ttyn; ! 21: int perms; ! 22: ! 23: struct sigmsg { ! 24: struct mesg m; ! 25: char sig[1]; ! 26: }; ! 27: ! 28: struct buffer { ! 29: int rfd,wfd; ! 30: int mesgld; ! 31: char *rptr; ! 32: char *wptr; ! 33: char data[4096+MSGHLEN]; ! 34: }; ! 35: ! 36: struct mesg *getmsg(); ! 37: int fillbuf(); ! 38: ! 39: #define msglen(mp) ((mp)->losize + ((mp)->hisize<<8)) ! 40: ! 41: int lfd; ! 42: char *av0; ! 43: int notdef; ! 44: ! 45: usage() ! 46: { ! 47: fprintf(stderr, "usage: %s [-l] host\n"); ! 48: exit(1); ! 49: } ! 50: ! 51: main(argc, argv) ! 52: char **argv; ! 53: { ! 54: char *host; ! 55: struct stat sb; ! 56: int all; ! 57: extern int hupcatch(); ! 58: char *ttyname(); ! 59: ! 60: av0 = strrchr(argv[0], '/'); ! 61: av0 = av0==NULL ? argv[0] : av0+1; ! 62: while(argc>1 && argv[1][0]=='-'){ ! 63: char *cp; ! 64: for(cp= &argv[1][1]; *cp; cp++) ! 65: switch (*cp) { ! 66: case 'l': ! 67: av0 = "con-l"; ! 68: break; ! 69: default: ! 70: usage(); ! 71: } ! 72: argv++; ! 73: argc--; ! 74: } ! 75: host=argv[1]; ! 76: /* ! 77: if (host==NULL) ! 78: usage(); ! 79: */ ! 80: ioctl(0, TIOCGETP, &sgbuf); ! 81: ioctl(0, TIOCGETC, &tcbuf); ! 82: ! 83: all = strcmp(av0, "con")==0; ! 84: if (all || strcmp(av0, "ndcon")==0) ! 85: rem = trymesg(host); ! 86: if (rem<0 && (all || strcmp(av0, "dcon")==0)) ! 87: rem = trynomesg(host); ! 88: if (rem<0 && (all || strcmp(av0, "rogin")==0 || strcmp(av0, "rlogin")==0)) ! 89: rem = tryrogin(host); ! 90: if (rem<0 && (all || strcmp(av0, "con-l")==0)) ! 91: rem = trysimple(host); ! 92: if (rem<0) { ! 93: fprintf(stderr, "%s: %s connecting to %s\n", av0, errstr, host); ! 94: exit(1); ! 95: } ! 96: ! 97: signal(SIGHUP, hupcatch); ! 98: if ((ttyn = ttyname(0)) != NULL ! 99: && stat(ttyn, &sb) >= 0) { ! 100: perms = sb.st_mode & ~S_IFMT; ! 101: chmod(ttyn, 0); ! 102: } ! 103: ioctl(0, TIOCFLUSH, (char *)0); /* race with readahead still possible */ ! 104: if(ioctl(0, FIOPUSHLD, &mesg_ld) < 0) ! 105: go(rem, 0); ! 106: else ! 107: go(rem, 1); ! 108: ! 109: finish(0); ! 110: /* NOTREACHED */ ! 111: } ! 112: ! 113: /* try to set up a message line discipline connection */ ! 114: trymesg(host) ! 115: char *host; ! 116: { ! 117: int fd; ! 118: ! 119: fd = ipcopen(ipcpath(host, "dk", "mesgdcon"), "light"); ! 120: if (fd<0) ! 121: return fd; ! 122: if (ipclogin(fd)<0) { ! 123: fprintf(stderr, "%s: can't log in\n", av0); ! 124: exit(1); ! 125: } ! 126: return fd; ! 127: } ! 128: ! 129: /* try to set up a no line discipline connection */ ! 130: trynomesg(host) ! 131: char *host; ! 132: { ! 133: int fd; ! 134: ! 135: fd = ipcopen(ipcpath(host, "dk", "dcon"), "light"); ! 136: if (fd<0) ! 137: return fd; ! 138: if (ipclogin(fd)<0) { ! 139: fprintf(stderr, "%s: can't log in\n", av0); ! 140: exit(1); ! 141: } ! 142: remtty(); ! 143: return fd; ! 144: } ! 145: ! 146: /* try to set up a rlogin-like connection */ ! 147: tryrogin(host) ! 148: char *host; ! 149: { ! 150: int fd; ! 151: char *term; ! 152: ! 153: fd = ipcopen(ipcpath(host, "tcp", "tcp.513"), "light hup"); ! 154: if (fd<0) ! 155: return fd; ! 156: term = getenv("TERM"); ! 157: ipcrogin(fd, term?term:""); ! 158: remtty(); ! 159: return fd; ! 160: } ! 161: ! 162: /* try to set up a non-authenticated connection */ ! 163: trysimple(host) ! 164: char *host; ! 165: { ! 166: int fd; ! 167: ! 168: fd = ipcopen(ipcpath(host, "dk", ""), "light 1200"); ! 169: if (fd<0) ! 170: return fd; ! 171: remtty(); ! 172: return fd; ! 173: } ! 174: ! 175: /* set up for tty control to be remote */ ! 176: remtty() ! 177: { ! 178: struct sgttyb sg; ! 179: struct tchars tc; ! 180: ! 181: sg = sgbuf; ! 182: sg.sg_flags &= ~(CRMOD|ECHO|XTABS); ! 183: sg.sg_flags |= CBREAK; ! 184: ioctl(0, TIOCSETP, &sg); ! 185: tc.t_quitc = tcbuf.t_quitc; ! 186: tc.t_intrc = tc.t_startc = tc.t_stopc = tc.t_eofc = tc.t_brkc = -1; ! 187: ioctl(0, TIOCSETC, &tc); ! 188: ttyrem = 1; ! 189: } ! 190: ! 191: ! 192: static struct buffer ttyb; ! 193: static struct buffer netb; ! 194: ! 195: go(fd, mesg) ! 196: { ! 197: int rbits, wbits; ! 198: struct mesg *mp; ! 199: int dgenerated=0; ! 200: ! 201: wbits = 0; ! 202: ttyb.rptr = ttyb.wptr = ttyb.data; ! 203: ttyb.rfd = 0; ! 204: ttyb.wfd = 1; ! 205: ttyb.mesgld = mesg; ! 206: netb.rptr = netb.wptr = netb.data; ! 207: netb.rfd = fd; ! 208: netb.wfd = fd; ! 209: netb.mesgld = ttyrem==0; ! 210: while(1){ ! 211: rbits = 1 | (1<<fd); ! 212: if(select(20, (fd_set*)&rbits, (fd_set*)&wbits, 20000) < 0){ ! 213: if(errno != EINTR) ! 214: return; ! 215: continue; ! 216: } ! 217: if(rbits & 1) ! 218: if (fillbuf(&ttyb)<0) ! 219: return; ! 220: if(rbits & (1<<fd)) ! 221: if (fillbuf(&netb)<0) ! 222: return; ! 223: while(mp = getmsg(&ttyb)) { ! 224: if (mp->type==M_SIGNAL ! 225: && ((struct sigmsg *)mp)->sig[0]==SIGQUIT) { ! 226: dolocal(mp); ! 227: continue; ! 228: } ! 229: mp->magic = MSGMAGIC; /* temp safety */ ! 230: if(writemsg(&netb, mp)<0) ! 231: return; ! 232: if(mp->type == M_FLUSH) { ! 233: remflush(); ! 234: rbits = 0; ! 235: } ! 236: } ! 237: while(mp = getmsg(&netb)){ ! 238: if(mp->type == M_HANGUP) ! 239: return; ! 240: if(mp->type == M_IOCTL){ ! 241: doioctl(mp); ! 242: } else if(dgenerated && mp->type==M_DELIM){ ! 243: dgenerated = 0; ! 244: } else { ! 245: if(writemsg(&ttyb, mp)<0) ! 246: return; ! 247: if(mp->type==M_DATA) { ! 248: sendmsg(&ttyb, M_DELIM, (char *)mp, 0); ! 249: dgenerated = 1; ! 250: } ! 251: } ! 252: } ! 253: } ! 254: } ! 255: ! 256: /* read in at least a complete message */ ! 257: fillbuf(bp) ! 258: register struct buffer *bp; ! 259: { ! 260: register int n; ! 261: struct mesg *mp; ! 262: static int neofs; ! 263: ! 264: if(!bp->mesgld) { ! 265: bp->rptr = bp->data; ! 266: bp->wptr = bp->data+MSGHLEN; ! 267: mp = (struct mesg *)bp->rptr; ! 268: } else { ! 269: /* compact */ ! 270: n = bp->wptr-bp->rptr; ! 271: if (n > 0 && bp->rptr!=bp->data) ! 272: memcpy(bp->data, bp->rptr, n); ! 273: bp->rptr = bp->data; ! 274: bp->wptr = bp->rptr + n; ! 275: } ! 276: ! 277: /* try reading */ ! 278: n = bp->data+sizeof(bp->data) - bp->wptr; ! 279: if (n > 0) { ! 280: if ((n = read(bp->rfd, bp->wptr, n))<=0) ! 281: if(n<0 || ++neofs>4) ! 282: return -1; ! 283: bp->wptr += n; ! 284: } else ! 285: neofs = 0; ! 286: ! 287: if(!bp->mesgld) { ! 288: mp->type = M_DATA; ! 289: mp->magic = MSGMAGIC; ! 290: setmsgl(mp, n); ! 291: } ! 292: return 0; ! 293: } ! 294: ! 295: /* get the next (buffered) message */ ! 296: struct mesg * ! 297: getmsg(bp) ! 298: struct buffer *bp; ! 299: { ! 300: struct mesg *mp = (struct mesg *)bp->rptr; ! 301: int n = bp->wptr - bp->rptr; ! 302: ! 303: if (n<MSGHLEN || n<MSGHLEN+msglen(mp)) ! 304: return NULL; ! 305: bp->rptr += MSGHLEN + msglen(mp); ! 306: mp->magic = MSGMAGIC; ! 307: return mp; ! 308: } ! 309: ! 310: int ! 311: writemsg(bp, mp) ! 312: struct buffer *bp; ! 313: struct mesg *mp; ! 314: { ! 315: int len; ! 316: char *cp; ! 317: ! 318: if(bp->mesgld) { ! 319: len = MSGHLEN + msglen(mp); ! 320: cp = (char *)mp; ! 321: } else if(mp->type==M_DATA){ ! 322: len = msglen(mp); ! 323: cp = ((char *)mp)+MSGHLEN; ! 324: } else ! 325: return 0; ! 326: if(write(bp->wfd, cp, len)!=len) ! 327: return -1; ! 328: return 0; ! 329: } ! 330: ! 331: doioctl(mp) ! 332: struct mesg *mp; ! 333: { ! 334: struct iofoo{ ! 335: int cmd; ! 336: union{ ! 337: int i; ! 338: char errno; ! 339: struct insld insld; ! 340: } u; ! 341: } *iop; ! 342: int cmd, ld; ! 343: int n; ! 344: ! 345: iop = (struct iofoo *)(((char*)mp) + MSGHLEN); ! 346: cmd = iop->cmd; ! 347: n = msglen(mp); ! 348: n -= sizeof(iop->cmd); ! 349: switch(cmd){ ! 350: case FIOLOOKLD: ! 351: if(n > 0) ! 352: ld = iop->u.i; ! 353: else ! 354: ld = 0; ! 355: ld++; ! 356: if(ioctl(1, FIOLOOKLD, &ld) < 0) ! 357: goto bad; ! 358: iop->cmd = ld; ! 359: n = sizeof(iop->cmd); ! 360: break; ! 361: ! 362: case FIOPOPLD: ! 363: if(n > 0) ! 364: ld = iop->u.i; ! 365: else ! 366: ld = 0; ! 367: ld++; ! 368: if(ioctl(1, FIOPOPLD, &ld) < 0) ! 369: goto bad; ! 370: n = 0; ! 371: break; ! 372: ! 373: case FIOPUSHLD: ! 374: iop->u.insld.level = 0; ! 375: /* fall through... */ ! 376: case FIOINSLD: ! 377: iop->u.insld.level++; ! 378: if(ioctl(1, FIOINSLD, &(iop->u.insld)) < 0) ! 379: goto bad; ! 380: n = 0; ! 381: break; ! 382: ! 383: default: ! 384: mp->magic = MSGMAGIC; /* safety */ ! 385: writemsg(&ttyb, mp); ! 386: return; ! 387: } ! 388: /* locally successful */ ! 389: mp->type = M_IOCACK; ! 390: mp->magic = MSGMAGIC; ! 391: setmsgl(mp, n); ! 392: writemsg(&netb, mp); ! 393: return; ! 394: bad: ! 395: mp->type = M_IOCNAK; ! 396: mp->magic = MSGMAGIC; ! 397: setmsgl(mp, sizeof(struct iofoo)); ! 398: iop->u.errno = errno; ! 399: writemsg(&netb, mp); ! 400: } ! 401: ! 402: remflush() ! 403: { ! 404: char buf[5000]; ! 405: struct mesg *mp; ! 406: ! 407: mp = (struct mesg *) buf; ! 408: mp->type = M_IOCTL; ! 409: setmsgl(mp, sizeof(int)); ! 410: mp->magic = MSGMAGIC; ! 411: writemsg(&netb, (struct mesg *)buf); ! 412: ! 413: while(read(rem, buf, sizeof(buf)) > 0){ ! 414: if(mp->type == M_IOCNAK || mp->type == M_IOCACK) ! 415: return; ! 416: } ! 417: } ! 418: ! 419: setmsgl(mp, n) ! 420: register struct mesg *mp; ! 421: int n; ! 422: { ! 423: mp->losize = n; ! 424: mp->hisize = n >> 8; ! 425: } ! 426: ! 427: hupcatch() ! 428: { ! 429: finish(0); ! 430: } ! 431: ! 432: finish(sts) ! 433: { ! 434: struct mesg m; ! 435: ! 436: if(ioctl(0, FIOLOOKLD, 0) == mesg_ld) ! 437: ioctl(0, FIOPOPLD, 0); ! 438: if (ttyn) ! 439: chmod(ttyn, perms); ! 440: ioctl(0, TIOCSETP, &sgbuf); ! 441: ioctl(0, TIOCSETC, &tcbuf); ! 442: if (sts == 0) ! 443: printf("Eof\n"); ! 444: exit(sts); ! 445: } ! 446: ! 447: dolocal(mp) ! 448: register struct mesg *mp; ! 449: { ! 450: char lbuf[128+1]; ! 451: register char *lp; ! 452: struct sgttyb nsgbuf; ! 453: struct tchars ntcbuf; ! 454: int done; ! 455: ! 456: ioctl(0, FIOPOPLD, (char *)0); ! 457: ioctl(0, TIOCFLUSH, (char *)0); ! 458: ioctl(0, TIOCGETP, &nsgbuf); ! 459: ioctl(0, TIOCSETP, &sgbuf); ! 460: ioctl(0, TIOCGETC, &ntcbuf); ! 461: ioctl(0, TIOCSETC, &tcbuf); ! 462: chmod(ttyn, perms); ! 463: for (done=0;!done;) { ! 464: lp = lbuf; ! 465: printf( "con>> "); ! 466: fflush(stdout); ! 467: while (lp < &lbuf[128] && read(0, lp, 1)>0 && *lp!='\n') ! 468: lp++; ! 469: *lp = '\0'; ! 470: switch(*lbuf) { ! 471: case 'b': ! 472: if (!ttyrem) ! 473: sendmsg(&netb, M_BREAK, (char *)NULL, 0); ! 474: mp->type = 0; ! 475: done = 1; ! 476: break; ! 477: case 'i': ! 478: if (ttyrem) { ! 479: sendmsg(&netb, M_DATA, &tcbuf.t_quitc, 1); ! 480: mp->type = 0; ! 481: } ! 482: done = 1; ! 483: break; ! 484: case 'q': ! 485: case 'x': ! 486: case '.': ! 487: finish(1); ! 488: case '!': ! 489: system(lbuf+1); ! 490: printf("!!\n"); ! 491: fflush(stdout); ! 492: mp->type = 0; ! 493: done = 1; ! 494: break; ! 495: case '\0': ! 496: mp->type = 0; ! 497: done = 1; ! 498: break; ! 499: default: ! 500: printf("[qx.] to exit, i for quit signal, b for break, !cmd for shell\n"); ! 501: fflush(stdout); ! 502: } ! 503: } ! 504: ioctl(0, TIOCSETP, &nsgbuf); ! 505: ioctl(0, TIOCSETC, &ntcbuf); ! 506: ioctl(0, FIOPUSHLD, &mesg_ld); ! 507: chmod(ttyn, 0); ! 508: if (mp->type) { ! 509: mp->magic = MSGMAGIC; /* safety */ ! 510: writemsg(&netb, mp); ! 511: } ! 512: } ! 513: ! 514: sendmsg(bp, type, cp, len) ! 515: struct buffer *bp; ! 516: int type, len; ! 517: char *cp; ! 518: { ! 519: struct amesg { ! 520: struct mesg m; ! 521: char body[128]; ! 522: } am; ! 523: ! 524: am.m.magic = MSGMAGIC; ! 525: am.m.type = type; ! 526: setmsgl(&am.m, len); ! 527: if (cp!=NULL && len>0) ! 528: memcpy(am.body, cp, len); ! 529: writemsg(bp, (struct mesg *)&am); ! 530: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.