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