|
|
1.1 root 1: #define MUXTERM
2: #define MPXTERM
3:
4: #include <jerq.h>
5: #include <font.h>
6: #include <menu.h>
7: #include "defs.h"
8:
9: #undef getname /* strange hack to avoid name clash */
10:
11: /* user nice sys queue idle */
12: Texture black={
13: 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
14: 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
15: };
16: Texture white={
17: 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
18: 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
19: };
20: Texture darkgrey = {
21: 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777,
22: 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777,
23: };
24: Texture lightgrey = {
25: 0x2222, 0x8888, 0x2222, 0x8888, 0x2222, 0x8888, 0x2222, 0x8888,
26: 0x2222, 0x8888, 0x2222, 0x8888, 0x2222, 0x8888, 0x2222, 0x8888,
27: };
28: Texture grey = {
29: 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555,
30: 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555, 0xAAAA, 0x5555,
31: };
32: Texture *txt[]={
33: &black, &lightgrey, &darkgrey, &grey, &white
34: };
35:
36: # define TIMELEN 6
37: char time[TIMELEN];
38: # define NAMELEN 9
39: # define LOADLEN 13
40: # define MAILLEN 18
41:
42: struct nodedef {
43: Rectangle bar; /* the bar graph of system use */
44: char name[NAMELEN]; /* node name */
45: char load[LOADLEN]; /* load numbers */
46: int vec[5]; /* current use vectors */
47: int oldvec[5]; /* old use vectors */
48: char mail[MAILLEN]; /* last mail from this node */
49: };
50: struct nodedef node0; /* preallocate node 0 */
51: int nodes = 0; /* number of nodes */
52: struct nodedef *node[MAXMACHS] = {
53: &node0
54: };
55:
56: /* size contraints */
57: #define ICONSEP 2
58: #define BARHEIGHT 18
59: #define MINBARHEIGHT 4
60: #define MAXBARHEIGHT 24
61: #define TIMEORIGIN 2
62: int CHARHEIGHT;
63: int CHARWIDTH;
64: int TIMECORNER;
65: int LOADORIGIN;
66: int LOADCORNER;
67: int MAILORIGIN;
68: int MAILCORNER;
69:
70: int size;
71: int barheight;
72: int iconorigin;
73:
74: /* the communications process */
75: struct Proc *cwp;
76:
77: /* icon info */
78: #define ICONSIZE 48
79: #define ICONWORDS (ICONSIZE*(ICONSIZE/16))
80: Bitmap *icon, *ticon;
81: int icons = 0;
82: int maxicons;
83: int haveicons = 0;
84:
85: /* dynamically add/remove monitored systems */
86:
87: static NMitem astroitems[] = {
88: {"alice"},
89: {"arend"},
90: {"atomic"},
91: {"bowell"},
92: {"dutoit"},
93: {"encke"},
94: {"forbes"},
95: {"grigg"},
96: {"ikeya"},
97: {"kwee"},
98: {"mrkos"},
99: {"panther"},
100: {"piggot"},
101: {"polya"},
102: {"research"},
103: {"seki"},
104: {"snb"},
105: {"spit"},
106: {"swift"},
107: {"west"},
108: {"wild"},
109: {0}
110: };
111:
112: static NMenu astromenu = {astroitems};
113:
114: static NMitem phoneitems[] = {
115: {"shannon"},
116: {"shewhart"},
117: {"sid"},
118: {"slepian"},
119: {"sweet"},
120: {"tukey"},
121: {0}
122: };
123:
124: static NMenu phonemenu = {phoneitems};
125:
126: static NMitem mercuryitems[] = {
127: {"arachne"},
128: {"balin"},
129: {"bashful"},
130: {"bifur"},
131: {"capek"},
132: {"doc"},
133: {"eeyore"},
134: {"gimli"},
135: {"gunn"},
136: {"happy"},
137: {"hunny"},
138: {"icarus"},
139: {"indra"},
140: {"iota"},
141: {"jones"},
142: {"kanga"},
143: {"sapir"},
144: {"siriusb"},
145: {"sola"},
146: {"sweet"},
147: {"thorin"},
148: {0}
149: };
150:
151: static NMenu mercurymenu = {mercuryitems};
152:
153: static NMitem machitems[] = {
154: {"mh/vlsi/araki"},
155: {"alc/ram/most"},
156: {"mh/astro", 0, &astromenu},
157: {"mh/mercury", 0, &mercurymenu},
158: {"mh/phone", 0, &phonemenu},
159: {0}
160: };
161:
162: NMenu nmenu2 = {machitems};
163:
164: static struct {
165: char *name;
166: NMitem *base, *lim;
167: } menulist[] = {
168: {"mh/astro/", astroitems, astroitems+sizeof(astroitems)/(sizeof(NMitem))-1},
169: {"mh/mercury/", mercuryitems, mercuryitems+sizeof(mercuryitems)/(sizeof(NMitem))-1},
170: {"mh/phone/", phoneitems, phoneitems+sizeof(phoneitems)/(sizeof(NMitem))-1},
171: {0}
172: };
173:
174:
175: main()
176: {
177: register i, state, hadmouse;
178:
179: #ifdef LUCA
180: Rectangle tempr;
181:
182: /*
183: * The following is a layer reshaping for Luca. See sysmon -l.
184: */
185: tempr = display.rect;
186: dellayer(P->layer);
187: tempr.corner.y = tempr.origin.y + 8+ICONSIZE;
188: if (Drect.corner.y > YMAX-16) {
189: tempr.corner.y = YMAX-8;
190: tempr.origin.y = YMAX-8-(8+ICONSIZE);
191: }
192: Drect = inset(tempr,2);
193: Jdisplayp = (Bitmap *) (P->layer = newlayer(tempr));
194: if (!P->layer)
195: exit();
196: #endif
197:
198: request(RCV|MOUSE|KBD);
199:
200: CHARHEIGHT = defont.height - 2;
201: CHARWIDTH = strwidth(&defont, "m");
202: TIMECORNER = NAMELEN*CHARWIDTH;
203: LOADORIGIN = TIMECORNER;
204: LOADCORNER = TIMECORNER + LOADLEN*CHARWIDTH;
205: MAILORIGIN = LOADCORNER;
206: MAILCORNER = LOADCORNER + MAILLEN*CHARWIDTH;
207: barheight = MAXBARHEIGHT;
208: iconorigin = MAILCORNER;
209: time[0] = 0;
210: hadmouse = 0;
211:
212: for(;;sleep(3)){
213: if (cwp != 0 && cwp->state == 0)
214: cwp = 0;
215: state = own();
216: if(state&RCV)
217: get();
218: if(state&MOUSE) {
219: if(button2()) {
220: domenu();
221: } else if(button3()) {
222: request(RCV|KBD);
223: sleep(1);
224: request(RCV|KBD|MOUSE);
225: } else if (!hadmouse || button1()) {
226: clearmail();
227: clearicon();
228: }
229: }
230: hadmouse = state&MOUSE;
231: if(state&KBD) {
232: while(kbdchar() != -1) /* dump any keyboard input */
233: ;
234: }
235: for (i = 0; i < nodes; i++)
236: drawbar (node[i]);
237: if(P->state&RESHAPED)
238: reshape(0);
239: }
240: }
241:
242: reshape(msg)
243: char *msg;
244: {
245: register int i;
246:
247: P->state&=~RESHAPED;
248: rectf(&display, Drect, F_CLR);
249:
250: /* output an error message */
251: if (msg != 0) {
252: string(&defont, msg, &display,
253: Pt (Drect.origin.x+2, Drect.origin.y + 2), F_XOR);
254: sleep(200);
255: rectf(&display, Drect, F_CLR);
256: }
257:
258: /* resize objects */
259: size = Drect.corner.x-Drect.origin.x;
260: barheight = (Drect.corner.y-Drect.origin.y-2)/(nodes?nodes:1) - CHARHEIGHT;
261: if (barheight < MINBARHEIGHT)
262: barheight = MINBARHEIGHT;
263: if (haveicons) {
264: if (barheight > MAXBARHEIGHT)
265: barheight = MAXBARHEIGHT;
266: i = 3*size/4;
267: #ifndef LUCA
268: size = (i > MAILCORNER) ? MAILCORNER
269: : ((i > LOADCORNER) ? LOADCORNER
270: : TIMECORNER);
271: #else
272: size = (i > LOADCORNER) ? LOADCORNER : TIMECORNER;
273: #endif LUCA
274: iconorigin = size;
275: maxicons = (Drect.corner.x-Drect.origin.x-iconorigin)
276: / (ICONSIZE+ICONSEP);
277: }
278:
279: /* redraw */
280: for (i = 0; i < nodes; i++) {
281: nodeinit(i);
282: drawload(node[i]);
283: drawmail(node[i]);
284: };
285: drawtime();
286: clearmail();
287: clearicon();
288: }
289:
290:
291: /* clear out the bar and write in the node name */
292: nodeinit (ind)
293: int ind; /* index into node array */
294: {
295: register struct nodedef *n;
296: register int i;
297:
298: n = node[ind];
299:
300: /* make the bar */
301: n->bar.origin.x = Drect.origin.x;
302: n->bar.origin.y = Drect.origin.y + ind*(barheight+CHARHEIGHT);
303: n->bar.corner.x = Drect.origin.x + size;
304: n->bar.corner.y = n->bar.origin.y + barheight;
305: n->bar = inset(n->bar, 4);
306: rectf(&display, inset(n->bar, -2), F_OR);
307: rectf(&display, n->bar, F_CLR);
308:
309: /* init the node */
310: for(i = 0; i<4; i++)
311: n->vec[i] = n->oldvec[i] = 0;
312: n->vec[4]=n->oldvec[4]=size;
313:
314: /* write the name */
315: if (ind != 0 && size >= TIMECORNER)
316: string (&defont, n->name, &display,
317: Pt(TIMEORIGIN+Drect.origin.x, n->bar.origin.y+barheight-6),
318: F_XOR);
319: };
320:
321: domenu() {
322: NMitem *mhit(), *sys;
323: char name[48];
324:
325: sys = mhit(&nmenu2, 2, 0);
326: if (sys) {
327: register int i;
328: strcpy(name, "M");
329: for (i = 0; menulist[i].name; i++) {
330: if (sys >= menulist[i].base && sys < menulist[i].lim) {
331: strcat (name, menulist[i].name);
332: break;
333: }
334: }
335: strcat(name, sys->text);
336: strcat(name, "\n");
337: if (index (name, '/'))
338: sendnchars(strlen(name), name);
339: }
340: }
341:
342:
343: Point pt[4];
344: Rectangle new, old;
345:
346: /* draw the bar graph for a system's CPU time */
347: drawbar (n)
348: struct nodedef *n;
349: {
350: register i, now;
351:
352: pt[0].y = pt[2].y = n->bar.origin.y;
353: pt[1].y = pt[3].y = n->bar.corner.y;
354: new = old = n->bar;
355: for(i=0; i<5; i++){
356: now = relax(n->oldvec[i], n->vec[i]);
357: old.corner.x = n->oldvec[i] + old.origin.x;
358: new.corner.x = now+new.origin.x;
359: sort(old.origin.x,old.corner.x, new.origin.x,new.corner.x);
360: if (pt[3].x > n->bar.corner.x)
361: pt[3].x = n->bar.corner.x;
362: if (pt[1].x > n->bar.corner.x)
363: pt[1].x = n->bar.corner.x;
364: texture(&display, Rpt(pt[0], pt[1]), txt[i], F_XOR);
365: texture(&display, Rpt(pt[2], pt[3]), txt[i], F_XOR);
366: new.origin.x = new.corner.x;
367: old.origin.x = old.corner.x;
368: n->oldvec[i] = now;
369: }
370: }
371:
372: relax(o, n)
373: int o, n;
374: {
375: register a;
376: register s=1;
377: register long lo = o;
378: register long ln = n;
379:
380: if(o>n)
381: s= -1;
382: a=abs(o-n);
383: if(a<2)
384: return n;
385: if(a<127)
386: return o+s;
387: ln = (127L*lo + ln) / 128L;
388: s = ln;
389:
390: return s;
391: }
392:
393: sort(x)
394: int x;
395: {
396: register int *p= &x;
397: register i,j;
398: register t;
399: for(i=0; i<3; i++){
400: for(j=0; j<3; j++)
401: if(p[j]>p[j+1]){
402: t=p[j];
403: p[j]=p[j+1];
404: p[j+1]=t;
405: }
406: }
407: for(i=0; i<4; i++)
408: pt[i].x=p[i];
409: }
410:
411: drawload(n)
412: struct nodedef *n;
413: {
414: if (size < LOADCORNER)
415: return;
416: string(&defont, n->load, &display,
417: Pt (Drect.origin.x+LOADORIGIN, n->bar.origin.y+barheight-6), F_XOR);
418: }
419:
420: drawtime()
421: {
422: if (size < TIMECORNER)
423: return;
424: string(&defont, time, &display,
425: Pt (Drect.origin.x+TIMEORIGIN, Drect.origin.y+barheight-2), F_XOR);
426: }
427:
428: drawmail(n)
429: struct nodedef *n;
430: {
431: if (size < MAILCORNER)
432: return;
433: string(&defont, n->mail, &display,
434: Pt (Drect.origin.x+MAILORIGIN, n->bar.origin.y+barheight-6), F_XOR);
435: }
436:
437: clearmail()
438: {
439: register int i;
440:
441: for (i = 0; i < nodes; i++) {
442: drawmail(node[i]);
443: node[i]->mail[0] = '\0';
444: }
445: }
446:
447: drawicon()
448: {
449: Rectangle rect;
450: Point to;
451: int bltwidth;
452:
453: if (!haveicons || maxicons < 1)
454: return;
455:
456: /* move icons right */
457: bltwidth = (maxicons-1)*(ICONSIZE+ICONSEP) - ICONSEP;
458: rect.origin.x = Drect.origin.x + iconorigin;
459: rect.origin.y = Drect.origin.y + 2;
460: rect.corner.x = rect.origin.x + bltwidth;
461: rect.corner.y = rect.origin.y + ICONSIZE + 4 + CHARHEIGHT;
462: to.x = rect.origin.x + ICONSIZE + ICONSEP;
463: to.y = rect.origin.y;
464: bitblt(&display, rect, &display, to, F_STORE);
465:
466: if (icons != maxicons)
467: icons++;
468:
469: /* clear area */
470: rect.corner.x = to.x;
471: rectf(&display, rect, F_CLR);
472:
473: /* drop in new picture */
474: to = rect.origin;
475: rect = icon->rect;
476: for (rect.origin.y += ICONSIZE-1;
477: rect.origin.y >= icon->rect.origin.y;
478: rect.origin.y--) {
479: bitblt(icon, rect, &display, to, F_STORE);
480: sleep(2);
481: }
482:
483: /* add a time stamp */
484: to.y += ICONSIZE + 4;
485: string(&defont, time, &display, to, F_XOR);
486: }
487:
488: clearicon()
489: {
490: Rectangle rect;
491:
492: if (!haveicons || maxicons < 1 || icons == 0)
493: return;
494: icons = 0;
495: rect.origin.x = Drect.origin.x + iconorigin - 1;
496: rect.origin.y = Drect.origin.y + 1;
497: rect.corner.x = rect.origin.x + maxicons*(ICONSIZE+ICONSEP) - ICONSEP + 2;
498: rect.corner.y = rect.origin.y + ICONSIZE + CHARHEIGHT + 6;
499: rectf(&display, rect, F_CLR);
500: }
501:
502: /* process a host message */
503: get(){
504: register int ch;
505: register struct nodedef *n;
506: struct nodedef *nodeptr();
507: # define MAGIC '_'
508:
509: ch = hostchar();
510: if (ch == MAGIC) {
511:
512: /* this is probably a message from the host half of sysmon */
513: ch = hostchar();
514: switch(ch){
515: case 'V':
516: while ((ch = hostchar()) != -1) {
517: n = nodeptr(ch);
518: getvec(n);
519: }
520: break;
521: case 'L':
522: while ((ch = hostchar()) != -1) {
523: n = nodeptr(ch);
524: drawload(n);
525: getload(n);
526: drawload(n);
527: }
528: break;
529: case 'T':
530: drawtime();
531: gettime();
532: drawtime();
533: break;
534: case 'M':
535: n = nodeptr(hostchar());
536: drawmail(n);
537: getmail(n);
538: drawmail(n);
539: break;
540: case 'I':
541: geticon();
542: drawicon();
543: break;
544: case 'N':
545: getname();
546: reshape(0);
547: break;
548: case 'Q':
549: icon = balloc(Rect(0, 0, ICONSIZE, ICONSIZE));
550: ticon = balloc(Rect(0, 0, ICONSIZE, ICONSIZE));
551: if (!icon || !ticon) {
552: reshape("Not enough memory for faces.");
553: sendnchars(2, "R\n"); /* refuse faces */
554: break;
555: }
556: sendnchars(2, "A\n"); /* accept faces */
557: haveicons = 1;
558: reshape(0);
559: break;
560: case 'R':
561: remove(hostchar()-'0');
562: reshape(0);
563: break;
564: case -1:
565: return;
566: default:
567: writecw(ch);
568: break;
569: }
570: } else {
571: writecw(ch);
572: }
573: ignorerest();
574: }
575:
576: struct nodedef *
577: nodeptr(c)
578: int c;
579: {
580: register i;
581:
582: i = c - '0';
583: if (i < 0 || i >= nodes)
584: i = 0;
585: return node[i];
586: }
587:
588: getvec(n)
589: struct nodedef *n;
590: {
591: register int i, sum, nsum, vec[5];
592:
593: for(sum=0,i=0; i<5; i++)
594: sum += (vec[i] = hostchar());
595: sum = sum ? sum : 1;
596: for(nsum=0,i=0; i<4; i++)
597: nsum += n->vec[i] = ((long)(vec[i])*size) / sum;
598: n->vec[4]=size-nsum;
599: }
600:
601: gettime()
602: {
603: register char *p=time;
604: register int c, i=0;
605:
606: while((c = hostchar()) != -1 && ++i < TIMELEN)
607: *p++ = c;
608: *p=0;
609: }
610:
611: getload(n)
612: struct nodedef *n;
613: {
614: register char *p=n->load;
615: register int i=0;
616:
617: while((*p = hostchar()) != '\t' && ++i < LOADLEN)
618: p++;
619: *p=0;
620: }
621:
622: getname()
623: {
624: register char *p;
625: register int c, i=0;
626:
627: if (nodes != 0) {
628: node[nodes] = (struct nodedef *)alloc(sizeof (struct nodedef));
629: if (!node[nodes]) {
630: reshape("out of memory");
631: sendnchars(2, "R\n"); /* refuse connection */
632: return;
633: }
634: }
635: sendnchars(2, "A\n"); /* accept connection */
636: p = node[nodes]->name;
637: while((c = hostchar()) != -1 && ++i < NAMELEN)
638: *p++ = c;
639: *p=0;
640: nodes++;
641: }
642:
643: remove(ind)
644: register int ind;
645: {
646: if (ind < 0 || ind >= nodes)
647: return;
648: free (node[ind]);
649: for (; ind < nodes-1; ind++)
650: node[ind] = node[ind+1];
651: nodes--;
652: }
653:
654: getmail(n)
655: struct nodedef *n;
656: {
657: register char *p=n->mail;
658: register int c, i=0;
659:
660: while((c = hostchar()) != -1 && ++i < MAILLEN)
661: *p++ = c;
662: upfront(P->layer);
663: ringbell ();
664: *p=0;
665: }
666:
667: geticon()
668: {
669: register int c, i, j;
670: register short *ip;
671:
672: /* once per scan line */
673: ip = (short *)icon->base;
674: for (i = 0; i < ICONSIZE; i++) {
675:
676: /* once per short */
677: for (j = 0; j < ICONSIZE/16; j++) {
678: c = hostchar();
679: *ip = (c<<8) | hostchar();
680: #ifndef mc68000
681: if (VALSCREENCOLOR==0)
682: *ip = ~*ip;
683: #endif mc68000
684: ip++;
685: }
686:
687: #ifndef mc68000
688: /* blit and 5620 have different size bitmaps */
689: ip++;
690: #endif mc68000
691: }
692: }
693:
694: int atend = 0; /* non-zero if at end of message */
695:
696: hostchar(){
697: register int c;
698:
699: if (atend)
700: return -1;
701:
702: if((c=rcvchar())==-1)
703: wait(RCV), c=rcvchar();
704:
705: if (c == '\n') {
706:
707: /* newline's mark end of message */
708: atend = 1;
709: return -1;
710: } else if (c == '\\') {
711:
712: /* backslashes are character escapes */
713: if ((c=rcvchar())==-1)
714: wait(RCV), c=rcvchar();
715: }
716:
717: return c&0xff;
718: }
719:
720: ignorerest()
721: {
722: while (hostchar() != -1)
723: ;
724: atend = 0;
725: }
726:
727:
728: #ifdef mc68000
729: ringbell ()
730: {
731: *((char *)(384*1024L+062)) = 2;
732: }
733: #endif mc68000
734:
735: /*
736: * The rest of jerqmon.c contains routines to create and update the
737: * communications window.
738: */
739: #define INSET 4
740: #define C_NEW 2
741:
742: makecw()
743: {
744: register Rectangle r;
745: register unsigned char *pout;
746:
747: /* first see if the process already exists */
748: if (cwp != 0 && cwp->state != 0)
749: return 0;
750: else
751: cwp = 0;
752:
753: /* create process */
754: r = Drect;
755: if(!(cwp=newproc((struct Proc *)0)))
756: return -1;
757: cwp->rect=inset(r, INSET);
758: if( !rectclip(&cwp->rect,Jrect) || !(cwp->layer=newlayer(r))){
759: cwp->state=0;
760: return -1;
761: }
762:
763: /* give it a window */
764: #ifndef mc68000
765: muxnewwind(cwp, C_NEW);
766: #else
767: mpxnewwind(cwp, C_NEW);
768: #endif mc68000
769:
770: /* wait for a prompt */
771: pout = cwp->cbufpout;
772: do sleep( 60 ); while( pout == cwp->cbufpout );
773: ringbell();
774:
775: return 0;
776: }
777:
778: /*
779: * Write a string to the communications window. Create the
780: * window if it has disappeared.
781: */
782: writecw(c)
783: register int c;
784: {
785: if (makecw() < 0) {
786: drawmail(node[0]);
787: getmail(node[0], "can't open comm window\n");
788: drawmail(node[0]);
789: return;
790: }
791: do {
792: if (cwp->state) {
793: upfront(cwp->layer);
794: while (cwp->nchars < CBSIZE*3) {
795: *(cwp->cbufpin++) = c != -1 ? c : '\n';
796: cwp->nchars++;
797: if (cwp->cbufpin >= &(cwp->cbuf[CBSIZE*3]))
798: cwp->cbufpin = cwp->cbuf;
799: if (c == -1)
800: break;
801: c = hostchar();
802: }
803: cwp->state |= WAKEUP;
804: sleep (10);
805: } else
806: return;
807: } while (c != -1);
808: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.