|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.