|
|
1.1 ! root 1: #if TRACING | PSTATISTICS ! 2: #include <stdio.h> ! 3: #endif ! 4: ! 5: #include <sys/param.h> ! 6: #include <sys/types.h> ! 7: #include <sys/stream.h> ! 8: #include <sys/ttyio.h> ! 9: #include <sys/filio.h> ! 10: #include <signal.h> ! 11: #include <errno.h> ! 12: #include <jioctl.h> ! 13: #include <tty.h> ! 14: ! 15: #include "msgs.h" ! 16: #include "pconfig.h" ! 17: #include "proto.h" ! 18: #include "packets.h" ! 19: #include "pstats.h" ! 20: ! 21: /* ! 22: * One layer structure per file-descriptor ! 23: */ ! 24: struct layer { ! 25: char chan; /* jerq protocol channel */ ! 26: char busy; ! 27: char dx, dy; /* Window size in characters */ ! 28: short bitsx, bitsy; /* Window size in bits */ ! 29: int more; ! 30: struct ttychars ttychars; ! 31: char ptfile[14]; /* file name of slave */ ! 32: char bchan; /* holding area for blocked data */ ! 33: char bcount; ! 34: char bbuf[MAXPKTDSIZE]; ! 35: }; ! 36: ! 37: #define NLAYERS 16 /* Same as in jerq itself */ ! 38: #define NSELFD 20 /* Maximum file descriptors for 'select' */ ! 39: #define SELTIMO (1000*3) /* 'select' timeout in millisecs */ ! 40: #define CDSIZE (sizeof(struct sgttyb)-1) ! 41: ! 42: char *jerqprog; ! 43: char *jerqstart; ! 44: char umesgf[]= "/dev/pt/pt109"; ! 45: char *progname; ! 46: char *shell; ! 47: int quitflag; ! 48: fd_set rdfd; ! 49: int enabled=1; ! 50: int blocked=0; ! 51: struct layer layer[NSELFD]; ! 52: char buf[MAXPKTDSIZE+MSGHLEN]; ! 53: struct sgttyb sttymodes; ! 54: struct sgttyb sttysave; ! 55: struct ttydevb devmodes; ! 56: struct ttydevb devsave; ! 57: struct tchars tcharssave; ! 58: struct ttychars ttychars; ! 59: struct ttychars zerochars; ! 60: short booted; ! 61: extern int receive(); ! 62: extern int creceive(); ! 63: void dosig(); ! 64: int twrite(); ! 65: void wrmesgb(); ! 66: extern char *sys_errlist[]; ! 67: extern char *getenv(); ! 68: extern char *itoa(); ! 69: extern char *strcpy(); ! 70: extern char *strcat(); ! 71: extern int tty_ld; ! 72: extern int mesg_ld; ! 73: extern int errno; ! 74: extern int sys_nerr; ! 75: extern int strlen(); ! 76: extern int write(); ! 77: ! 78: struct{ ! 79: short speed; ! 80: short bytes; ! 81: } speeds[] = { ! 82: EXTA, 1920, ! 83: B9600, 960, ! 84: B4800, 480, ! 85: B1200, 120, ! 86: B300, 30, ! 87: 0, 960, /* default */ ! 88: }; ! 89: #define NSPEEDS ((sizeof speeds)/(sizeof speeds[0])) ! 90: #define max(A,B) (((A)>(B))?(A):(B)) ! 91: ! 92: struct Pchannel pconvs[NLAYERS]; ! 93: struct Pconfig pconfig = { ! 94: # ifndef TRACING ! 95: write, ! 96: # else ! 97: twrite, ! 98: # endif ! 99: receive, ! 100: (void(*)())creceive, ! 101: }; ! 102: ! 103: #ifdef TRACING ! 104: int twrite(); ! 105: FILE *tracefd; ! 106: void trace(); ! 107: void tread(); ! 108: #define ifdeftracing(a) a ! 109: #else ! 110: #define trace(a, b) ! 111: #define tread(a, b) ! 112: #define ifdeftracing(a) ! 113: #endif ! 114: ! 115: #if TRACING==1 || PDEBUG==1 ! 116: char tracefile[]="traces"; ! 117: #define _exit exit ! 118: #endif ! 119: ! 120: main(argc, argv) ! 121: char *argv[]; ! 122: { ! 123: register int n; ! 124: char cmdline[64]; ! 125: progname=argv[0]; ! 126: for(n=1; n<argc; n++) { ! 127: if(strcmp(argv[n], "-L")==0) ! 128: jerqstart=argv[++n]; ! 129: else if(strcmp(argv[n], "-l")==0){ ! 130: register fd; char jfd[32]; ! 131: fd = creat(mktemp(strcpy(jfd, "/tmp/.muxXXXXXX")), 0744); ! 132: ++n, write(fd, argv[n], strlen(argv[n])); ! 133: close(fd); ! 134: strcpy(cmdline, jfd); ! 135: strcat(strcat(strcat(cmdline, "; rm "), jfd), "; exit"); ! 136: jerqstart = cmdline; ! 137: }else{ ! 138: n=argc+1; break; ! 139: } ! 140: } ! 141: if(n!=argc) ! 142: return service(argc-1, argv+1); ! 143: if((jerqprog=getenv("MUXTERM")) == 0) ! 144: jerqprog="/usr/jerq/lib/muxterm"; ! 145: if((shell=getenv("SHELL")) == 0) ! 146: shell="sh"; ! 147: ioctl(0, TIOCGETP, &sttymodes); ! 148: sttysave=sttymodes; ! 149: if(ioctl(0, TIOCGDEV, &devmodes)>=0) /* band-aid for old systems */ ! 150: devsave=devmodes; ! 151: else { ! 152: devsave.ispeed=devmodes.ispeed=sttymodes.sg_ispeed; ! 153: devsave.ospeed=devmodes.ospeed=sttymodes.sg_ospeed; ! 154: } ! 155: ioctl(0, TIOCGETC, &tcharssave); ! 156: setmodes(&ttychars, &sttymodes); ! 157: settchars(&ttychars, &tcharssave); ! 158: sttymodes.sg_flags|=RAW; ! 159: sttymodes.sg_flags&=~ECHO; ! 160: ioctl(0, TIOCSETP, &sttymodes); ! 161: devmodes.flags|=F8BIT; ! 162: ioctl(0, TIOCSDEV, &devmodes); ! 163: signal(SIGPIPE, (int (*)())1); ! 164: #ifdef TRACING ! 165: tracefd=fopen(tracefile, "w"); ! 166: #ifdef PDEBUG ! 167: ptracefd = tracefd; ! 168: #endif ! 169: #endif ! 170: #if TRACING!=1 && PDEBUG==1 ! 171: ptracefd=fopen(tracefile, "w"); ! 172: #endif ! 173: if(boot(jerqprog)) ! 174: quit("can't boot terminal program"); ! 175: booted++; ! 176: ioctl(0, TIOCEXCL, 0); ! 177: trace(0, 0); ! 178: trace("start\n", 0); ! 179: for(n=0; n<NSPEEDS; n++) ! 180: if(speeds[n].speed<=devmodes.ospeed) ! 181: break; ! 182: n=speeds[n].bytes; ! 183: Pxtimeout=max((((NLAYERS-2)*sizeof(struct Packet)*NPCBUFS+n-1)/n), 3); ! 184: Prtimeout=max(((sizeof(struct Packet)+n-1)/n), 2); ! 185: Pscanrate=1; ! 186: trace("speed = %d", n); ! 187: trace(" xtimo = %d", Pxtimeout); ! 188: trace(" rtimo = %d\n", Prtimeout); ! 189: Pxfdesc=1; ! 190: if(pinit(NLAYERS)==-1) ! 191: quit("bad protocol initialization"); ! 192: buf[0]=JTIMO; ! 193: buf[1]=Prtimeout; ! 194: buf[2]=Pxtimeout; ! 195: if (jerqstart && (n = strlen(jerqstart)) <= MAXPKTDSIZE-3) { ! 196: strncpy(&buf[3], jerqstart, n); ! 197: n += 3; ! 198: } else ! 199: n = 3; ! 200: (void)psend(0, buf, n); ! 201: while(scan()!=-1){ ! 202: if(quitflag) ! 203: quit(NULL); ! 204: ifdeftracing(fflush(tracefd)); ! 205: } ! 206: trace("errno = %d\n", errno); ! 207: quit("select"); ! 208: } ! 209: scan() ! 210: { ! 211: register fd, bit, n, ret=0; ! 212: ! 213: trace(0, 0); ! 214: trace("enabled %o\n", enabled); ! 215: if(blocked){ /* try to clear blocked channels */ ! 216: for(fd=0, bit=1; fd<NSELFD; fd++, bit<<=1) ! 217: if((bit&blocked) && ! 218: psend(layer[fd].bchan, layer[fd].bbuf, layer[fd].bcount)!=-1){ ! 219: blocked&=~bit; ! 220: return 0; ! 221: } ! 222: } ! 223: rdfd.fds_bits[0]=enabled&~blocked; ! 224: while(select(NSELFD, &rdfd, (fd_set *)0, SELTIMO)==-1){ ! 225: if(errno!=EINTR) ! 226: return -1; ! 227: ret++; ! 228: } ! 229: trace(0, 0); ! 230: trace("selected %o\n", rdfd.fds_bits[0]); ! 231: if(rdfd.fds_bits[0]==0) { ! 232: if(Ptflag) ! 233: ptimeout(SIGALRM); ! 234: }else for(fd=0, bit=1; fd<NSELFD; fd++, bit<<=1) ! 235: if(bit&rdfd.fds_bits[0]){ ! 236: while((n=read(fd, buf, sizeof buf))==-1) ! 237: if(errno!=EINTR) ! 238: return -1; ! 239: else{ ! 240: trace("read error, errno=%d\n", errno); ! 241: return 0; ! 242: } ! 243: ifdeftracing(if(n==0) trace("0 byte read", 0)); ! 244: if(fd==0){ ! 245: if(n==0) ! 246: quit("EOF on jerq"); ! 247: tread(buf, n); ! 248: precv(buf, n); ! 249: } else if(unpack(fd, buf, n)) ! 250: enabled&=~bit; ! 251: } ! 252: return ret; /* used in quit */ ! 253: } ! 254: psend_hold(chan, bufp, count, fd) ! 255: int chan; ! 256: register char *bufp; ! 257: int count; ! 258: register fd; ! 259: { ! 260: int ret; ! 261: register i; ! 262: if((ret=psend(chan, bufp, count))==-1){ ! 263: trace("psend hold on fd %d\n", fd); ! 264: layer[fd].bchan=chan; ! 265: layer[fd].bcount=count; ! 266: for(i=0; i<count; i++) ! 267: layer[fd].bbuf[i]=bufp[i]; ! 268: blocked|=1<<fd; ! 269: } ! 270: return ret; ! 271: } ! 272: quit(s) ! 273: register char *s; ! 274: { ! 275: register l, i; ! 276: ! 277: ifdeftracing(trace("\nmux: %s\n", s); trace(0, 0); fflush(tracefd)); ! 278: if(booted){ ! 279: for(i=0; i<NSELFD; i++) ! 280: if(layer[i].busy) ! 281: (void)close(i); ! 282: layer[0].chan=0; ! 283: sendioctl(0, JTERM); /* kill demux ==> boot terminal */ ! 284: for(i=Pxtimeout+1; Ptflag && i>0;){ ! 285: enabled=1; ! 286: if((l=scan())==-1) ! 287: break; ! 288: i-=l; ! 289: } ! 290: alarm(0); ! 291: } ! 292: ioctl(0, TIOCSDEV, &devsave); ! 293: ioctl(0, TIOCSETP, &sttysave); ! 294: ioctl(0, TIOCNXCL, 0); ! 295: sleep(2); ! 296: if (s) { ! 297: write(2, progname, strlen(progname)); ! 298: write(2, ": ", 2); ! 299: write(2, s, strlen(s)); ! 300: write(2, "\n", 1); ! 301: } ! 302: #ifdef PSTATISTICS ! 303: for(i=0, l=0; i<PS_NSTATS; i++) ! 304: if (pstats[i].count) { ! 305: if(l++==0) ! 306: fprintf(stderr, "\nPacket protocol statistics:\n"); ! 307: fprintf(stderr, "%6ld %s\n" ! 308: ,pstats[i].count ! 309: #ifdef PSTATSDESC ! 310: ,pstats[i].descp ! 311: #else ! 312: ,"" ! 313: #endif ! 314: ); ! 315: trace("%6ld ", pstats[i].count); ! 316: trace("%s\n", pstats[i].descp); ! 317: } ! 318: fflush(stderr); ! 319: #endif ! 320: #if TRACING == 1 || PDEBUG == 1 ! 321: fprintf(stderr, "\nThere are traces in '%s'\n", tracefile); ! 322: #endif ! 323: ifdeftracing(fflush(tracefd); abort()); ! 324: #ifdef MONITOR ! 325: monitor(0); ! 326: #endif ! 327: _exit(0); ! 328: } ! 329: /* ! 330: * Unpack a message buffer bp of length n. ! 331: */ ! 332: unpack(fd, bp, n) ! 333: register int fd; ! 334: char *bp; ! 335: int n; ! 336: { ! 337: register struct mesg *mp; ! 338: struct ttychars tempchars; ! 339: static char cdbuf[256]; ! 340: char *s; ! 341: register int size; ! 342: mp = (struct mesg *)bp; ! 343: size = mp->losize + (mp->hisize<<8); ! 344: trace("unpack fd %d", fd); ! 345: trace(" size %d", n); ! 346: trace(" count %d\n", size); ! 347: if(n<=0) ! 348: mp->type=M_HANGUP; ! 349: else if(layer[fd].more>0){ ! 350: layer[fd].more-=n; ! 351: return sendchars(fd, bp, n); ! 352: } ! 353: switch (mp->type) { ! 354: case M_HANGUP: ! 355: trace("shell died\n", 0); ! 356: wait((int *)0); ! 357: if(layer[fd].busy){ ! 358: sendioctl(fd, JDELETE); ! 359: /*(void)psend(layer[fd].chan, "Shell died.\n", 12);*/ ! 360: } ! 361: layer[fd].busy = 0; ! 362: close(fd); ! 363: enabled &= ~(1<<fd); ! 364: return 1; ! 365: case M_DELAY: ! 366: default: ! 367: trace("ignore type 0%o\n", mp->type); ! 368: return 0; ! 369: case M_DELIM: ! 370: case M_DATA: ! 371: if(size==0){ ! 372: trace("size 0 %s ignored\n", mp->type==M_DELIM? "delim" : "data"); ! 373: return 0; ! 374: } ! 375: break; ! 376: case M_IOCTL: ! 377: mp->type = M_IOCACK; ! 378: switch (*(int *)(bp+MSGHLEN)) { ! 379: case TIOCSETP: ! 380: case TIOCSETN: ! 381: tempchars=layer[fd].ttychars; ! 382: setmodes(&tempchars, (struct sgttyb *)(bp+MSGHLEN+sizeof(int))); ! 383: ttyset(fd, &tempchars); ! 384: size = 0; ! 385: break; ! 386: case TIOCGETP: ! 387: tempchars=layer[fd].ttychars; ! 388: getmodes(&tempchars, (struct sgttyb *)(bp+MSGHLEN+sizeof(int))); ! 389: size=sizeof(struct sgttyb)+sizeof(int); ! 390: ttyset(fd, &tempchars); ! 391: break; ! 392: case TIOCSETC: ! 393: tempchars=layer[fd].ttychars; ! 394: settchars(&tempchars, (struct tchars *)(bp+MSGHLEN+sizeof(int))); ! 395: ttyset(fd, &tempchars); ! 396: size=0; ! 397: break; ! 398: case TIOCGETC: ! 399: gettchars(&layer[fd].ttychars, (struct tchars *)(bp+MSGHLEN+sizeof(int))); ! 400: size=sizeof (struct tchars) + sizeof (int); ! 401: break; ! 402: case TIOCSDEV: ! 403: size=0; ! 404: break; ! 405: case TIOCGDEV: ! 406: size=sizeof(devsave)+sizeof(int); ! 407: *(struct ttydevb *)(bp+MSGHLEN+sizeof(int))=devsave; ! 408: break; ! 409: case JMUX: ! 410: size=0; ! 411: break; ! 412: case JWINSIZE: ! 413: *((int *)(bp+MSGHLEN))=JWINSIZE; /* answering JWINSIZE ioctl */ ! 414: #define BP ((struct winsize *)(bp+MSGHLEN+sizeof(int))) ! 415: BP->bytesx=layer[fd].dx; ! 416: BP->bytesy=layer[fd].dy; ! 417: BP->bitsx=layer[fd].bitsx; ! 418: BP->bitsy=layer[fd].bitsy; ! 419: size=sizeof(struct winsize)+sizeof(int); ! 420: break; ! 421: case JTERM: ! 422: case JBOOT: ! 423: case JZOMBOOT: ! 424: sendioctl(fd, *(int *)(bp+MSGHLEN)); ! 425: size=0; ! 426: break; ! 427: case JEXIT: ! 428: sendioctl(fd, *(int *)(bp+MSGHLEN)); ! 429: size=0; ! 430: break; ! 431: case JCHDIR: ! 432: s=bp+MSGHLEN+sizeof(int); ! 433: if(*s==0){ ! 434: if(chdir(cdbuf)!=0) ! 435: mp->type = M_IOCNAK; ! 436: cdbuf[0]=0; ! 437: }else ! 438: strcat(cdbuf, s); ! 439: size = 0; ! 440: break; ! 441: default: ! 442: mp->type = M_IOCNAK; ! 443: size = 0; ! 444: } ! 445: mp->magic = MSGMAGIC; /* safety net */ ! 446: mp->losize = size; ! 447: mp->hisize = size>>8; ! 448: write(fd, bp, MSGHLEN+size); ! 449: trace("unpack ioctl type '%c'", *(int *)(bp+MSGHLEN)>>8); ! 450: trace(" %d\n", *(int *)(bp+MSGHLEN)&0xff); ! 451: return 0; ! 452: } ! 453: if(size>MAXPKTDSIZE){ ! 454: layer[fd].more=size-MAXPKTDSIZE; ! 455: size=MAXPKTDSIZE; ! 456: } ! 457: return sendchars(fd, bp+MSGHLEN, size); ! 458: } ! 459: getmodes(tp, bp) ! 460: register struct ttychars *tp; ! 461: register struct sgttyb *bp; ! 462: { ! 463: bp->sg_ispeed=sttysave.sg_ispeed; ! 464: bp->sg_ospeed=sttysave.sg_ospeed; ! 465: bp->sg_flags=(tp->flags1<<8)|(tp->flags0&0xFF); ! 466: bp->sg_erase=tp->erase; ! 467: bp->sg_kill=tp->kill; ! 468: } ! 469: setmodes(tp, bp) ! 470: register struct ttychars *tp; ! 471: register struct sgttyb *bp; ! 472: { ! 473: tp->flags0=bp->sg_flags; ! 474: tp->flags1=bp->sg_flags>>8; ! 475: tp->erase=bp->sg_erase; ! 476: tp->kill=bp->sg_kill; ! 477: } ! 478: gettchars(tp, bp) ! 479: register struct ttychars *tp; ! 480: register struct tchars *bp; ! 481: { ! 482: bp->t_intrc=tp->intrc; ! 483: bp->t_quitc=tp->quitc; ! 484: bp->t_startc=tp->startc; ! 485: bp->t_stopc=tp->stopc; ! 486: bp->t_eofc=tp->eofc; ! 487: bp->t_brkc=tp->brkc; ! 488: } ! 489: settchars(tp, bp) ! 490: register struct ttychars *tp; ! 491: register struct tchars *bp; ! 492: { ! 493: tp->intrc=bp->t_intrc; ! 494: tp->quitc=bp->t_quitc; ! 495: tp->startc=bp->t_startc; ! 496: tp->stopc=bp->t_stopc; ! 497: tp->eofc=bp->t_eofc; ! 498: tp->brkc=bp->t_brkc; ! 499: } ! 500: ttyset(fd, tp) ! 501: struct ttychars *tp; ! 502: { ! 503: register char *p, *q; ! 504: register i; ! 505: static struct ttycmesg m={JTTYC}; ! 506: for(i=0, p=(char *)tp, q=(char *)&layer[fd].ttychars; *p++==*q++; i++) ! 507: if(i>=sizeof(struct ttychars)) ! 508: return; /* no need to send; they're identical */ ! 509: m.chan=layer[fd].chan; ! 510: layer[fd].ttychars = *tp; ! 511: m.ttychars = *tp; ! 512: (void)psend_hold(0, (char *)&m, sizeof m, fd); ! 513: } ! 514: sendioctl(fd, cmd) ! 515: { ! 516: char ioctlvec[2]; ! 517: ioctlvec[0]=cmd; ! 518: ioctlvec[1]=layer[fd].chan; ! 519: if(psend_hold(0, ioctlvec, sizeof ioctlvec, fd)!=-1) ! 520: unblock(fd); ! 521: } ! 522: int ! 523: sendchars(fd, s, cc) ! 524: char *s; ! 525: int cc; ! 526: { ! 527: register int l=layer[fd].chan; ! 528: register int n; ! 529: ! 530: # ifdef TRACING ! 531: char buf[256]; ! 532: trace("write %d chars ", cc); ! 533: trace("to layer %d\n", l); ! 534: strncpy(buf, s, cc); ! 535: buf[cc]=0; ! 536: trace("<%s>\n", buf); ! 537: # endif ! 538: if(fd!=0 && layer[fd].busy==0) ! 539: return 0; /* layer was deleted, but there's still data */ ! 540: if(cc>0) ! 541: do{ ! 542: if((n=cc)>MAXPKTDSIZE) ! 543: n=MAXPKTDSIZE; ! 544: if(psend(l, s, n)==-1){ ! 545: trace("layer %d blocked\n", l); ! 546: return fd; /* BUG */ ! 547: } ! 548: }while(s+=n, (cc-=n)>0); ! 549: unblock(fd); ! 550: return 0; ! 551: } ! 552: unblock(fd) ! 553: int fd; ! 554: { ! 555: register Pch_p pcp= &pconvs[layer[fd].chan]; ! 556: ! 557: trace("unblock for layer %d", layer[fd].chan); ! 558: trace(" freepkts=%d\n", pcp->freepkts); ! 559: if(fd==0) ! 560: return; ! 561: if(pcp->freepkts>=1) ! 562: enabled|=1<<fd; ! 563: else ! 564: enabled&=~(1<<fd); ! 565: } ! 566: void ! 567: lerror(l, s, t) ! 568: int l; ! 569: char *s, t; ! 570: { ! 571: char ebuf[128]; ! 572: int busy; ! 573: strcpy(ebuf, s); ! 574: if(errno){ ! 575: strcat(ebuf, ": "); ! 576: if(errno < sys_nerr) ! 577: strcat(ebuf, sys_errlist[errno]); ! 578: else{ ! 579: strcat(ebuf, "error "); ! 580: strcat(ebuf, itoa(errno)); ! 581: } ! 582: errno=0; ! 583: } ! 584: strcat(ebuf, "\n"); ! 585: trace("lerror type %d", t); ! 586: trace(" for layer %d", l); ! 587: trace(" %s\n", ebuf); ! 588: layer[0].chan=l; ! 589: sendchars(0, ebuf, strlen(ebuf)); ! 590: } ! 591: int ! 592: creceive(l, s, n) ! 593: char *s; ! 594: { ! 595: if(s[0]!=C_UNBLK || n!=1) ! 596: quit("bad control type"); ! 597: (void)receive(l, s, n); ! 598: } ! 599: int ! 600: receive(l, s, cc) ! 601: int l; ! 602: register char *s; ! 603: register int cc; ! 604: { ! 605: register int i; ! 606: struct mesg hupmsg; ! 607: if((i=ltofd(l))==-1) ! 608: switch(*s){ ! 609: case C_NEW: ! 610: case C_EXIT: ! 611: break; ! 612: default: ! 613: errno = 0; ! 614: lerror(l, "inactive layer", *s); ! 615: case C_UNBLK: ! 616: return 0; ! 617: } ! 618: while(cc--){ ! 619: trace("receive C type %d", *s); ! 620: trace(" for layer %d", l); ! 621: trace(" fd %d\n", i); ! 622: switch(*s++){ ! 623: case C_SENDCHAR: /* send layer char */ ! 624: wrmesgb(i, s++, 1); ! 625: delim(i); ! 626: cc--; ! 627: break; ! 628: case C_DELIM: /* send delimiter */ ! 629: delim(i); ! 630: break; ! 631: case C_NEW: /* make layer */ ! 632: if((i=doshell())==-1){ ! 633: lerror(l, umesgf, C_NEW); ! 634: trace("can't open %s\n", umesgf); ! 635: cc-=6; ! 636: break; ! 637: } ! 638: layer[i].busy=1; ! 639: layer[i].chan=l; ! 640: ttyset(i, &ttychars); ! 641: trace("new fd %d ", i); ! 642: trace("layer %d ", l); ! 643: enabled |= (1<<i); ! 644: case C_RESHAPE: ! 645: layer[i].dx= *s++; ! 646: trace("x wid %d ", layer[i].dx); ! 647: layer[i].dy= *s++; ! 648: trace("y wid %d\n", layer[i].dy); ! 649: layer[i].bitsx=(unsigned char)*s++; ! 650: layer[i].bitsx|=(*s++)<<8; ! 651: layer[i].bitsy=(unsigned char)*s++; ! 652: layer[i].bitsy|=(*s++)<<8; ! 653: cc-=6; ! 654: break; ! 655: case C_UNBLK: /* unblock layer */ ! 656: unblock(i); ! 657: break; ! 658: case C_PUSHLD: /* push ld onto stream */ ! 659: pushld(i); ! 660: break; ! 661: case C_POPLD: /* pop ld from stream */ ! 662: popld(i); ! 663: break; ! 664: case C_DELETE: /* delete layer */ ! 665: hupmsg.losize=0; ! 666: hupmsg.hisize=0; ! 667: hupmsg.magic=MSGMAGIC; ! 668: hupmsg.type=M_HANGUP; ! 669: write(i, (char *)&hupmsg, MSGHLEN); ! 670: layer[i].busy=0; ! 671: pconvs[layer[i].chan].freepkts=1; /* hack */ ! 672: unblock(i); ! 673: layer[i].ttychars=zerochars; ! 674: break; ! 675: case C_EXIT: /* exit */ ! 676: quitflag++; ! 677: return 0; ! 678: case C_SENDNCHARS: /* send cc characters */ ! 679: wrmesgb(i, s, cc); ! 680: return 0; ! 681: case C_KILL: /* send layer signal */ ! 682: dosig(i, *s++); ! 683: cc--; ! 684: break; ! 685: default: ! 686: quit("unknown state incase 0"); ! 687: } ! 688: ifdeftracing(if(cc<0) quit("bad count in receive")); ! 689: } ! 690: return 0; ! 691: } ! 692: int ! 693: ltofd(l) ! 694: { ! 695: register i; ! 696: if(l==0) ! 697: return 0; ! 698: for(i=1; i<NSELFD; i++) ! 699: if(layer[i].busy && layer[i].chan==l) ! 700: return i; ! 701: trace("unknown layer %d\n", l); ! 702: return -1; ! 703: } ! 704: void ! 705: dosig(fd, sig) /* Interrupt shell */ ! 706: { ! 707: char sigbuf[MSGHLEN+1]; ! 708: register struct mesg *mp; ! 709: ! 710: mp = (struct mesg *)sigbuf; ! 711: mp->type=M_SIGNAL; ! 712: mp->magic=MSGMAGIC; ! 713: mp->losize=sizeof(char); ! 714: mp->hisize=0; ! 715: sigbuf[MSGHLEN]=sig; ! 716: write(fd, sigbuf, MSGHLEN+1); ! 717: mp->type=M_FLUSH; ! 718: mp->magic=MSGMAGIC; ! 719: mp->losize=0; ! 720: mp->hisize=0; ! 721: write(fd, sigbuf, MSGHLEN); ! 722: } ! 723: void ! 724: wrmesgb(fd, cp, n) ! 725: register char *cp; ! 726: int n; ! 727: { ! 728: char wrbuf[MAXPKTDSIZE+MSGHLEN]; ! 729: register char *bp; ! 730: register struct mesg *mp; ! 731: register int i; ! 732: ! 733: ifdeftracing(fprintf(tracefd, "mesg to fd %d: <%.*s>\n", fd, n, cp)); ! 734: mp = (struct mesg *)wrbuf; ! 735: mp->type=M_DATA; ! 736: mp->magic=MSGMAGIC; ! 737: mp->losize=n; ! 738: mp->hisize=n>>8; ! 739: bp=wrbuf+MSGHLEN; ! 740: i=n; ! 741: while(i--) ! 742: *bp++= *cp++; ! 743: write(fd, wrbuf, MSGHLEN+n); ! 744: } ! 745: delim(fd) ! 746: { ! 747: struct mesg delbuf; ! 748: ! 749: ifdeftracing(fprintf(tracefd, "delim fd %d\n", fd)); ! 750: delbuf.type=M_DELIM; ! 751: delbuf.magic=MSGMAGIC; ! 752: delbuf.losize=0; ! 753: delbuf.hisize=0; ! 754: write(fd, (char *)&delbuf, MSGHLEN); ! 755: } ! 756: popld(fd) ! 757: { ! 758: register f, i; ! 759: struct ttychars tempchars; ! 760: struct sgttyb tb; ! 761: struct tchars tc; ! 762: errno=0; ! 763: if((f=open(layer[fd].ptfile, 2))>0){ ! 764: if((i=ioctl(f, FIOLOOKLD, 0))==tty_ld) { ! 765: i=0; ! 766: if(ioctl(f, TIOCGETP, &tb)<0 ! 767: || ioctl(f, TIOCGETC, &tc)<0) ! 768: i=1; /* hack for old systems */ ! 769: ioctl(f, FIOPOPLD, (struct sgttyb *)0); ! 770: if(i==0){ ! 771: setmodes(&tempchars, &tb); ! 772: settchars(&tempchars, &tc); ! 773: ttyset(fd, &tempchars); ! 774: } ! 775: } ! 776: else if(i>=0) ! 777: lerror(layer[fd].chan, "mux warning: unknown line discipline", 0); ! 778: } ! 779: close(f); ! 780: trace("popld file %s\n", layer[fd].ptfile); ! 781: trace("popld file descriptor %d\n", f); ! 782: } ! 783: pushld(fd) ! 784: { ! 785: register f, i; ! 786: int tty; ! 787: struct tchars tc; ! 788: struct sgttyb tb; ! 789: if((f=open(layer[fd].ptfile, 2))>0){ ! 790: if((i=ioctl(f, FIOLOOKLD, 0))==-1){ ! 791: ioctl(f, FIOPUSHLD, (struct sgttyb *)&tty_ld); ! 792: getmodes(&layer[fd].ttychars, &tb); ! 793: gettchars(&layer[fd].ttychars, &tc); ! 794: ioctl(f, TIOCSETP, &tb); ! 795: ioctl(f, TIOCSETC, &tc); ! 796: }else ! 797: ; /* can't warn; program could be e.g. jim! */ ! 798: } ! 799: trace("pushld errno file %d\n", errno); ! 800: close(f); ! 801: trace("pushld file descriptor file %s\n", layer[fd].ptfile); ! 802: } ! 803: int ! 804: doshell() ! 805: { ! 806: register fd, slave; ! 807: trace("do shell\n", 0); ! 808: if((fd=ptopen(umesgf))<0){ ! 809: trace("can't open %s\n", umesgf); ! 810: return -1; ! 811: } ! 812: if((slave=open(umesgf, 2))==-1){ ! 813: trace("can't open %s\n", umesgf); ! 814: close(fd); ! 815: return -1; ! 816: } ! 817: trace("opened %s\n", umesgf); ! 818: strcpy(layer[fd].ptfile, umesgf); ! 819: if(ioctl(fd, FIOPUSHLD, &mesg_ld) == -1){ ! 820: trace("FIOPUSHLD fails, errno=%d\n", errno); ! 821: close(fd); ! 822: return -1; ! 823: } ! 824: switch(fork()){ ! 825: case 0: ! 826: /* close every file descriptor in sight, and then some */ ! 827: for(fd=0; fd<5+NLAYERS; fd++) ! 828: if(fd!=slave) ! 829: close(fd); ! 830: dup(slave); dup(slave); dup(slave); dup(slave); ! 831: close(slave); ! 832: ioctl(0, TIOCSPGRP, 0); ! 833: signal(SIGPIPE, (int (*)())0); ! 834: execlp(shell, shell, 0); ! 835: perror(shell); ! 836: exit(1); ! 837: break; ! 838: case -1: ! 839: close(fd); ! 840: return -1; ! 841: } ! 842: trace("doshell succeeds\n", 0); ! 843: close(slave); ! 844: return fd; ! 845: } ! 846: int ! 847: boot(s) ! 848: char *s; ! 849: { ! 850: if(system("/usr/jerq/bin/32ld", "32ld", s)) ! 851: return 1; ! 852: sleep(2); ! 853: return 0; ! 854: } ! 855: int ! 856: system(s, t, u) ! 857: char *s, *t, *u; ! 858: { ! 859: int status, pid, l; ! 860: ! 861: if ((pid=fork())==0){ ! 862: execl(s, t, u, 0); ! 863: _exit(127); ! 864: } ! 865: while ((l = wait(&status)) != pid && l != -1) ! 866: ; ! 867: if (l == -1) ! 868: status = -1; ! 869: return(status); ! 870: } ! 871: char * ! 872: itoa(i) ! 873: register int i; ! 874: { ! 875: static char str[11]; ! 876: register char * sp = &str[sizeof str]; ! 877: ! 878: *--sp = '\0'; ! 879: if(i>0){ ! 880: do ! 881: *--sp=i%10+'0'; ! 882: while((i/=10)>0); ! 883: }else ! 884: *--sp='0'; ! 885: return sp; ! 886: } ! 887: service(argc, argv) ! 888: char *argv[]; ! 889: { ! 890: if(strcmp(argv[0], "cd")==0){ ! 891: char *where=argv[1]; ! 892: char buf[CDSIZE+1]; ! 893: buf[CDSIZE]=0; ! 894: if(where==0 && (where=getenv("HOME"))==0){ ! 895: write(2, "cd: no HOME set\n", 16); ! 896: return 1; ! 897: } ! 898: while(*where){ ! 899: strncpy(buf, where, CDSIZE); ! 900: ioctl(0, JCHDIR, buf); ! 901: where+=strlen(buf); ! 902: } ! 903: if(ioctl(0, JCHDIR, where)!=0){ ! 904: write(2, "cd: bad directory\n", 18); ! 905: return 1; ! 906: } ! 907: return 0; ! 908: } ! 909: if(strcmp(argv[0], "exit")==0) ! 910: return ioctl(0, JEXIT, 0); ! 911: write(2, "mux: no such command ", 21); ! 912: write(2, argv[0], strlen(argv[0])); ! 913: write(2, "\n", 1); ! 914: return 1; ! 915: } ! 916: #ifdef TRACING ! 917: /*VARARGS1*/ ! 918: void ! 919: trace(s, a) ! 920: char *s, *a; ! 921: { ! 922: long t; ! 923: extern long time(); ! 924: extern char *ctime(); ! 925: ! 926: if(s) ! 927: fprintf(tracefd, s, a); ! 928: else{ ! 929: (void)time(&t); ! 930: fprintf(tracefd, "%.9s", ctime(&t)+11); ! 931: } ! 932: } ! 933: int ! 934: twrite(fd, s, n) ! 935: unsigned char * s; ! 936: { ! 937: register i; ! 938: fprintf(tracefd, "to jerq: "); ! 939: for(i=0; i<n; i++) ! 940: fprintf(tracefd, "<%o>", s[i]); ! 941: fprintf(tracefd, "\n"); ! 942: return write(fd, s, n); ! 943: } ! 944: void ! 945: tread(s, n) ! 946: unsigned char * s; ! 947: { ! 948: register i; ! 949: fprintf(tracefd, "from jerq: "); ! 950: for(i=0; i<n; i++) ! 951: fprintf(tracefd, "<%o>", s[i]); ! 952: fprintf(tracefd, "\n"); ! 953: } ! 954: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.