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