Annotation of 43BSD/contrib/X/xload/xload.c, revision 1.1

1.1     ! root        1: #include <X/mit-copyright.h>
        !             2: 
        !             3: /* Copyright 1985, by the Massachusetts Institute of Technology */
        !             4: /* xload -- graph load average on X window system display.
        !             5:  * K. Shane Hartman and Stuart A. Malone with ripoffs from xclock.
        !             6:  * Host name feature added by Jim Gettys.
        !             7:  * Scale feature added by Bob Scheifler.
        !             8:  * Rescale feature added by Stuart A. Malone.
        !             9:  */
        !            10: #ifndef lint
        !            11: static char *rcsid_xload_c = "$Header: xload.c,v 10.9 86/02/01 16:00:54 tony Rel $";
        !            12: #endif  lint
        !            13: 
        !            14: #include <stdio.h>
        !            15: #include <strings.h>
        !            16: #include <nlist.h>
        !            17: #include <sys/time.h>
        !            18: #include <sys/file.h>
        !            19: #include <sys/param.h>
        !            20: #include <X/Xlib.h>
        !            21: 
        !            22: typedef enum _bool {FALSE, TRUE} Bool;
        !            23: 
        !            24: #define KMEM_FILE "/dev/kmem"
        !            25: #define KMEM_ERROR "cannot open /dev/kmem"
        !            26: 
        !            27: #define DEFAULT_BORDER_WIDTH 3
        !            28: #define DEFAULT_UPDATE 5                   /* Any smaller leads to lossage */
        !            29: #define DEFAULT_FONT "6x10"
        !            30: #define DEFAULT_POSITION "=360x120-0+0"            /* upper right hand corner */
        !            31: #define DEFAULT_SCALE 1
        !            32: 
        !            33: struct nlist namelist[] = {                /* namelist for vmunix grubbing */
        !            34: #define LOADAV 0
        !            35:     {"_avenrun"},
        !            36:     {0}
        !            37: };
        !            38: 
        !            39: extern char *getenv();
        !            40: 
        !            41: /* GLOBAL */
        !            42: 
        !            43: Window win;                                /* load average window */
        !            44: double data[2048];                         /* accumulated load average data */
        !            45: int background;                                    /* color of background */
        !            46: int foreground;                                    /* color of graph */
        !            47: int highlight;                             /* color of text, scale */
        !            48: Font font;                                 /* font for printing hostname */
        !            49: char *fn = DEFAULT_FONT;                   /* font for hostname */
        !            50: FontInfo font_info;
        !            51: char host[256];                             /* the host name */
        !            52: double scale = DEFAULT_SCALE;              /* n divisions for graph */
        !            53: double min_scale = DEFAULT_SCALE;          /* minimum value for scale */
        !            54: double max_loadavg = 0.0;                  /* maximum loadavg on the graph */
        !            55: int mapped = 1;                                    /* should really display? */
        !            56:                                              
        !            57: short gray_bits[16] = {
        !            58:     0xaaaa, 0x5555, 0xaaaa, 0x5555,
        !            59:     0xaaaa, 0x5555, 0xaaaa, 0x5555,
        !            60:     0xaaaa, 0x5555, 0xaaaa, 0x5555,
        !            61:     0xaaaa, 0x5555, 0xaaaa, 0x5555};
        !            62: 
        !            63: /* Diagnostic printer - Print message and exit */
        !            64: 
        !            65: void xload_error(message)
        !            66:     char *message;
        !            67: {
        !            68:     fprintf(stderr, "xload: %s\n", message);
        !            69:     perror("xload");
        !            70:     exit(1);
        !            71: }
        !            72: 
        !            73: /* Blts data according to current size, then redraws the load average window.
        !            74:  * Next represents the number of valid points in data.  Returns the (possibly)
        !            75:  * adjusted value of next.  If next is 0, this routine draws an empty window
        !            76:  * (scale - 1 lines for graph).  If next is less than the current window width,
        !            77:  * the returned value is identical to the initial value of next and data is
        !            78:  * unchanged.  Otherwise keeps half a window's worth of data.  If data is
        !            79:  * changed, then max_loadavg is updated to reflect the largest data point.
        !            80:  */
        !            81: 
        !            82: int repaint_window(width, height, next)
        !            83:     register int width, height, next;
        !            84: {
        !            85:     register int i, j;
        !            86: 
        !            87:     if (mapped)
        !            88:        XClear(win);
        !            89:     if (next >= width) {
        !            90:        j = width >> 1;
        !            91:        bcopy((char *)(data + next - j),(char *)data, j * sizeof(double));
        !            92:        next = j;
        !            93:        /* Since we just lost some data, recompute the max_loadavg. */
        !            94:        max_loadavg = 0.0;
        !            95:        for (i = 0; i < next; i++) {
        !            96:            if (data[i] > max_loadavg) max_loadavg = data[i];
        !            97:        }
        !            98:     }
        !            99: 
        !           100:     /* Compute the minimum scale required to graph the data, but don't go
        !           101:        lower than min_scale. */
        !           102:     if (max_loadavg > min_scale) scale = ((int)max_loadavg) + 1;
        !           103:     else scale = min_scale;
        !           104: 
        !           105:     if (!mapped) return(next);
        !           106: 
        !           107:     /* Print hostname */
        !           108:     XTextMask(win, 2, 2, host, strlen(host), font, highlight);
        !           109: 
        !           110:     /* Draw graph reference lines */
        !           111:     for (i = 1; i < scale; i++) {
        !           112:        j = (i * height) / scale;
        !           113:        XLine(win, 0, j, width, j, 1, 1, highlight, GXcopy, AllPlanes);
        !           114:     }
        !           115: 
        !           116:     /* Draw data point lines. */
        !           117:     for (i = 0; i < next; i++)
        !           118:        XLine(win, i, height, i, (int)(height - (data[i] * height) / scale),
        !           119:                1, 1, foreground, GXcopy, AllPlanes);
        !           120:     return(next);
        !           121: }
        !           122: 
        !           123: /* Exit with message describing command line format */
        !           124: 
        !           125: void usage()
        !           126: {
        !           127:     fprintf(stderr,
        !           128: "usage: xload [-fn {font}] [-update {seconds}] [-scale {integer}] [-rv]\n"
        !           129: );
        !           130:     fprintf(stderr,
        !           131: "             [=[{width}][x{height}][{+-}{xoff}[{+-}{yoff}]]] [[{host}]:[{vs}]]\n"
        !           132: );
        !           133:     fprintf(stderr,
        !           134: "             [-fg {color}] [-bg {color}] [-hl {color}] [-bd {color}] [-bw {pixels}]\n");
        !           135:     exit(1);
        !           136: }
        !           137: 
        !           138: /* Returns pointer to first char in search which is also in what, else NULL. */
        !           139: 
        !           140: char *strscan(search, what)
        !           141:     register char *search;
        !           142:     register char *what;
        !           143: {
        !           144:     register int i;
        !           145:     register len = strlen(what);
        !           146:     register char c;
        !           147:     while (c = *(search++))
        !           148:        for (i = 0; i < len; i++)
        !           149:            if (c == what[i]) return (--search);
        !           150:     return (NULL);
        !           151: }
        !           152: 
        !           153: 
        !           154: void main(argc, argv)
        !           155:     int argc;
        !           156:     char **argv;
        !           157: {
        !           158:     char *arg;
        !           159: 
        !           160:     register int i;
        !           161: 
        !           162:     register int kmem;                      /* kmem pointer */
        !           163:     register double loadavg;                /* load average value */
        !           164:     long loadavg_seek;                      /* offset to load average in kmem */
        !           165: 
        !           166:     char display[256];                      /* will contain vs host */
        !           167:     int vsnum;                              /* will contain vs number */
        !           168:     
        !           169:     int reverse = 0;
        !           170:     char *border_color;
        !           171:     char *fore_color;
        !           172:     char *back_color;
        !           173:     char *high_color;
        !           174:     int border_pixmap;
        !           175:     int border_width = DEFAULT_BORDER_WIDTH;
        !           176:     int update = DEFAULT_UPDATE;
        !           177:     Color cdef;
        !           178:     OpaqueFrame window;                            /* frame for the window */
        !           179:     char *geometry = NULL;
        !           180:     char *def = DEFAULT_POSITION;          /* default position */
        !           181:     char *option;
        !           182: 
        !           183:     XEvent event;
        !           184: 
        !           185:     int maxfds;                             /* for select call */
        !           186:     int readfds;
        !           187:     int fdmask;
        !           188:     struct timeval timeout;                 /* will contain update interval */
        !           189: 
        !           190:     /* Get name list. Then open kmem so we can seek for load average. */
        !           191: 
        !           192:     nlist("/vmunix", namelist);
        !           193:     if (namelist[LOADAV].n_type == 0) xload_error("cannot get name list");
        !           194:     loadavg_seek = namelist[LOADAV].n_value;
        !           195:     kmem = open(KMEM_FILE, O_RDONLY);
        !           196:     if (kmem < 0) xload_error(KMEM_ERROR);
        !           197: 
        !           198:     gethostname(host, sizeof(host));       /* Who are we? */
        !           199:     display[0] = '\0';
        !           200: 
        !           201:     if ((option = XGetDefault(argv[0],"ReverseVideo")) != NULL )
        !           202:                if (strcmp (option, "on") == 0)
        !           203:                        reverse = 1;
        !           204:     if ((option = XGetDefault(argv[0],"BorderWidth")) != NULL)
        !           205:        border_width = atoi(option);
        !           206:     if ((option = XGetDefault(argv[0],"BodyFont")) != NULL)
        !           207:        fn = option;
        !           208:     if ((border_color = XGetDefault(argv[0],"Border")) == NULL)
        !           209:        border_color = XGetDefault(argv[0],"BorderColor");
        !           210:     back_color = XGetDefault(argv[0],"Background");
        !           211:     fore_color = XGetDefault(argv[0],"Foreground");
        !           212:     high_color = XGetDefault(argv[0],"Highlight");
        !           213:     if ((option = XGetDefault(argv[0],"Update")) != NULL)
        !           214:        update = atoi(option);
        !           215:     if ((option = XGetDefault(argv[0],"Scale")) != NULL)
        !           216:        min_scale = atoi(option);
        !           217: 
        !           218:     for (i = 1; i < argc; i++) {                       /* Parse line */
        !           219:        if (argv[i][0] == '=') {
        !           220:            geometry = argv[i];
        !           221:            continue;
        !           222:        }
        !           223:        if (index(argv[i], ':') != NULL) {              /* host:display */
        !           224:            strncpy(display, argv[i], sizeof(display));
        !           225:            continue;
        !           226:        }
        !           227:        if (strcmp(argv[i], "-rv") == 0 ||
        !           228:            strcmp(argv[i], "-reverse") == 0) {         /* black on white */
        !           229:            reverse = 1;
        !           230:            continue;
        !           231:        }
        !           232:        if (strcmp(argv[i], "-fw") == 0 ||
        !           233:            strcmp(argv[i], "-forward") == 0) {         /* white on black */
        !           234:            reverse = 0;
        !           235:            continue;
        !           236:        }
        !           237:        if (strcmp(argv[i], "-bw") == 0 ||
        !           238:            strcmp(argv[i], "-border") == 0) {          /* border width */
        !           239:            if (++i >= argc) usage();
        !           240:            border_width = atoi(argv[i]);
        !           241:            continue;
        !           242:        }
        !           243:        if (strcmp(argv[i], "-fn") == 0 ||
        !           244:            strcmp(argv[i], "-font") == 0) {            /* host name font */
        !           245:            if (++i >= argc) usage();
        !           246:            fn = argv[i];
        !           247:            continue;
        !           248:        }
        !           249:        if (strcmp(argv[i], "-bd") == 0 ||
        !           250:            strcmp(argv[i], "-color") == 0) {          /* border color */
        !           251:           if (++i >= argc) usage();
        !           252:           border_color = argv[i];
        !           253:           continue;
        !           254:        }
        !           255:        if (strcmp(argv[i], "-fg") == 0 ||
        !           256:            strcmp(argv[i], "-foreground") == 0) {     /* foreground color */
        !           257:           if (++i >= argc) usage();
        !           258:           fore_color = argv[i];
        !           259:           continue;
        !           260:        }
        !           261:        if (strcmp(argv[i], "-bg") == 0 ||
        !           262:            strcmp(argv[i], "-background") == 0) {     /* background color */
        !           263:           if (++i >= argc) usage();
        !           264:           back_color = argv[i];
        !           265:           continue;
        !           266:        }
        !           267:        if (strcmp(argv[i], "-hl") == 0 ||
        !           268:            strcmp(argv[i], "-highlight") == 0) {     /* highlight color */
        !           269:           if (++i >= argc) usage();
        !           270:           high_color = argv[i];
        !           271:           continue;
        !           272:        }
        !           273:        if (strcmp(argv[i], "-u") == 0 ||
        !           274:            strcmp(argv[i], "-update") == 0) {          /* update interval */
        !           275:            if (++i >= argc) usage();
        !           276:            update = atoi(argv[i]);
        !           277:            continue;
        !           278:        }
        !           279:        if (strcmp(argv[i], "-s") == 0 ||
        !           280:            strcmp(argv[i], "-scale") == 0) {           /* load scale */
        !           281:            if (++i >= argc) usage();
        !           282:            min_scale = atoi(argv[i]);
        !           283:            continue;
        !           284:        }
        !           285:        usage();
        !           286:     }
        !           287: 
        !           288:     if (border_width < 0) border_width = DEFAULT_BORDER_WIDTH;
        !           289:     if (update < DEFAULT_UPDATE) update = DEFAULT_UPDATE;
        !           290:     if (min_scale <= 0) min_scale = DEFAULT_SCALE;
        !           291:     scale = min_scale;
        !           292: 
        !           293:     /* Open display  */
        !           294:     if (!XOpenDisplay(display))
        !           295:        xload_error("cannot open display");
        !           296: 
        !           297:     /* Need a font to print hostname in */
        !           298:     font = XGetFont(fn);
        !           299:     if (!font)
        !           300:        xload_error("cannot open font");
        !           301:     XQueryFont(font, &font_info);
        !           302: 
        !           303:     if (border_color && DisplayCells() > 2 &&
        !           304:        XParseColor(border_color, &cdef) && XGetHardwareColor(&cdef))
        !           305:        border_pixmap = XMakeTile(cdef.pixel);
        !           306:     else if (border_color && strcmp(border_color, "black") == 0)
        !           307:        border_pixmap = BlackPixmap;
        !           308:     else if (border_color && strcmp(border_color, "white") == 0)
        !           309:        border_pixmap = WhitePixmap;
        !           310:     else
        !           311:        border_pixmap = XMakePixmap ((Bitmap) XStoreBitmap (16, 16, gray_bits),
        !           312:                                        BlackPixel, WhitePixel);
        !           313: 
        !           314:     if (back_color && DisplayCells() > 2 &&
        !           315:        XParseColor(back_color, &cdef) && XGetHardwareColor(&cdef)) {
        !           316:        background = cdef.pixel;
        !           317:     } else if (back_color && strcmp(back_color, "white") == 0) {
        !           318:        background = WhitePixel;
        !           319:        reverse = 0;
        !           320:     } else if (back_color && strcmp(back_color, "black") == 0) {
        !           321:        background = BlackPixel;
        !           322:        reverse = 0;
        !           323:     } else
        !           324:        background = BlackPixel;
        !           325: 
        !           326:     if (fore_color && DisplayCells() > 2 &&
        !           327:        XParseColor(fore_color, &cdef) && XGetHardwareColor(&cdef)) {
        !           328:        foreground = cdef.pixel;
        !           329:     } else if (fore_color && strcmp(fore_color, "black") == 0) {
        !           330:        foreground = BlackPixel;
        !           331:        reverse = 0;
        !           332:     } else if (fore_color && strcmp(fore_color, "white") == 0) {
        !           333:        foreground = WhitePixel;
        !           334:        reverse = 0;
        !           335:     } else
        !           336:        foreground = WhitePixel;
        !           337: 
        !           338:     if (high_color && DisplayCells() > 2 &&
        !           339:        XParseColor(high_color, &cdef) && XGetHardwareColor(&cdef))
        !           340:        highlight = cdef.pixel;
        !           341:     else if (reverse)
        !           342:        highlight = background;
        !           343:     else
        !           344:        highlight = foreground;
        !           345: 
        !           346:     if (reverse) {
        !           347:        background = foreground;
        !           348:        foreground = highlight;
        !           349:     }
        !           350: 
        !           351:     window.bdrwidth = border_width;
        !           352:     window.border = border_pixmap;
        !           353:     window.background = XMakeTile(background);
        !           354:     win = XCreate ("Load Average", argv[0], geometry, def, &window,
        !           355:                   font_info.width * strlen(host) + 4, font_info.height + 4);
        !           356:     XSelectInput(win, ExposeWindow|UnmapWindow);
        !           357:     XMapWindow(win);                       /* Map window to screen */
        !           358:     timeout.tv_sec = update;               /* Set up timeout for select */
        !           359:     timeout.tv_usec = 0;
        !           360:     maxfds = dpyno() + 1;                  /* Set up select arguments */
        !           361:     fdmask = 1 << dpyno();
        !           362:     i = 0;                                 /* Window is initially empty */
        !           363: 
        !           364:     while (1) {                                    /* Main loop */
        !           365:        if (XPending()) {
        !           366:            XNextEvent(&event);
        !           367:            switch (event.type) {
        !           368:            case ExposeWindow:
        !           369:                mapped = 1;
        !           370:                window.width = ((XExposeEvent *) &event)->width;
        !           371:                window.height = ((XExposeEvent *) &event)->height;
        !           372:                i = repaint_window(window.width, window.height, i);
        !           373:                break;
        !           374:            case UnmapWindow:
        !           375:                mapped = 0;
        !           376:                break;
        !           377:            default:
        !           378:                xload_error("unexpected X event");
        !           379:            }
        !           380:        }
        !           381:        else if (i >= window.width) i = repaint_window(window.width, window.height, i);
        !           382:        /* Get the load average, stash the point and draw corresponding line. */
        !           383:        lseek(kmem, loadavg_seek, 0);
        !           384: #ifdef sun
        !           385:        {
        !           386:                long temp;
        !           387:                read(kmem, (char *)&temp, sizeof(long));
        !           388:                loadavg = (double)temp/FSCALE;
        !           389:        }
        !           390: #else
        !           391:        read(kmem, (char *)&loadavg, sizeof(double));
        !           392: #endif
        !           393: 
        !           394:        /* Keep max_loadavg up to date, and if this data point is off the
        !           395:           graph, change the scale to make it fit. */
        !           396:        if (loadavg > max_loadavg) {
        !           397:            max_loadavg = loadavg;
        !           398:            if (max_loadavg > scale) {
        !           399:                scale = ((int)max_loadavg) + 1;
        !           400:                i = repaint_window(window.width, window.height, i);
        !           401:            }
        !           402:        }
        !           403: 
        !           404:        data[i] = loadavg;
        !           405:        if (mapped) {
        !           406:            XLine(win, i, window.height, i, 
        !           407:                    (int)(window.height - (window.height * loadavg) / scale),
        !           408:                    1, 1, foreground, GXcopy, AllPlanes);
        !           409:            XFlush();                       /* Flush output buffers */
        !           410:        }
        !           411:        i++;                                /* Next point */
        !           412:        readfds = fdmask;                   /* Initialize select mask */
        !           413:                                            /* and select on display fd */
        !           414:        if (select(maxfds, &readfds, NULL, NULL, &timeout) == -1)
        !           415:            xload_error("select error on display file descriptor");
        !           416:     } /* while */
        !           417: } /* main */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.