Annotation of 43BSDTahoe/new/X/xload/xload.c, revision 1.1.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.13 86/11/30 14:59:08 jg 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: /* Diagnostic printer - Print message and exit */
                     58: 
                     59: void xload_error(message)
                     60:     char *message;
                     61: {
                     62:     fprintf(stderr, "xload: %s\n", message);
                     63:     perror("xload");
                     64:     exit(1);
                     65: }
                     66: 
                     67: /* Blts data according to current size, then redraws the load average window.
                     68:  * Next represents the number of valid points in data.  Returns the (possibly)
                     69:  * adjusted value of next.  If next is 0, this routine draws an empty window
                     70:  * (scale - 1 lines for graph).  If next is less than the current window width,
                     71:  * the returned value is identical to the initial value of next and data is
                     72:  * unchanged.  Otherwise keeps half a window's worth of data.  If data is
                     73:  * changed, then max_loadavg is updated to reflect the largest data point.
                     74:  */
                     75: 
                     76: int repaint_window(width, height, next)
                     77:     register int width, height, next;
                     78: {
                     79:     register int i, j;
                     80: 
                     81:     if (mapped)
                     82:        XClear(win);
                     83:     if (next >= width) {
                     84:        j = width >> 1;
                     85:        bcopy((char *)(data + next - j),(char *)data, j * sizeof(double));
                     86:        next = j;
                     87:        /* Since we just lost some data, recompute the max_loadavg. */
                     88:        max_loadavg = 0.0;
                     89:        for (i = 0; i < next; i++) {
                     90:            if (data[i] > max_loadavg) max_loadavg = data[i];
                     91:        }
                     92:     }
                     93: 
                     94:     /* Compute the minimum scale required to graph the data, but don't go
                     95:        lower than min_scale. */
                     96:     if (max_loadavg > min_scale) scale = ((int)max_loadavg) + 1;
                     97:     else scale = min_scale;
                     98: 
                     99:     if (!mapped) return(next);
                    100: 
                    101:     /* Print hostname */
                    102:     XTextMask(win, 2, 2, host, strlen(host), font, highlight);
                    103: 
                    104:     /* Draw graph reference lines */
                    105:     for (i = 1; i < scale; i++) {
                    106:        j = (i * height) / scale;
                    107:        XLine(win, 0, j, width, j, 1, 1, highlight, GXcopy, AllPlanes);
                    108:     }
                    109: 
                    110:     /* Draw data point lines. */
                    111:     for (i = 0; i < next; i++)
                    112:        XLine(win, i, height, i, (int)(height - (data[i] * height) / scale),
                    113:                1, 1, foreground, GXcopy, AllPlanes);
                    114:     return(next);
                    115: }
                    116: 
                    117: /* Exit with message describing command line format */
                    118: 
                    119: void usage()
                    120: {
                    121:     fprintf(stderr,
                    122: "usage: xload [-fn {font}] [-update {seconds}] [-scale {integer}] [-rv]\n"
                    123: );
                    124:     fprintf(stderr,
                    125: "             [=[{width}][x{height}][{+-}{xoff}[{+-}{yoff}]]] [[{host}]:[{vs}]]\n"
                    126: );
                    127:     fprintf(stderr,
                    128: "             [-fg {color}] [-bg {color}] [-hl {color}] [-bd {color}] [-bw {pixels}]\n");
                    129:     exit(1);
                    130: }
                    131: 
                    132: /* Returns pointer to first char in search which is also in what, else NULL. */
                    133: 
                    134: char *strscan(search, what)
                    135:     register char *search;
                    136:     register char *what;
                    137: {
                    138:     register int i;
                    139:     register len = strlen(what);
                    140:     register char c;
                    141:     while (c = *(search++))
                    142:        for (i = 0; i < len; i++)
                    143:            if (c == what[i]) return (--search);
                    144:     return (NULL);
                    145: }
                    146: 
                    147: 
                    148: void main(argc, argv)
                    149:     int argc;
                    150:     char **argv;
                    151: {
                    152:     char *arg;
                    153: 
                    154:     register int i;
                    155: 
                    156:     register int kmem;                      /* kmem pointer */
                    157:     register double loadavg;                /* load average value */
                    158:     long loadavg_seek;                      /* offset to load average in kmem */
                    159: 
                    160:     char display[256];                      /* will contain vs host */
                    161:     int vsnum;                              /* will contain vs number */
                    162:     
                    163:     int reverse = 0;
                    164:     char *border_color;
                    165:     char *fore_color;
                    166:     char *back_color;
                    167:     char *high_color;
                    168:     int border_pixmap;
                    169:     int border_width = DEFAULT_BORDER_WIDTH;
                    170:     int update = DEFAULT_UPDATE;
                    171:     Color cdef;
                    172:     OpaqueFrame window;                            /* frame for the window */
                    173:     char *geometry = NULL;
                    174:     char *def = DEFAULT_POSITION;          /* default position */
                    175:     char *option;
                    176: 
                    177:     XEvent event;
                    178: 
                    179:     int maxfds;                             /* for select call */
                    180:     int readfds;
                    181:     int fdmask;
                    182:     struct timeval timeout;                 /* will contain update interval */
                    183: 
                    184:     /* Get name list. Then open kmem so we can seek for load average. */
                    185: 
                    186:     nlist("/vmunix", namelist);
                    187:     if (namelist[LOADAV].n_type == 0) xload_error("cannot get name list");
                    188:     loadavg_seek = namelist[LOADAV].n_value;
                    189:     kmem = open(KMEM_FILE, O_RDONLY);
                    190:     if (kmem < 0) xload_error(KMEM_ERROR);
                    191: 
                    192:     gethostname(host, sizeof(host));       /* Who are we? */
                    193:     display[0] = '\0';
                    194: 
                    195:     if ((option = XGetDefault(argv[0],"ReverseVideo")) != NULL )
                    196:                if (strcmp (option, "on") == 0)
                    197:                        reverse = 1;
                    198:     if ((option = XGetDefault(argv[0],"BorderWidth")) != NULL)
                    199:        border_width = atoi(option);
                    200:     if ((option = XGetDefault(argv[0],"BodyFont")) != NULL)
                    201:        fn = option;
                    202:     if ((border_color = XGetDefault(argv[0],"Border")) == NULL)
                    203:        border_color = XGetDefault(argv[0],"BorderColor");
                    204:     back_color = XGetDefault(argv[0],"Background");
                    205:     fore_color = XGetDefault(argv[0],"Foreground");
                    206:     high_color = XGetDefault(argv[0],"Highlight");
                    207:     if ((option = XGetDefault(argv[0],"Update")) != NULL)
                    208:        update = atoi(option);
                    209:     if ((option = XGetDefault(argv[0],"Scale")) != NULL)
                    210:        min_scale = atoi(option);
                    211:     if ((option = XGetDefault(argv[0], "Geometry")) != NULL)
                    212:        geometry = option;
                    213: 
                    214:     for (i = 1; i < argc; i++) {                       /* Parse line */
                    215:        if (argv[i][0] == '=') {
                    216:            geometry = argv[i];
                    217:            continue;
                    218:        }
                    219:        if (index(argv[i], ':') != NULL) {              /* host:display */
                    220:            strncpy(display, argv[i], sizeof(display));
                    221:            continue;
                    222:        }
                    223:        if (strcmp(argv[i], "-rv") == 0 ||
                    224:            strcmp(argv[i], "-reverse") == 0) {         /* black on white */
                    225:            reverse = 1;
                    226:            continue;
                    227:        }
                    228:        if (strcmp(argv[i], "-fw") == 0 ||
                    229:            strcmp(argv[i], "-forward") == 0) {         /* white on black */
                    230:            reverse = 0;
                    231:            continue;
                    232:        }
                    233:        if (strcmp(argv[i], "-bw") == 0 ||
                    234:            strcmp(argv[i], "-border") == 0) {          /* border width */
                    235:            if (++i >= argc) usage();
                    236:            border_width = atoi(argv[i]);
                    237:            continue;
                    238:        }
                    239:        if (strcmp(argv[i], "-fn") == 0 ||
                    240:            strcmp(argv[i], "-font") == 0) {            /* host name font */
                    241:            if (++i >= argc) usage();
                    242:            fn = argv[i];
                    243:            continue;
                    244:        }
                    245:        if (strcmp(argv[i], "-bd") == 0 ||
                    246:            strcmp(argv[i], "-color") == 0) {          /* border color */
                    247:           if (++i >= argc) usage();
                    248:           border_color = argv[i];
                    249:           continue;
                    250:        }
                    251:        if (strcmp(argv[i], "-fg") == 0 ||
                    252:            strcmp(argv[i], "-foreground") == 0) {     /* foreground color */
                    253:           if (++i >= argc) usage();
                    254:           fore_color = argv[i];
                    255:           continue;
                    256:        }
                    257:        if (strcmp(argv[i], "-bg") == 0 ||
                    258:            strcmp(argv[i], "-background") == 0) {     /* background color */
                    259:           if (++i >= argc) usage();
                    260:           back_color = argv[i];
                    261:           continue;
                    262:        }
                    263:        if (strcmp(argv[i], "-hl") == 0 ||
                    264:            strcmp(argv[i], "-highlight") == 0) {     /* highlight color */
                    265:           if (++i >= argc) usage();
                    266:           high_color = argv[i];
                    267:           continue;
                    268:        }
                    269:        if (strcmp(argv[i], "-u") == 0 ||
                    270:            strcmp(argv[i], "-update") == 0) {          /* update interval */
                    271:            if (++i >= argc) usage();
                    272:            update = atoi(argv[i]);
                    273:            continue;
                    274:        }
                    275:        if (strcmp(argv[i], "-s") == 0 ||
                    276:            strcmp(argv[i], "-scale") == 0) {           /* load scale */
                    277:            if (++i >= argc) usage();
                    278:            min_scale = atoi(argv[i]);
                    279:            continue;
                    280:        }
                    281:        usage();
                    282:     }
                    283: 
                    284:     if (border_width < 0) border_width = DEFAULT_BORDER_WIDTH;
                    285:     if (update < DEFAULT_UPDATE) update = DEFAULT_UPDATE;
                    286:     if (min_scale <= 0) min_scale = DEFAULT_SCALE;
                    287:     scale = min_scale;
                    288: 
                    289:     /* Open display  */
                    290:     if (!XOpenDisplay(display)) {
                    291:        fprintf(stderr, "%s: Can't open display '%s'\n",
                    292:                argv[0], XDisplayName(display));
                    293:        exit(1);
                    294:       }
                    295: 
                    296:     /* Need a font to print hostname in */
                    297:     font = XGetFont(fn);
                    298:     if (!font)
                    299:        xload_error("cannot open font");
                    300:     XQueryFont(font, &font_info);
                    301: 
                    302:     if (border_color && DisplayCells() > 2 &&
                    303:        XParseColor(border_color, &cdef) && XGetHardwareColor(&cdef))
                    304:        border_pixmap = XMakeTile(cdef.pixel);
                    305:     else if (reverse) border_pixmap = WhitePixmap;
                    306:     else border_pixmap = BlackPixmap;
                    307: 
                    308:     if (back_color && DisplayCells() > 2 &&
                    309:        XParseColor(back_color, &cdef) && XGetHardwareColor(&cdef))
                    310:        background = cdef.pixel;
                    311:     else if (reverse) background = BlackPixel;
                    312:     else background = WhitePixel;
                    313: 
                    314:     if (fore_color && DisplayCells() > 2 &&
                    315:        XParseColor(fore_color, &cdef) && XGetHardwareColor(&cdef))
                    316:        foreground = cdef.pixel;
                    317:     else if (reverse) foreground = WhitePixel;
                    318:     else foreground = BlackPixel;
                    319: 
                    320:     if (high_color && DisplayCells() > 2 &&
                    321:        XParseColor(high_color, &cdef) && XGetHardwareColor(&cdef))
                    322:        highlight = cdef.pixel;
                    323:     else highlight = foreground;
                    324: 
                    325:     window.bdrwidth = border_width;
                    326:     window.border = border_pixmap;
                    327:     window.background = XMakeTile(background);
                    328:     win = XCreate ("Load Average", argv[0], geometry, def, &window,
                    329:                   font_info.width * strlen(host) + 4, font_info.height + 4);
                    330:     XSelectInput(win, ExposeWindow|UnmapWindow);
                    331:     XMapWindow(win);                       /* Map window to screen */
                    332:     timeout.tv_sec = update;               /* Set up timeout for select */
                    333:     timeout.tv_usec = 0;
                    334:     maxfds = dpyno() + 1;                  /* Set up select arguments */
                    335:     fdmask = 1 << dpyno();
                    336:     i = 0;                                 /* Window is initially empty */
                    337: 
                    338:     while (1) {                                    /* Main loop */
                    339:        if (XPending()) {
                    340:            XNextEvent(&event);
                    341:            switch (event.type) {
                    342:            case ExposeWindow:
                    343:                mapped = 1;
                    344:                window.width = ((XExposeEvent *) &event)->width;
                    345:                window.height = ((XExposeEvent *) &event)->height;
                    346:                i = repaint_window(window.width, window.height, i);
                    347:                break;
                    348:            case UnmapWindow:
                    349:                mapped = 0;
                    350:                break;
                    351:            default:
                    352:                xload_error("unexpected X event");
                    353:            }
                    354:        }
                    355:        else if (i >= window.width) i = repaint_window(window.width, window.height, i);
                    356:        /* Get the load average, stash the point and draw corresponding line. */
                    357:        lseek(kmem, loadavg_seek, 0);
                    358: #ifdef sun
                    359:        {
                    360:                long temp;
                    361:                read(kmem, (char *)&temp, sizeof(long));
                    362:                loadavg = (double)temp/FSCALE;
                    363:        }
                    364: #else
                    365:        read(kmem, (char *)&loadavg, sizeof(double));
                    366: #endif
                    367: 
                    368:        /* Keep max_loadavg up to date, and if this data point is off the
                    369:           graph, change the scale to make it fit. */
                    370:        if (loadavg > max_loadavg) {
                    371:            max_loadavg = loadavg;
                    372:            if (max_loadavg > scale) {
                    373:                scale = ((int)max_loadavg) + 1;
                    374:                i = repaint_window(window.width, window.height, i);
                    375:            }
                    376:        }
                    377: 
                    378:        data[i] = loadavg;
                    379:        if (mapped) {
                    380:            XLine(win, i, window.height, i, 
                    381:                    (int)(window.height - (window.height * loadavg) / scale),
                    382:                    1, 1, foreground, GXcopy, AllPlanes);
                    383:            XFlush();                       /* Flush output buffers */
                    384:        }
                    385:        i++;                                /* Next point */
                    386:        readfds = fdmask;                   /* Initialize select mask */
                    387:                                            /* and select on display fd */
                    388:        if (select(maxfds, &readfds, NULL, NULL, &timeout) == -1)
                    389:            xload_error("select error on display file descriptor");
                    390:     } /* while */
                    391: } /* main */

unix.superglobalmegacorp.com

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