Annotation of researchv9/jtools/src/pads/host/term.c, revision 1.1

1.1     ! root        1: #include <ctype.h>
        !             2: #include <pads.pri>
        !             3: #include <CC/sys/types.h>
        !             4: #include <CC/sys/stat.h>
        !             5: #ifdef BSD
        !             6: #include <sys/socket.h>
        !             7: #endif BSD
        !             8: SRCFILE("term.c")
        !             9: 
        !            10: void Pick( char *s, Action a, long o )
        !            11: {
        !            12:        Index ix;
        !            13: 
        !            14:        trace("Pick(%d,%d)", a, o);
        !            15:        ix = ICache->place(Item(s, a, o));
        !            16:        R->pktstart( P_PICK );
        !            17:        R->sendshort( ix.sht() );
        !            18:        R->pktend();
        !            19: }
        !            20: 
        !            21: char *JerqTERM[] = {   "/usr/jerq/bin/32ld /usr/jerq/mbin/pads.m",
        !            22:                        "5620", "jerq", "JERQ", "Jerq", "DMD", "DMD5620",
        !            23:                        0 };
        !            24: 
        !            25: char *BlitTERM[] = {   "/usr/blit/bin/68ld /usr/blit/mbin/pads.m",
        !            26:                        "blit", "BLIT", "Blit",
        !            27:                        0 };
        !            28: 
        !            29: char *XTERM[] = {      "pads",
        !            30:                        "xterm", "sun",
        !            31:                        0 };
        !            32: 
        !            33: char **MapTERM[] = { JerqTERM, BlitTERM, XTERM, 0 };
        !            34: 
        !            35: int pipe(int[2]), fork(), _exit(int);
        !            36: #ifdef BSD
        !            37: int socketpair(int,int,int,int[2]);
        !            38: #endif BSD
        !            39: 
        !            40: char *PadsInit(char *loadcmd)
        !            41: {
        !            42:        trace( "PadsInit(%s)", loadcmd );
        !            43:        if( !loadcmd ){
        !            44:                char *getenv(char*), *TERM = getenv("TERM"), ***map, **term;
        !            45:                loadcmd = MapTERM[0][0];
        !            46:                for( map = MapTERM; TERM && *map; ++map )
        !            47:                        for( term = *map, ++term; *term; ++term )
        !            48:                                if( !strcmp(TERM, *term) )
        !            49:                                        loadcmd = **map;
        !            50:        }
        !            51:        if( loadcmd == XTERM[0] ){
        !            52:                int afildes[2], pid;
        !            53: #ifdef BSD
        !            54:                if( socketpair(AF_UNIX, SOCK_STREAM, 0, afildes)==-1 )
        !            55: #else
        !            56:                if( pipe(afildes)==-1 )
        !            57: #endif BSD
        !            58:                        return "can't open pipe\n";
        !            59:                if( (pid=fork())==0 ){
        !            60:                        dup2(afildes[0], 0);
        !            61:                        dup2(afildes[0], 1);
        !            62:                        close(afildes[0]);
        !            63:                        close(afildes[1]);
        !            64:                        execlp(loadcmd, "pads", (char *)0);
        !            65:                        _exit(1);
        !            66:                }
        !            67:                if(pid==-1)
        !            68:                        return "terminal fork failed";
        !            69:                close(afildes[0]);
        !            70:                R = new Remote(afildes[1]);
        !            71:        }
        !            72:        else {
        !            73:                if ( system(loadcmd) ) return "terminal download failed";
        !            74:                R = new Remote("/dev/tty");
        !            75:        }
        !            76:        R->pktstart(P_VERSION); R->sendlong(PADS_VERSION); R->pktend();
        !            77:        R->pktstart(P_BUSY); R->pktend();
        !            78:        ICache = new ItemCache;
        !            79:        CCache = new CarteCache;
        !            80:        close(2);
        !            81:        return 0;
        !            82: }
        !            83: 
        !            84: char *PadsTermInit(char *machine)
        !            85: {
        !            86:        char *loadcmd =  XTERM[0];
        !            87:        int afildes[2], pid;
        !            88: #ifdef BSD
        !            89:        if( socketpair(AF_UNIX, SOCK_STREAM, 0, afildes)==-1 )
        !            90: #else
        !            91:        if( pipe(afildes)==-1 )
        !            92: #endif BSD
        !            93:                return "can't open pipe\n";
        !            94:        if( (pid=fork())==0 ){
        !            95:                dup2(afildes[0], 0);
        !            96:                dup2(afildes[0], 1);
        !            97:                close(afildes[0]);
        !            98:                close(afildes[1]);
        !            99:                execlp(loadcmd, "pads", (char *)0);
        !           100:                _exit(1);
        !           101:        }
        !           102:        if(pid==-1)
        !           103:                return "terminal fork failed";
        !           104:        dup2(afildes[1], 0);
        !           105:        dup2(afildes[1], 1);
        !           106:        dup2(afildes[1], 2);
        !           107:        close(afildes[0]);
        !           108:        close(afildes[1]);
        !           109:        execlp("rsh", machine, "exec /usr/jerq/bin/pi -R", 0);
        !           110:        exit(127);
        !           111:        return 0;
        !           112: }
        !           113: 
        !           114: void PadsRemInit()
        !           115: {
        !           116:        R = new Remote(0);
        !           117:        R->pktstart(P_VERSION); R->sendlong(PADS_VERSION); R->pktend();
        !           118:        R->pktstart(P_BUSY); R->pktend();
        !           119:        ICache = new ItemCache;
        !           120:        CCache = new CarteCache;
        !           121: }
        !           122: 
        !           123: char *TapTo;
        !           124: void WireTap(PRINTF_ARGS)
        !           125: {
        !           126:        static int fd = -1;
        !           127:        static long t0;
        !           128:        struct stat s;
        !           129:        char *ctime(long*);
        !           130:        long t, time(long*);
        !           131: 
        !           132:        if( !TapTo ) return;
        !           133:        t = time(0);
        !           134:        if( ::stat("/usr/jerq/lib/.logpads", &s) || ctime(&t)[23]!='6' )
        !           135:                goto BailOut;
        !           136:        if( t0 )
        !           137:                t -= t0;
        !           138:        else
        !           139:                t0 = t;
        !           140:        char buf[256];
        !           141:        sprintf(buf, "%x:", t);
        !           142:        sprintf(buf+strlen(buf), PRINTF_COPY);
        !           143:        if( fd < 0 ){
        !           144:                if( ::stat(TapTo, &s) )
        !           145:                        creat(TapTo, 0777); 
        !           146:                fd = open(TapTo, 1);
        !           147:        }
        !           148: #define PILOGSIZE 32000
        !           149:        if( fd<0
        !           150:         || fstat(fd, &s)
        !           151:         || s.st_size > PILOGSIZE )
        !           152:                        goto BailOut;
        !           153:        lseek(fd, s.st_size, 0);
        !           154:        write(fd, buf, strlen(buf));
        !           155:        return;
        !           156: BailOut:
        !           157:        TapTo = 0;
        !           158: }
        !           159: 
        !           160: int BothValid(PadRcv *p, PadRcv *o)
        !           161: {
        !           162:        return p && o;
        !           163: }
        !           164: 
        !           165: void TermAction(PadRcv *parent, PadRcv *obj, int pick)
        !           166: {
        !           167:        Item *item;
        !           168:        Index ix(R->rcvshort());
        !           169: 
        !           170:        trace( "TermAction(%d,%d,%d)", parent, obj, pick );
        !           171:        if( ix.null() ) return;
        !           172:        item = ICache->take(ix);
        !           173:        if( !BothValid(parent,obj)
        !           174:         || (pick && !obj->accept(item->action)) )
        !           175:                return;
        !           176:        Action a = item->action;
        !           177:        long faddr, ixorf = (int) a;                    // yuk: can't say
        !           178:        if( ixorf & (~127) )                            // &(obj->*item->action)
        !           179:                faddr = ixorf;                          //
        !           180:        else                                            //
        !           181:                faddr = ((long**) obj)[1][ixorf-1];     //
        !           182:        WireTap("%x->%x(%x)\n", obj, faddr, item->opand);
        !           183:        if( item->action ) (obj->*item->action)(item->opand, 0, 0);
        !           184: }
        !           185: 
        !           186: char *DoKbd(PadRcv *obj, char *buf)
        !           187: {
        !           188:        WireTap("%x->%x(%x) %s\n", obj, &obj->kbd, strlen(buf), buf);
        !           189:        char *e = obj->kbd(buf);
        !           190:        if( e ) PadsWarn("%s", e);
        !           191:        return e;
        !           192: }
        !           193: 
        !           194: void Shell()
        !           195: {
        !           196:        char cmd[256];
        !           197:        R->rcvstring(cmd);
        !           198:        FILE *fp = Popen(cmd, "w");
        !           199:        for( long lines = R->rcvlong(); lines>0; --lines ){
        !           200:                char data[256];
        !           201:                if( fp ) fprintf(fp, "%s\n", R->rcvstring(data));
        !           202:        }
        !           203:        if( !fp ){
        !           204:                PadsWarn("cannot write to pipe");
        !           205:                return;
        !           206:        }
        !           207:        int x = Pclose(fp);
        !           208:        if( x ) PadsWarn( "exit(%d): %s", x, cmd );
        !           209: }
        !           210: 
        !           211: void ShKbd(PadRcv *obj, char *cmd)
        !           212: {
        !           213:        trace( "ShKbd(%d,%s)", obj, buf );
        !           214:        FILE *fp = Popen(cmd, "r");
        !           215:        if( !fp ){
        !           216:                PadsWarn("cannot read from pipe");
        !           217:                return;
        !           218:        }
        !           219:        char buf[256];
        !           220:        while( fgets(buf, sizeof buf, fp) ){
        !           221:                buf[strlen(buf)-1] = 0;
        !           222:                if( DoKbd(obj, buf) ) break;
        !           223:        }
        !           224:        int x = Pclose(fp);
        !           225:        if( x ) PadsWarn( "exit(%d): %s", x, cmd );
        !           226: }
        !           227: 
        !           228: void Kbd(PadRcv *parent, PadRcv *obj)
        !           229: {
        !           230:        char buf[256];
        !           231:        R->rcvstring(buf);
        !           232:        trace( "Kbd %d %s", obj, buf );
        !           233:        if( !BothValid(parent,obj) ) return;
        !           234:        if( !strcmp( buf, "?" ) ){
        !           235:                char *h = obj->help();
        !           236:                PadsWarn( "%s", (h && *h) ? h : "error: null help string" );
        !           237:        } else if( buf[0] == '<' ){
        !           238:                ShKbd(obj, buf+1);
        !           239:        } else
        !           240:                DoKbd(obj, buf);
        !           241: }
        !           242: 
        !           243: void TermServe()
        !           244: {
        !           245:        Protocol p;
        !           246:        long n, to, pick = 0;
        !           247: 
        !           248:        trace("TermServe()");
        !           249:        R->writesize = 0;
        !           250:        R->pktstart(P_IDLE); R->pktend();       /* flush */
        !           251:        p = (Protocol) R->get();
        !           252:        if( p == P_PICK ) {
        !           253:                pick = 1;
        !           254:                p = (Protocol) R->get();
        !           255:        }
        !           256:        PadRcv *par = R->rcvobj();
        !           257:        PadRcv *obj = R->rcvobj();
        !           258:        if( p != P_CYCLE ) { R->writesize = 0; R->pktstart(P_BUSY); R->pktend(); }
        !           259:        switch( (int) p ){
        !           260:                case P_ACTION:
        !           261:                        TermAction(par, obj, pick);
        !           262:                        break;
        !           263:                case P_KBDSTR:
        !           264:                        Kbd(par, obj);
        !           265:                        break;
        !           266:                case P_SHELL:
        !           267:                        Shell();
        !           268:                        break;
        !           269:                case P_NUMERIC:
        !           270:                case P_CYCLE:
        !           271:                case P_USERCLOSE:
        !           272:                case P_USERCUT:
        !           273:                        n = R->rcvshort();
        !           274:                        if( !BothValid(par,obj) ) return;
        !           275:                        switch( (int) p ){
        !           276:                        case P_NUMERIC:
        !           277:                                WireTap("%x->%x(%x)\n", obj, &obj->numeric, n);
        !           278:                                obj->numeric(n);        break;
        !           279:                        case P_CYCLE:
        !           280:                                obj->cycle();           break;
        !           281:                        case P_USERCLOSE:
        !           282:                                WireTap("%x->%x(0)\n", obj, &obj->userclose);
        !           283:                                obj->userclose();       break;
        !           284:                        case P_USERCUT  :
        !           285:                                WireTap("%x->%x(0)\n", obj, &obj->usercut);
        !           286:                                obj->usercut();         break;
        !           287:                        default: R->err();
        !           288:                        }
        !           289:                        break;
        !           290:                case P_LINEREQ:
        !           291:                        n = R->rcvlong();
        !           292:                        to = R->rcvlong();
        !           293:                        trace("P_LINEREQ %d %d %d", p, n, to);
        !           294:                        if( !BothValid(par,obj) ) return;
        !           295: //                     WireTap("%x->%x(%x)", obj, &obj->linereq, to-n+1);
        !           296:                        while( n <= to )
        !           297:                                obj->linereq((long) n++, 0);
        !           298:                        break;
        !           299:                default:
        !           300:                        R->err();
        !           301:        }
        !           302: }
        !           303: 
        !           304: void PadsServe(long n)
        !           305: {
        !           306:        if( n ){
        !           307:                while( n-->0 ) TermServe();
        !           308:        } else {
        !           309:                for( ;; )  TermServe();
        !           310:        }
        !           311: }
        !           312: 
        !           313: void PadsWarn(PRINTF_ARGS)
        !           314: {
        !           315:        char t[256];
        !           316:        sprintf( t, PRINTF_COPY );
        !           317:        R->pktstart( P_HELPSTR );
        !           318:        R->sendstring( t );
        !           319:        R->pktend();
        !           320: }
        !           321: 
        !           322: void PadsError(PRINTF_ARGS)
        !           323: {
        !           324:        char t[256];
        !           325:        sprintf(t, PRINTF_COPY);
        !           326:        int fd = open("/dev/tty", 1);
        !           327:        write(fd, "  ", 2);
        !           328:        write(fd, t, strlen(t));
        !           329:        abort();
        !           330: }

unix.superglobalmegacorp.com

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