Annotation of researchv10dc/630/src/mux.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.