Annotation of researchv9/jtools/src/pads/host/term.c, revision 1.1.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.