/* * LOADAV.C * * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved. * * LOADAV [frequency] Connect to remote UNIX system and display * load average. Default is every 5 minutes. * * frequency in seconds, default is every 60 seconds * */ #include #include "/include/typedefs.h" #include "/dnet/channel.h" #include "/server/servers.h" #define BASELOAD 2 #define LOADINCR 2 short MaxLoad = BASELOAD; ubyte Title[64] = { "LoadAv" }; typedef struct timerequest IOT; NW Nw = { 640-150, 0, 150, 50, -1, -1, NEWSIZE|CLOSEWINDOW, WINDOWSIZING|WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|NOCAREREFRESH, NULL, NULL, Title, NULL, NULL, 32, 18, -1, -1, WBENCHSCREEN }; WIN *Win; RP *Rp; int Enable_Abort; char Buf[512]; char Cc; extern void *OpenWindow(); extern void *GetMsg(); extern void *CreatePort(); long IntuitionBase; long GfxBase; main(ac,av) char *av[]; { long chan = NULL; short numsecs = 60; long n; long imask, tmask, dmask, mask; char notdone = 1; char *host = NULL; PORT *TimPort = CreatePort(NULL, 0); IOT Iot; { register short i; for (i = 1; i < ac; ++i) { if (strncmp(av[i], "-N", 2) == 0) { host = av[i]+2; continue; } numsecs = atoi(av[i]); } } Iot.tr_node.io_Device = NULL; if (OpenDevice("timer.device", UNIT_VBLANK, &Iot, 0)) goto fail; Iot.tr_node.io_Command = TR_ADDREQUEST; Iot.tr_node.io_Message.mn_ReplyPort = TimPort; Iot.tr_time.tv_micro = 1; Iot.tr_time.tv_secs = 0; SendIO(&Iot); Enable_Abort = 0; IntuitionBase = OpenLibrary("intuition.library", 0); GfxBase = OpenLibrary("graphics.library", 0); chan = DOpen(host, PORT_LOADAV, 25, 25); if (chan == NULL) { puts("no connect"); goto fail; } Win = OpenWindow(&Nw); if (Win == NULL) { puts("Unable to open window"); goto fail; } Rp = Win->RPort; imask = 1 << Win->UserPort->mp_SigBit; dmask = 1 << ((PORT *)chan)->mp_SigBit; tmask = 1 << TimPort->mp_SigBit; clearwindow(); while (notdone) { mask = Wait(imask|dmask|tmask|SIGBREAKF_CTRL_C); if (mask & SIGBREAKF_CTRL_C) notdone = 0; if (mask & imask) { IMESS *im; while (im = GetMsg(Win->UserPort)) { switch(im->Class) { case NEWSIZE: clearwindow(); break; case CLOSEWINDOW: notdone = 0; break; } ReplyMsg(im); } } if (mask & dmask) { char dummy; if ((dummy = DNRead(chan, &dummy, 1)) != 0) notdone = 0; } while (mask & tmask) { /* while just so we can break */ char len = 0; char buf[64]; long onei,onef,fivei,fivef,teni,tenf; if (GetMsg(TimPort)) { Iot.tr_time.tv_micro = 0; Iot.tr_time.tv_secs = numsecs; SendIO(&Iot); if (DWrite(chan, &len, 1) == 1 && DRead(chan, &len, 1) == 1) { if (DRead(chan, buf, len) == len) { sscanf(buf, "%ld.%ld %ld.%ld %ld.%ld", &onei,&onef,&fivei,&fivef,&teni,&tenf ); updatewindow(onei,onef,fivei,fivef,teni,tenf); break; } } notdone = 0; } break; } } fail: if (Iot.tr_node.io_Device) { AbortIO(&Iot); WaitIO(&Iot); CloseDevice(&Iot); } DeletePort(TimPort); if (Win) CloseWindow(Win); if (chan) DClose(chan); if (IntuitionBase) CloseLibrary(IntuitionBase); if (GfxBase) CloseLibrary(GfxBase); } #define LSIZE (sizeof(LBuf)/sizeof(LBuf[0])) #define LIDX(i) ((Li + i) & (LSIZE-1)) uword LBuf[1024]; /* The last N readings, (loadav * 256) + 1 */ /* size must be power of 2 */ uword Li; short Wbl, Wbt, Wbr, Wbb, Wh, Ww; clearwindow() { short i, j; short height; Wbl = Win->BorderLeft; Wbr = Win->BorderRight; Wbt = Win->BorderTop; Wbb = Win->BorderBottom; Ww = Win->Width; Wh = Win->Height; SetAPen(Rp, 0); RectFill(Rp, Wbl, Wbt, Ww - Wbr, Wh - Wbb); Wbl += 2; Wbr += 4; SetAPen(Rp, 1); for (i = 0, j = Ww - Wbr; i < LSIZE && j > Wbl; ++i, --j) { height = (Wh - Wbb - Wbt) * LBuf[LIDX(i)] / (MaxLoad << 8); if (Wh - Wbb - height > 0) { Move(Rp, j, Wh - Wbb); Draw(Rp, j, Wh - Wbb - height); } } SetAPen(Rp, 3); for (i = 1; i < MaxLoad; ++i) { height = Wh - Wbb - (Wh - Wbb - Wbt) * i / MaxLoad; RectFill(Rp, Wbl - 2 , height, Wbl - 1 , height + 1); RectFill(Rp, Ww - (Wbr - 3), height, Ww - (Wbr - 4), height + 1); } SetAPen(Rp, 1); } updatewindow(i1, f1, i5, f5, i10, f10) { short height; short res = 0; while (i1 < 1000 && i1 >= MaxLoad) { MaxLoad += LOADINCR; res = 1; } if (res) clearwindow(); sprintf(Title, "LoadAv %2ld.%02ld %2ld.%02ld %2ld.%02ld Max=%2ld", i1, f1, i5, f5, i10, f10, MaxLoad ); SetWindowTitles(Win, Title, -1); f1 = (f1 * 256) / 100; f5 = (f5 * 256) / 100; f10= (f10 * 256) / 100; ScrollRaster(Rp, 1, 0, Wbl, Wbt, Ww - Wbr, Wh - Wbb); Li = (Li-1) & (LSIZE-1); LBuf[Li] = ((i1 << 8) | f1) + 1; height = (Wh - Wbb - Wbt) * LBuf[Li] / (MaxLoad << 8); if (Wh - Wbb - height > 0) { Move(Rp, Ww - Wbr, Wh - Wbb); Draw(Rp, Ww - Wbr, Wh - Wbb - height); } SetAPen(Rp, 2); Move(Rp, Wbl, Wbt + Rp->TxBaseline); Text(Rp, Title + 7, 5); SetAPen(Rp, 1); }