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