Annotation of 43BSDTahoe/new/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.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.