bobs@rand.org (Rober Schwartzkopf) (06/18/91)
Submitted-by: Rober Schwartzkopf <bobs@rand.org> Posting-number: Volume 13, Issue 56 Archive-name: xmeter/patch6 Patch-To: xmeter: Volume 9, Issue 59 (9/28/90) This is xmeter patchlevel 6. Changes since the previous release include new option (-v) to print xmeter version, defstat option to change the default statistic to be watched, clearing of stripchart widgets when watched stat is changed, and better handling of dead hosts, as well as a couple of minor bug fixes. Bob Schwartzkopf (bobs@rand.org) #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: patchlevel.h README Imakefile xmeter.c xmeter.man # XMeter.ad # Wrapped by root@boris on Mon Jun 3 15:27:22 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'patchlevel.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'patchlevel.h'\" else echo shar: Extracting \"'patchlevel.h'\" \(21 characters\) sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE' X#define PATCHLEVEL 6 END_OF_FILE if test 21 -ne `wc -c <'patchlevel.h'`; then echo shar: \"'patchlevel.h'\" unpacked with wrong size! fi # end of 'patchlevel.h' fi if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(1879 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' Xxmeter displays a histogram of data returned by rstat(3). It can be Xtold to monitor multiple hosts, or to monitor multiple statistics on the Xsame host. X XAuthor: Bob Schwartzkopf (bobs@rand.org) X The RAND Corporation X 1700 Main Street X Santa Monica, CA 90406-2138 X XEdit history X XPatchlevel 6 X - Clear stripcharts when monitored statistic is changed. X - Allow setting of monitored stat in .Xdefaults. X - Added -v option to display version number. X - Fork new process to wait for dead host to come back up. X XPatchlevel 5 X - Put explict closes of sockets back in after clnt_destroy(). X Apparently some versions of clnt_destroy don't close the X socket. X - Minor changes to XMeter.ad. X XPatchlevel 4 X - Allow user to specify foreground, border, internal border and X highlight color for each level. X - Fixed bug in determining width/height of form widget. X - Allow user to specify label foreground and background colors X independently of stripcharts. X - Made all colors either class Foreground or Background, should X simplify .Xdefaults files. X XPatchlevel 3 X - Added "cols" and "rows" options, allows rectangular X layout of graphs. Removed "orientation" option. X - Backgrounds of stripcharts can now be set to user specified X bitmaps with "*Bitmap" resources. X - Added op, wp, ep and fp options, which takes a program name as an X argument. When a graph enters state OK, WARN, ERROR or FATAL, the X specified program is invoked. X - Added menus which allow the monitored statistic to be changed X on the fly. X XPatchlevel 2 X - Changed resource name of paned widgets to host name. X - Used actual time between rstat(3) calls instead of "update" X interval for computing graph values. X - Rewrote functions that return graph values. X - Fixed divide by 0 errors in fcpu(), fsys() and fuser(). X - Use RSTATVERS_TIME instead of RSTATVERS. X XPatchlevel 1 X - Fixed memory leak. END_OF_FILE if test 1879 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'Imakefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Imakefile'\" else echo shar: Extracting \"'Imakefile'\" \(369 characters\) sed "s/^X//" >'Imakefile' <<'END_OF_FILE' X INCLUDES = -I$(TOP) -I$(TOP)/X11 X DEPLIBS = XawClientDepLibs XLOCAL_LIBRARIES = XawClientLibs X SYS_LIBRARIES = -lrpcsvc X SRCS = xmeter.c X OBJS = xmeter.o X SHARS = patchlevel.h README Imakefile xmeter.c xmeter.man XMeter.ad X XComplexProgramTarget(xmeter) XInstallAppDefaults(XMeter) X Xxmeter.shar: $(SHARS) X shar -o xmeter.shar $(SHARS) END_OF_FILE if test 369 -ne `wc -c <'Imakefile'`; then echo shar: \"'Imakefile'\" unpacked with wrong size! fi # end of 'Imakefile' fi if test -f 'xmeter.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xmeter.c'\" else echo shar: Extracting \"'xmeter.c'\" \(33499 characters\) sed "s/^X//" >'xmeter.c' <<'END_OF_FILE' X/* X * xmeter.c - Display histogram of rstat(3) output for multiple hosts. X * X * Author: Bob Schwartzkopf, The RAND Corporation X * X * Suggestions for improvements and bug fixes can be sent to "bobs@rand.org". X * As my schedule permits I'll try to incorporate them. X */ X X#ifndef lint Xstatic char *RCSid="$Header: /usr/rand/src/bin/xmeter/RCS/xmeter.c,v 1.7 1991/06/03 22:21:43 root Exp $"; X#endif lint X X/* X * $Log: xmeter.c,v $ X * Revision 1.7 1991/06/03 22:21:43 root X * Add -v option to print xmeter version number. X * Add defstat option. X * Add code to clear stripchart when watched stat is changed. X * When host is down fork process to wait for it to come up instead of X * having toplevel process wait for timeouts. X * X * Revision 1.6 90/09/28 20:32:34 root X * Add explicit closes of sockets back in, apparently some versions of X * clnt_destroy() don't do it automatically. X * X * Revision 1.5 90/09/18 20:47:03 root X * Allow user specification of foreground colors. X * X * Revision 1.4 90/08/20 14:18:01 root X * Added menus, column and row options, background bitmaps, and user X * specifiable programs to be invoked when graphs change state. X * X * Revision 1.3 90/06/07 16:17:06 bobs X * Removed "retries". X * Changed name of paned widgets to host name displayed in that widget. X * Used actual time between rstat calls instead of "update" interval in X * computing rates in functions that return values to stripchart widgets. X * Removed "ost" variable, rewrote functions that return values to X * stripcharts. X * Fixed bug in fsys, fcpu and fuser that could cause divide by 0 errors. X * Fixed rpc timeout handling in getmeter and getport. X * Use RSTATVERS_TIME instead of RSTATVERS, which isn't defined in SunOS 4.1. X * X * Revision 1.2 90/05/04 12:31:52 bobs X * Fix memory leak in getport(). Wasn't freeing resources allocated by X * clntudp_create when clnt_call failed. Also removed explicit calls X * to close sockets since clnt_destroy() does this. X * X * Revision 1.1 90/04/30 14:33:59 bobs X * Initial revision X * X */ X X#include <stdio.h> X#include <sys/time.h> X#include <sys/param.h> X#include <sys/socket.h> X#include <sys/dk.h> X#include <signal.h> X#include <netdb.h> X#include <rpc/rpc.h> X#include <rpc/pmap_prot.h> X#include <rpcsvc/rstat.h> X#include <X11/Xlib.h> X#include <X11/Intrinsic.h> X#include <X11/StringDefs.h> X#include <X11/Xatom.h> X#include <X11/Shell.h> X#include <X11/Xaw/Cardinals.h> X#include <X11/Xaw/Form.h> X#include <X11/Xaw/StripChart.h> X#include <X11/Xaw/SimpleMenu.h> X#include <X11/Xaw/MenuButton.h> X#include <X11/Xaw/SmeBSB.h> X#include <X11/Xaw/Paned.h> X#include <X11/Xmu/Xmu.h> X#include "patchlevel.h" X X#define MAJORVERSION 1 X#define DMSG "down" X#define OK 0 X#define WARN 1 X#define ERROR 2 X#define FATAL 3 X#define MAXBACKS (FATAL+1) X#define STATMENU "statmenu" X#ifndef FSCALE X#define FSCALE (1 << 8) X#endif X X/* X * There is one METER structure per strip chart. If multiple stats X * on a single host are being watched we save rstatd calls by sharing X * part of this structure (SHMETER) between the different meters watching X * the same host. X */ Xtypedef struct _shmeter { X char *name; /* Host name */ X struct sockaddr_in addr; X CLIENT *clnt; X int s; /* Socket */ X struct statstime st[2]; /* Keep last 2 stats to compute diffs */ X int idx; /* Index into st array */ X int refcnt; /* Meters sharing this structure */ X int curcnt; /* Meters who've displayed current data */ X int first; /* TRUE when only 1 rstat has been done */ X int pid; /* Pid of proc waiting for host */ X struct _shmeter *nxt; /* Link these together */ X} SHMETER; X Xtypedef struct _meter { X char *label; X int stat; /* Which stat to watch */ X Widget pdwidget; /* Paned widget */ X Widget mbwidget; /* MenuButton widget */ X Widget scwidget; /* StripChart widget */ X int oldstate; /* Save state so know when to */ X /* change backgrounds */ X SHMETER *sh; /* Shared info */ X Pixmap pm; /* Current background pixmap */ X int oldjumpscroll; /* Old jumpscroll value */ X struct _meter *nxt; X} METER; X X/* X * There is a STATDATA structure for each statistic that can be monitored. X */ Xtypedef struct { X int scale; /* Each stat is scaled */ X int (*val)(); /* Function that computes this stat */ X char *name; /* Name of stat for menu widget */ X} STATDATA; X X/* X * xmeter supports 4 background colors and pixmaps that it will switch X * between as a meter changes state, called OK, WARN, ERROR and FATAL. X * The background bitmaps are stored in BITMAP structures. X */ Xtypedef struct { X int w; /* Width of bitmap */ X int h; /* Height of bitmap */ X Pixmap bm; /* Bitmap */ X} BITMAP; X X/* X * Functions X */ Xextern char *malloc (); Xextern char *index (); Xint getstatus (); Xint changestat (); Xint selecthost (); Xint freechild (); XMETER *initmeter (); Xint fcoll (), fcpu (), fierr (), fintr (), fipkt (), fload (); Xint foerr (), fopkt (), fpage (), fpgpgin (), fpgpgout (); Xint fpswpin (), fpswpout (), fswt (), fsys (), fuser (); X XSTATDATA sd[] = { X#define S_COLL 0 X {1, fcoll, "coll"}, X#define S_CPU S_COLL+1 X {1, fcpu, "cpu"}, X#define S_IERR S_CPU+1 X {1, fierr, "ierr"}, X#define S_INTR S_IERR+1 X {1, fintr, "intr"}, X#define S_IPKT S_INTR+1 X {1, fipkt, "ipkt"}, X#define S_LOAD S_IPKT+1 X {1, fload, "load"}, X#define S_OERR S_LOAD+1 X {1, foerr, "oerr"}, X#define S_OPKT S_OERR+1 X {1, fopkt, "opkt"}, X#define S_PAGE S_OPKT+1 X {1, fpage, "page"}, X#define S_PGPGIN S_PAGE+1 X {1, fpgpgin, "pgpgin"}, X#define S_PGPGOUT S_PGPGIN+1 X {1, fpgpgout, "pgpgout"}, X#define S_PSWPIN S_PGPGOUT+1 X {1, fpswpin, "pswpin"}, X#define S_PSWPOUT S_PSWPIN+1 X {1, fpswpout, "pswpout"}, X#define S_SWT S_PSWPOUT+1 X {1, fswt, "swt"}, X#define S_SYS S_SWT+1 X {1, fsys, "sys"}, X#define S_USER S_SYS+1 X {1, fuser, "user"}, X}; X#define DEFSTATNAME "load" X#define MAXSTAT (sizeof (sd) / sizeof (STATDATA)) X#define MAXSTATNAME 10 /* Max length of stat name */ X Xstatic char *progname; XPixel back[MAXBACKS]; /* Meter backgrounds */ XPixel fore[MAXBACKS]; /* Meter foregrounds */ XPixel hl[MAXBACKS]; /* Meter highlights */ XPixel bd[MAXBACKS]; /* Meter borders */ XPixel ibd[MAXBACKS]; /* Meter internal bds */ XPixel lback[MAXBACKS]; /* Label backgrounds */ XPixel lfore[MAXBACKS]; /* Label foregrounds */ XBITMAP bitmap[MAXBACKS]; /* Stripchart bg pixmaps*/ XPixmap bitmapdef = XtUnspecifiedPixmap; Xint warnLevel; /* Warning level */ Xint errorLevel; /* Error level */ Xstatic struct timeval ptto = {0, 0}; /* RPC timeout interval */ Xstatic struct timeval tto = {0, 0}; /* Total timeout */ Xstatic SHMETER *shmeters = NULL; /* List of SHMETERs */ Xstatic METER *selected; /* Current meter */ Xstatic METER *meterlist = NULL; /* List of METERs */ Xint columns; /* Columns to display */ Xint rows; /* Rows to display */ Xint timeout; /* RPC timeout */ Xint retries; /* RPC retries */ Xint loadscaledef = FSCALE; /* Scale for load ave. */ XBoolean shortname; /* Short hostname flag */ XString prog[MAXBACKS]; /* Alert programs */ XString defstat; /* Default stat */ Xstatic XtResource application_resources[] = { X {"columns", "Columns", XtRInt, sizeof (int), X (Cardinal) &columns, XtRString, "0"}, X {"defStat", "DefStat", XtRString, sizeof (char *), X (Cardinal) &defstat, XtRString, DEFSTATNAME}, X {"errorBack", XtCBackground, XtRPixel, sizeof (Pixel), X (Cardinal) &back[ERROR], XtRString, XtDefaultBackground}, X {"errorBd", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &bd[ERROR], XtRString, XtDefaultForeground}, X {"errorBitmap", XtCBitmap, XtRBitmap, sizeof (Pixmap), X (Cardinal) &bitmap[ERROR].bm, XtRBitmap, (caddr_t) &bitmapdef}, X {"errorFore", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &fore[ERROR], XtRString, XtDefaultForeground}, X {"errorHl", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &hl[ERROR], XtRString, XtDefaultForeground}, X {"errorIbd", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &ibd[ERROR], XtRString, XtDefaultForeground}, X {"errorLevel", "ErrorLevel", XtRInt, sizeof (int), X (Cardinal) &errorLevel, XtRString, "6"}, X {"errorProg", "Program", XtRString, sizeof (char *), X (Cardinal) &prog[ERROR], XtRString, NULL}, X {"fatalBack", XtCBackground, XtRPixel, sizeof (Pixel), X (Cardinal) &back[FATAL], XtRString, XtDefaultBackground}, X {"fatalBd", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &bd[FATAL], XtRString, XtDefaultForeground}, X {"fatalBitmap", XtCBitmap, XtRBitmap, sizeof (Pixmap), X (Cardinal) &bitmap[FATAL].bm, XtRBitmap, (caddr_t) &bitmapdef}, X {"fatalFore", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &fore[FATAL], XtRString, XtDefaultForeground}, X {"fatalHl", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &hl[FATAL], XtRString, XtDefaultForeground}, X {"fatalIbd", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &ibd[FATAL], XtRString, XtDefaultForeground}, X {"fatalProg", "Program", XtRString, sizeof (char *), X (Cardinal) &prog[FATAL], XtRString, NULL}, X {"lErrorBack", XtCBackground, XtRPixel, sizeof (Pixel), X (Cardinal) &lback[ERROR], XtRString, XtDefaultBackground}, X {"lErrorFore", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &lfore[ERROR], XtRString, XtDefaultForeground}, X {"lFatalBack", XtCBackground, XtRPixel, sizeof (Pixel), X (Cardinal) &lback[FATAL], XtRString, XtDefaultBackground}, X {"lFatalFore", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &lfore[FATAL], XtRString, XtDefaultForeground}, X {"lOkBack", XtCBackground, XtRPixel, sizeof (Pixel), X (Cardinal) &lback[OK], XtRString, XtDefaultBackground}, X {"lOkFore", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &lfore[OK], XtRString, XtDefaultForeground}, X {"lWarnBack", XtCBackground, XtRPixel, sizeof (Pixel), X (Cardinal) &lback[WARN], XtRString, XtDefaultBackground}, X {"lWarnFore", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &lfore[WARN], XtRString, XtDefaultForeground}, X {"okBack", XtCBackground, XtRPixel, sizeof (Pixel), X (Cardinal) &back[OK], XtRString, XtDefaultBackground}, X {"okBd", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &bd[OK], XtRString, XtDefaultForeground}, X {"okBitmap", XtCBitmap, XtRBitmap, sizeof (Pixmap), X (Cardinal) &bitmap[OK].bm, XtRBitmap, (caddr_t) &bitmapdef}, X {"okFore", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &fore[OK], XtRString, XtDefaultForeground}, X {"okHl", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &hl[OK], XtRString, XtDefaultForeground}, X {"okIbd", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &ibd[OK], XtRString, XtDefaultForeground}, X {"okProg", "Program", XtRString, sizeof (char *), X (Cardinal) &prog[OK], XtRString, NULL}, X {"retries", "Retries", XtRInt, sizeof (int), X (Cardinal) &retries, XtRString, "2"}, X {"rows", "Rows", XtRInt, sizeof (int), X (Cardinal) &rows, XtRString, "0"}, X {"scaleColl", "ScaleColl", XtRInt, sizeof (int), X (Cardinal) &sd[S_COLL].scale, XtRString, "1"}, X {"scaleCpu", "ScaleCpu", XtRInt, sizeof (int), X (Cardinal) &sd[S_CPU].scale, XtRString, "20"}, X {"scaleIerr", "ScaleIerr", XtRInt, sizeof (int), X (Cardinal) &sd[S_IERR].scale, XtRString, "1"}, X {"scaleIntr", "ScaleIntr", XtRInt, sizeof (int), X (Cardinal) &sd[S_INTR].scale, XtRString, "50"}, X {"scaleIpkt", "ScaleIpkt", XtRInt, sizeof (int), X (Cardinal) &sd[S_IPKT].scale, XtRString, "20"}, X {"scaleLoad", "ScaleLoad", XtRInt, sizeof (int), X (Cardinal) &sd[S_LOAD].scale, XtRInt, (caddr_t) &loadscaledef}, X {"scaleOerr", "ScaleOerr", XtRInt, sizeof (int), X (Cardinal) &sd[S_OERR].scale, XtRString, "1"}, X {"scaleOpkt", "ScaleOpkt", XtRInt, sizeof (int), X (Cardinal) &sd[S_OPKT].scale, XtRString, "20"}, X {"scalePage", "ScalePage", XtRInt, sizeof (int), X (Cardinal) &sd[S_PAGE].scale, XtRString, "10"}, X {"scalePgpgin", "ScalePgpgin", XtRInt, sizeof (int), X (Cardinal) &sd[S_PGPGIN].scale, XtRString, "10"}, X {"scalePgpgout", "ScalePgpgout", XtRInt, sizeof (int), X (Cardinal) &sd[S_PGPGOUT].scale, XtRString, "10"}, X {"scalePswpin", "ScalePswpin", XtRInt, sizeof (int), X (Cardinal) &sd[S_PSWPIN].scale, XtRString, "1"}, X {"scalePswpout", "ScalePswpout", XtRInt, sizeof (int), X (Cardinal) &sd[S_PSWPOUT].scale, XtRString, "1"}, X {"scaleSwt", "ScaleSwt", XtRInt, sizeof (int), X (Cardinal) &sd[S_SWT].scale, XtRString, "30"}, X {"scaleSys", "ScaleSys", XtRInt, sizeof (int), X (Cardinal) &sd[S_SYS].scale, XtRString, "20"}, X {"scaleUser", "ScaleUser", XtRInt, sizeof (int), X (Cardinal) &sd[S_USER].scale, XtRString, "20"}, X {"shortName", "Shortname", XtRBoolean, sizeof (Boolean), X (Cardinal) &shortname, XtRString, "False"}, X {"timeout", "Timeout", XtRInt, sizeof (int), X (Cardinal) &timeout, XtRString, "5"}, X {"warnBack", XtCBackground, XtRPixel, sizeof (Pixel), X (Cardinal) &back[WARN], XtRString, XtDefaultBackground}, X {"warnBd", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &bd[WARN], XtRString, XtDefaultForeground}, X {"warnBitmap", XtCBitmap, XtRBitmap, sizeof (Pixmap), X (Cardinal) &bitmap[WARN].bm, XtRBitmap, (caddr_t) &bitmapdef}, X {"warnFore", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &fore[WARN], XtRString, XtDefaultForeground}, X {"warnHl", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &hl[WARN], XtRString, XtDefaultForeground}, X {"warnIbd", XtCForeground, XtRPixel, sizeof (Pixel), X (Cardinal) &ibd[WARN], XtRString, XtDefaultForeground}, X {"warnLevel", "WarnLevel", XtRInt, sizeof (int), X (Cardinal) &warnLevel, XtRString, "3"}, X {"warnProg", "Program", XtRString, sizeof (char *), X (Cardinal) &prog[WARN], XtRString, NULL}, X}; Xstatic XrmOptionDescRec options[] = { X {"-cols", "columns", XrmoptionSepArg, NULL}, X {"-ebd", "errorBd", XrmoptionSepArg, NULL}, X {"-ebg", "errorBack", XrmoptionSepArg, NULL}, X {"-efg", "errorFore", XrmoptionSepArg, NULL}, X {"-ehl", "errorHl", XrmoptionSepArg, NULL}, X {"-eibd", "errorIbd", XrmoptionSepArg, NULL}, X {"-elevel", "errorLevel", XrmoptionSepArg, NULL}, X {"-ep", "errorProg", XrmoptionSepArg, NULL}, X {"-fbd", "fatalBd", XrmoptionSepArg, NULL}, X {"-fbg", "fatalBack", XrmoptionSepArg, NULL}, X {"-ffg", "fatalFore", XrmoptionSepArg, NULL}, X {"-fhl", "fatalHl", XrmoptionSepArg, NULL}, X {"-fibd", "fatalIbd", XrmoptionSepArg, NULL}, X {"-fp", "fatalProg", XrmoptionSepArg, NULL}, X {"-h", "*Paned.height", XrmoptionSepArg, NULL}, X {"-lebg", "lErrorBack", XrmoptionSepArg, NULL}, X {"-lefg", "lErrorFore", XrmoptionSepArg, NULL}, X {"-lfbg", "lFatalBack", XrmoptionSepArg, NULL}, X {"-lffg", "lFatalFore", XrmoptionSepArg, NULL}, X {"-lobg", "lOkBack", XrmoptionSepArg, NULL}, X {"-lofg", "lOkFore", XrmoptionSepArg, NULL}, X {"-lwbg", "lWarnBack", XrmoptionSepArg, NULL}, X {"-lwfg", "lWarnFore", XrmoptionSepArg, NULL}, X {"-obd", "okBd", XrmoptionSepArg, NULL}, X {"-obg", "okBack", XrmoptionSepArg, NULL}, X {"-ofg", "okFore", XrmoptionSepArg, NULL}, X {"-ohl", "okHl", XrmoptionSepArg, NULL}, X {"-oibd", "okIbd", XrmoptionSepArg, NULL}, X {"-op", "okProg", XrmoptionSepArg, NULL}, X {"-rows", "rows", XrmoptionSepArg, NULL}, X {"-rt", "retries", XrmoptionSepArg, NULL}, X {"-scoll", "scaleColl", XrmoptionSepArg, NULL}, X {"-scpu", "scaleCpu", XrmoptionSepArg, NULL}, X {"-sierr", "scaleIerr", XrmoptionSepArg, NULL}, X {"-sintr", "scaleIntr", XrmoptionSepArg, NULL}, X {"-sipkt", "scaleIpkt", XrmoptionSepArg, NULL}, X {"-sload", "scaleLoad", XrmoptionSepArg, NULL}, X {"-sn", "shortName", XrmoptionNoArg, "on"}, X {"-soerr", "scaleOerr", XrmoptionSepArg, NULL}, X {"-sopkt", "scaleOpkt", XrmoptionSepArg, NULL}, X {"-spage", "scalePage", XrmoptionSepArg, NULL}, X {"-spgpgin", "scalePgpgin", XrmoptionSepArg, NULL}, X {"-spgpgout", "scalePgpgout", XrmoptionSepArg, NULL}, X {"-spswpin", "scalePswpin", XrmoptionSepArg, NULL}, X {"-spswpout", "scalePswpout", XrmoptionSepArg, NULL}, X {"-sswt", "scaleSwt", XrmoptionSepArg, NULL}, X {"-ssys", "scaleSys", XrmoptionSepArg, NULL}, X {"-suser", "scaleUser", XrmoptionSepArg, NULL}, X {"-to", "timeout", XrmoptionSepArg, NULL}, X {"-update", "*StripChart.update", XrmoptionSepArg, NULL}, X {"-w", "*Paned.width", XrmoptionSepArg, NULL}, X {"-wbd", "warnBd", XrmoptionSepArg, NULL}, X {"-wbg", "warnBack", XrmoptionSepArg, NULL}, X {"-wfg", "warnFore", XrmoptionSepArg, NULL}, X {"-whl", "warnHl", XrmoptionSepArg, NULL}, X {"-wibd", "warnIbd", XrmoptionSepArg, NULL}, X {"-wlevel", "warnLevel", XrmoptionSepArg, NULL}, X {"-wp", "warnProg", XrmoptionSepArg, NULL}, X}; Xstatic Arg formargs[] = { X {XtNdefaultDistance, 1}, /* Spacing */ X {XtNresizable, TRUE }, /* Resizable */ X}; X Xmain (argc, argv) X Xint argc; Xchar **argv; X X{ X Widget toplevel; X Widget form; X Widget pane = NULL; X int i; X int n; X Arg args[10]; X XtAppContext appcon; X String mbtrans = X "<EnterWindow>: highlight()\n\ X <LeaveWindow>: reset()\n\ X <BtnDown>: set() notify() PopupMenu()"; X XtTranslations mbtt; X Widget *lw; /* Last column or row of widgets */ X int numwgt; X X progname = argv[0]; X toplevel = XtAppInitialize (&appcon, "XMeter", options, X XtNumber (options), &argc, argv, NULL, NULL, ZERO); X XtGetApplicationResources (toplevel, NULL, application_resources, X XtNumber (application_resources), NULL, 0); X form = XtCreateManagedWidget ("form", formWidgetClass, toplevel, X formargs, XtNumber (formargs)); X if (argc < 2) X usage (); X if (strcmp ("-v", argv[1]) == 0) X printversion (); X init (toplevel, &lw); X createmenus (form); X mbtt = XtParseTranslationTable (mbtrans); X /* X * Each meter consists of a paned widget, each paned widget has two X * children, which are a menubutton widget and stripchart widget. X * The following loop creates and initializes the appropriate widgets. X */ X for (i = 1, numwgt = 0; i < argc; i++, numwgt++) { X meterlist = initmeter (meterlist, &i, argc, argv); X /* X * Create paned widget. X */ X n = 0; X if (columns > 0) { /* Locate pane in form ... */ X XtSetArg (args[n], XtNfromVert, lw[numwgt % columns]); n++; X if (numwgt % columns != 0) { X XtSetArg (args[n], XtNfromHoriz, pane); n++; X } X } else { X XtSetArg (args[n], XtNfromHoriz, lw[numwgt % rows]); n++; X if (numwgt % rows != 0) { X XtSetArg (args[n], XtNfromVert, pane); n++; X } X } X XtSetArg (args[n], XtNborder, bd[OK]); n++; X XtSetArg (args[n], XtNinternalBorderColor, ibd[OK]); n++; X pane = XtCreateManagedWidget (meterlist->sh->name, panedWidgetClass, X form, args, n); X lw[numwgt % (columns > 0 ? columns : rows)] = pane; X meterlist->pdwidget = pane; X /* X * Create menubutton widget. X */ X n = 0; X XtSetArg (args[n], XtNshowGrip, XtEno); n++; X XtSetArg (args[n], XtNlabel, meterlist->label); n++; X XtSetArg (args[n], XtNbackground, lback[OK]); n++; X XtSetArg (args[n], XtNforeground, lfore[OK]); n++; X XtSetArg (args[n], XtNmenuName, STATMENU); n++; X XtSetArg (args[n], XtNtranslations, mbtt); n++; X meterlist->mbwidget = XtCreateManagedWidget ("menu", X menuButtonWidgetClass, pane, args, n); X XtRemoveAllCallbacks (meterlist->mbwidget, XtNcallback); X XtAddCallback (meterlist->mbwidget, XtNcallback, selecthost, meterlist); X /* X * Create stripchart widget. X */ X n = 0; X XtSetArg (args[n], XtNfromVert, meterlist->mbwidget); n++; X XtSetArg (args[n], XtNresizable, TRUE); n++; X XtSetArg (args[n], XtNbackground, back[OK]); n++; X XtSetArg (args[n], XtNforeground, fore[OK]); n++; X XtSetArg (args[n], XtNhighlight, hl[OK]); n++; X meterlist->scwidget = XtCreateManagedWidget ("load", X stripChartWidgetClass, pane, args, n); X XtRemoveAllCallbacks (meterlist->scwidget, XtNgetValue); X XtAddCallback (meterlist->scwidget, XtNgetValue, getstatus, meterlist); X } X free (lw); X signal (SIGCHLD, freechild); /* Clean up after our children */ X XtRealizeWidget (toplevel); X setokbackgrounds (XtDisplay (toplevel), XtScreen (toplevel)); X XtAppMainLoop (appcon); X} X Xusage () X X{ X int i; X X fprintf (stderr, "Usage: %s [toolkit options] [options] [stat] host ...\n", X progname); X fprintf (stderr, " Options are:"); X for (i = 0; i < XtNumber (options); i++) { X if (i % 8 == 0) X fprintf (stderr, "\n "); X else X fprintf (stderr, ", "); X fprintf (stderr, "%s", options[i].option); X } X fprintf (stderr, ", -v\n Stats to watch are:"); X for (i = 0; i < MAXSTAT; i++) { X if (i % 8 == 0) X fprintf (stderr, "\n "); X else X fprintf (stderr, ", "); X fprintf (stderr, "-%s", sd[i].name); X } X fprintf (stderr, "\n"); X exit (1); X} X X/* X * printversion - Print version number and exit. X */ Xprintversion () X X{ X printf ("XMeter version %d.%d\n", MAJORVERSION, PATCHLEVEL); X exit (0); X} X X/* X * init - Initialze various globals. X */ Xinit (toplevel, lw) X XWidget toplevel; XWidget **lw; X X{ X int i; X Window rw; X int x; X int y; X int bwidth; X int depth; X X ptto.tv_sec = timeout; X tto.tv_sec = timeout * retries; X if (columns <= 0 && rows <= 0) X columns = 1; X if (columns > 0) { X if ((*lw = (Widget *) calloc (columns, sizeof (Widget))) == NULL) X fatal ("lw"); X } else X if ((*lw = (Widget *) calloc (rows, sizeof (Widget))) == NULL) X fatal ("lw"); X for (i = 0; i < MAXBACKS; i++) X if (bitmap[i].bm != bitmapdef) /* Get bitmap dimensions */ X XGetGeometry (XtDisplay (toplevel), bitmap[i].bm, &rw, &x, &y, X &bitmap[i].w, &bitmap[i].h, &bwidth, &depth); X} X X/* X * createmenus - Create menus used by each meter. Currently there's just X * one which consists of the stats that can be monitored. X */ Xcreatemenus (parent) X XWidget parent; X X{ X int i; X int n; X Widget menu; X Widget me; X Arg args[10]; X X menu = XtCreatePopupShell (STATMENU, simpleMenuWidgetClass, parent, X NULL, ZERO); X for (i = 0; i < MAXSTAT; i++) { X n = 0; X XtSetArg (args[n], XtNlabel, sd[i].name); n++; X me = XtCreateManagedWidget (sd[i].name, smeBSBObjectClass, menu, X args, n); X XtRemoveAllCallbacks (me, XtNcallback); X XtAddCallback (me, XtNcallback, changestat, i); X } X} X X/* X * setokbackgrounds - Set initial background pixmaps. Can't do this X * when the stripchart widgets are created as they have to be X * realized apparently before the pixmaps can be created. X */ Xsetokbackgrounds (d, s) X XDisplay *d; XScreen *s; X X{ X METER *h; X int n; X Arg args[10]; X X if (bitmap[OK].bm != bitmapdef) { X for (h = meterlist; h; h = h->nxt) { X h->pm = XmuCreatePixmapFromBitmap (d, XtWindow (h->scwidget), X bitmap[OK].bm, X bitmap[OK].w, bitmap[OK].h, X DefaultDepthOfScreen (s), X fore[OK], X back[OK]); X n = 0; X XtSetArg (args[n], XtNbackgroundPixmap, h->pm); n++; X XtSetValues (h->scwidget, args, n); X } X } X} X X/* X * freechild - Clean up child processes. X */ Xfreechild () X X{ X int status; X int pid; X METER *h; X X pid = wait (&status); X for (h = meterlist; h; h = h->nxt) X if (h->sh->pid == pid) { /* Start updating host again */ X h->sh->pid = -1; X break; X } X} X X/* X * getstatus - Get status from remote host, update meter appropriately, X * including changing colors, background pixmap and label if necessary. X */ Xgetstatus (w, h, data) X XWidget w; XMETER *h; Xchar *data; X X{ X int l; X int n; X int s; X register SHMETER *sh; X Arg args[10]; X X sh = h->sh; X if (h->oldstate == FATAL && sh->pid != -1) /* Ignore dead hosts */ X return; X if (h->oldjumpscroll) { /* Restore old jumpscroll value */ X n = 0; X XtSetArg (args[n], XtNjumpScroll, h->oldjumpscroll); n++; X XtSetValues (h->scwidget, args, n); X h->oldjumpscroll = 0; X } X s = state (l = getmeter (h), h); X *(double *) data = s == FATAL ? 0.0 : (double) l / sd[h->stat].scale; X if (s != h->oldstate) { X if (bitmap[h->oldstate].bm != bitmapdef) X XFreePixmap (XtDisplay (w), h->pm); X n = 0; /* Update stripchart widget */ X XtSetArg (args[n], XtNbackground, back[s]); n++; X XtSetArg (args[n], XtNforeground, fore[s]); n++; X XtSetArg (args[n], XtNhighlight, hl[s]); n++; X if (bitmap[s].bm != bitmapdef) { X h->pm = XmuCreatePixmapFromBitmap (XtDisplay (w), X XtWindow (w), X bitmap[s].bm, X bitmap[s].w, bitmap[s].h, X DefaultDepthOfScreen(XtScreen(w)), X fore[s], X back[s]); X XtSetArg (args[n], XtNbackgroundPixmap, h->pm); n++; X } else if (bitmap[h->oldstate].bm != bitmapdef) { X XtSetArg (args[n], XtNbackgroundPixmap, XtUnspecifiedPixmap); n++; X } X XtSetValues (w, args, n); X n = 0; /* Update menubutton widget */ X XtSetArg (args[n], XtNbackground, lback[s]); n++; X XtSetArg (args[n], XtNforeground, lfore[s]); n++; X if (s == FATAL || h->oldstate == FATAL) { X sprintf (h->label, "%s %s", sh->name, X s == FATAL ? DMSG : sd[h->stat].name); X XtSetArg (args[n], XtNlabel, h->label); n++; X } X XtSetValues (h->mbwidget, args, n); X n = 0; /* Update paned widget */ X XtSetArg (args[n], XtNborder, bd[s]); n++; X XtSetArg (args[n], XtNinternalBorderColor, ibd[s]); n++; X XtSetValues (h->pdwidget, args, n); X if (prog[s]) X runprog (h, s); X if (s == FATAL) X sh->pid = waitforhost (h); X } X h->oldstate = s; X} X X/* X * waitforhost - Fork process which will wait for host to come back up. X */ Xint waitforhost (h) X XMETER *h; X X{ X int pid; X X if (pid = fork ()) X return (pid); X while (1) { X sleep (10); X if (getport (h) >= 0) X exit (0); X } X} X X/* X * runprog - Run user specified alert program. X */ Xrunprog (h, s) X XMETER *h; Xint s; X X{ X char oldstate[4]; X char state[4]; X X sprintf (oldstate, "%d", h->oldstate); X sprintf (state, "%d", s); X if (vfork ()) X return; /* Parent just returns */ X execlp (prog[s], prog[s], oldstate, state, h->sh->name, NULL); X fatal (prog[s]); X} X X/* X * selecthost - Select host for next changestat(). X */ Xselecthost (w, h, data) X XWidget w; XMETER *h; Xchar *data; X X{ X selected = h; X} X X/* X * changestat - Change statistic we're looking at. To clear the stripchart X * it's necessary to poke the "interval" field in the StripChartWidget X * structure, and then set "jumpScroll" to the width of the stripchart. X * jumpScroll is saved here and restored in getstatus(). X */ X#include <X11/IntrinsicP.h> X#include <X11/Xaw/StripCharP.h> Xchangestat (w, statidx, data) X XWidget w; Xint statidx; Xchar *data; X X{ X int n; X Arg args[10]; X int width; X X selected->stat = statidx; X sprintf (selected->label, "%s %s", selected->sh->name, X sd[statidx].name); X n = 0; X XtSetArg (args[n], XtNlabel, selected->label); n++; X XtSetValues (selected->mbwidget, args, n); X n = 0; X XtSetArg (args[n], XtNwidth, &width); n++; X XtSetArg (args[n], XtNjumpScroll, &selected->oldjumpscroll); n++; X XtGetValues (selected->scwidget, args, n); X n = 0; X XtSetArg (args[n], XtNjumpScroll, width); n++; X XtSetValues (selected->scwidget, args, n); X ((StripChartWidget) selected->scwidget)->strip_chart.interval = width; X} X X/* X * state - Return state of current stat. X */ Xint state (l, h) X Xint l; XMETER *h; X X{ X if (l < 0) X return (FATAL); X else if (l < warnLevel * sd[h->stat].scale) X return (OK); X else if (l < errorLevel * sd[h->stat].scale) X return (WARN); X else X return (ERROR); X} X X/* X * The following functions return the value of the specified stat, which X * is normally computed by taking the difference between the current X * value and the previous value, and dividing by the update interval in X * order to get the current rate. X */ X#define DIF(m,fld) (m->sh->st[m->sh->idx].fld - \ X m->sh->st[m->sh->idx ^ 1].fld) X Xint fcoll (h) X XMETER *h; X X{ X return (DIF (h, if_collisions) / DIF (h, curtime.tv_sec)); X} X Xint fcpu (h) X XMETER *h; X X{ X int i; X int t; X int d[CPUSTATES]; X X for (t = 0, i= 0; i < CPUSTATES; i++) X t += (d[i] = DIF (h, cp_time[i])); X return (t ? (100 * (d[CP_USER]+d[CP_NICE]+d[CP_SYS])) / t : 0); X} X Xint fierr (h) X XMETER *h; X X{ X return (DIF (h, if_ierrors) / DIF (h, curtime.tv_sec)); X} X Xint fintr (h) X XMETER *h; X X{ X return (DIF (h, v_intr) / DIF (h, curtime.tv_sec)); X} X Xint fipkt (h) X XMETER *h; X X{ X return (DIF (h, if_ipackets) / DIF (h, curtime.tv_sec)); X} X Xint fload (h) X XMETER *h; X X{ X return (h->sh->st[h->sh->idx].avenrun[0]); X} X Xint foerr (h) X XMETER *h; X X{ X return (DIF (h, if_oerrors) / DIF (h, curtime.tv_sec)); X} X Xint fopkt (h) X XMETER *h; X X{ X return (DIF (h, if_opackets) / DIF (h, curtime.tv_sec)); X} X Xint fpage (h) X XMETER *h; X X{ X return ((DIF (h, v_pgpgin) + DIF (h, v_pgpgout)) / DIF (h, curtime.tv_sec)); X} X Xint fpgpgin (h) X XMETER *h; X X{ X return (DIF (h, v_pgpgin) / DIF (h, curtime.tv_sec)); X} X Xint fpgpgout (h) X XMETER *h; X X{ X return (DIF (h, v_pgpgout) / DIF (h, curtime.tv_sec)); X} X Xint fpswpin (h) X XMETER *h; X X{ X return (DIF (h, v_pswpin) / DIF (h, curtime.tv_sec)); X} X Xint fpswpout (h) X XMETER *h; X X{ X return (DIF (h, v_pswpout) / DIF (h, curtime.tv_sec)); X} X Xint fswt (h) X XMETER *h; X X{ X return (DIF (h, v_swtch) / DIF (h, curtime.tv_sec)); X} X Xint fsys (h) X XMETER *h; X X{ X int i; X int t; X int d[CPUSTATES]; X X for (t = 0, i= 0; i < CPUSTATES; i++) X t += (d[i] = DIF (h, cp_time[i])); X return (t ? (100 * d[CP_SYS]) / t : 0); X} X Xint fuser (h) X XMETER *h; X X{ X int i; X int t; X int d[CPUSTATES]; X X for (t = 0, i= 0; i < CPUSTATES; i++) X t += (d[i] = DIF (h, cp_time[i])); X return (t ? (100 * (d[CP_USER] + d[CP_NICE])) / t : 0); X} X X/* X * getmeter - Executes rstat(3) call to read statistics for specified host. X * I do all the rpc junk myself so that I have better control over timeouts X * than rstat(3) gives me. If we're watching multiple stats X * on the same host I only do one rstat(3) call (refcnt and curcnt are X * used for this). X */ Xint getmeter (h) X Xregister METER *h; X X{ X enum clnt_stat cs; X register SHMETER *sh; X int p; X X sh = h->sh; X if (sh->curcnt >= sh->refcnt) X sh->curcnt = 0; X if (!sh->curcnt++) { X if (sh->clnt == NULL) { X if ((p = getport (h)) < 0) X return (-1); X sh->addr.sin_port = htons (p); X sh->s = RPC_ANYSOCK; X if (!(sh->clnt = clntudp_create(&sh->addr, RSTATPROG, RSTATVERS_TIME, X ptto, &sh->s))) X return (-1); X sh->first = 1; X sh->idx = 0; X } else { X sh->first = 0; X sh->idx ^= 1; X } X cs = clnt_call (sh->clnt, RSTATPROC_STATS, xdr_void, 0, xdr_statstime, X &sh->st[sh->idx], tto); X if (cs != RPC_SUCCESS) { X clnt_destroy (sh->clnt); X close (sh->s); /* Some clnt_destroy's don't do this */ X sh->clnt = NULL; X return (-1); X } X } X return (sh->first ? 0 : X sh->clnt == NULL ? -1 : (sd[h->stat].val) (h)); X} X X/* X * getport - Get port rstatd is listening on. X */ Xint getport (h) X XMETER *h; X X{ X CLIENT *c; X enum clnt_stat cs; X static struct pmap pm = {RSTATPROG, RSTATVERS_TIME, IPPROTO_UDP, 0}; X short p; X register SHMETER *sh; X X sh = h->sh; X sh->s = RPC_ANYSOCK; X sh->addr.sin_port = htons (PMAPPORT); X if (!(c = clntudp_create (&sh->addr, PMAPPROG, PMAPVERS, ptto, &sh->s))) X return (-1); X cs = clnt_call (c, PMAPPROC_GETPORT, xdr_pmap, &pm, xdr_u_short, &p, tto); X clnt_destroy (c); X close (sh->s); /* Some clnt_destroy's don't do this */ X return (cs == RPC_SUCCESS ? p : -1); X} X X/* X * initmeter - Fill in METER and SHMETER structures for this stat. X */ XMETER *initmeter (meterlist, idx, argc, argv) X XMETER *meterlist; Xint *idx; Xint argc; Xchar **argv; X X{ X register METER *h; X register SHMETER *sh; X struct hostent *he; X int i; X char *cp; X X /* X * Create and fill in METER struct. X */ X if (!(h = (METER *) malloc (sizeof (METER)))) X fatal ("METER"); X h->nxt = meterlist; X cp = (argv[*idx][0] == '-') ? &argv[*idx][1] : defstat; X for (i = 0; i < MAXSTAT; i++) X if (strcmp (cp, sd[i].name) == 0) { X h->stat = i; X break; X } X if ((cp != defstat) && (++(*idx) == argc || i >= MAXSTAT)) X usage (); X if ((he = gethostbyname (argv[*idx])) == NULL) X fatal (argv[*idx]); X if (shortname) X if (cp = index (he->h_name, '.')) X *cp = '\0'; X if (!(h->label = malloc (strlen (he->h_name) + 2 + MAXSTATNAME))) X fatal ("label"); X sprintf (h->label, "%s %s", he->h_name, sd[h->stat].name); X h->oldstate = OK; X h->oldjumpscroll = 0; X /* X * If we're already looking at this host then just point h->sh at X * existing structure and we're done. X */ X for (sh = shmeters; sh; sh = sh->nxt) X if (strcmp (sh->name, he->h_name) == 0) { X h->sh = sh; X sh->refcnt++; /* Count how many references */ X return (h); X } X /* X * Not looking at this host yet, create and fill in SHMETER struct. X */ X if (!(sh = (SHMETER *) malloc (sizeof (SHMETER)))) X fatal ("SHMETER"); X sh->nxt = shmeters; /* Save this struct in linked list */ X shmeters = sh; X h->sh = sh; X if (!(sh->name = malloc (strlen (he->h_name) + 1))) X fatal ("name"); X strcpy (sh->name, he->h_name); X bcopy (he->h_addr, &sh->addr.sin_addr, he->h_length); X sh->addr.sin_family = AF_INET; X sh->clnt = NULL; X sh->refcnt = 1; X sh->curcnt = 0; X sh->pid = -1; X return (h); X} X Xfatal (m) X Xchar *m; X X{ X perror (m); X exit (1); X} END_OF_FILE if test 33499 -ne `wc -c <'xmeter.c'`; then echo shar: \"'xmeter.c'\" unpacked with wrong size! fi # end of 'xmeter.c' fi if test -f 'xmeter.man' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xmeter.man'\" else echo shar: Extracting \"'xmeter.man'\" \(14019 characters\) sed "s/^X//" >'xmeter.man' <<'END_OF_FILE' X.TH XMETER 1 "14 August 1989" "X Version 11" X.SH NAME Xxmeter - rstat display for X X.SH SYNOPSIS X.B xmeter X[-\fItoolkitoption\fP ...] [-\fIoption\fP ...] [-\fIstat\fP] hosts ... X.SH DESCRIPTION X.I Xmeter Xdisplays a periodically updating histogram of the system statistics Xgathered by rstat(3) for the specified hosts. Meters can be Xdisplayed in a vertical, horizontal or rectangular arrangement. As Xstatistics range between 4 user defineable levels (OK, WARN, ERROR Xor FATAL), the background, foreground, highlight, border and internal Xborder colors and the background bitmap of each meter can be changed. X.LP X.I Xmeter Xuses the StripChart widget of the Athena Widget Set to graph each Xstatistic. StripCharts automatically scale the graph as the value Xvaries, by drawing a number of horizontal lines across the StripChart. XEach line represents an increment of a user settable value. For Xexample, if the statistic being graphed is number of pages paged in Xper second, and the scale is set to 10, then each horizontal line Xwould represent 10 pages per second. Each time a graph is updated, X.I xmeter Xwill examine the current value of the statistic and the current scale, Xas the number of scale lines increases above X.I wlevel Xand X.I elevel Xthe background colors and bitmaps of each graph are modified as specified. X.LP XThe statistic being graphed may be modified while X.I xmeter Xis running by moving the mouse cursor into the label part of a graph, Xclicking any mouse button, and sliding down to the desired stat. X.SH OPTIONS X.PP X.I Xmeter Xaccepts all of the standard X Toolkit command line options along with the Xfollowing additional options: X.PP X.TP 8 X.B \-cols \fIcols\fP XThis option specifies the number of columns the meters should be Xdisplayed in. If both X.I cols Xand X.I rows Xare specified, X.I cols Xtakes precedence. The default is 1 column. X.PP X.TP 8 X.B \-ebd \fIcolor\fP XSet error level border color. X.PP X.TP 8 X.B \-ebg \fIcolor\fP XSet error level background color. X.PP X.TP 8 X.B \-efg \fIcolor\fP XSet error level foreground color. X.PP X.TP 8 X.B \-ehl \fIcolor\fP XSet error level highlight color. X.PP X.TP 8 X.B \-eibd \fIcolor\fP XSet error level internal border color. X.PP X.TP 8 X.B \-elevel \fIinteger\fP XThis option specifies the level at which the background color is changed Xto ebg. The default is 6. X.PP X.TP 8 X.B \-ep \fIprogram\fP X.I program Xshould be the name of a program to be invoked when the meter enters the Xerror state. X.I program Xwill be passed 3 arguments, oldstate, newstate and the hostname being Xmonitored. Oldstate and newstate will be integers ranging from 0 to X3, corresponding to levels OK, WARN, ERROR and FATAL. X.PP X.TP 8 X.B \-fbd \fIcolor\fP XSet fatal level border color. X.PP X.TP 8 X.B \-fbg \fIcolor\fP XSet fatal level background color. X.PP X.TP 8 X.B \-ffg \fIcolor\fP XSet fatal level foreground color. X.PP X.TP 8 X.B \-fhl \fIcolor\fP XSet fatal level highlight color. X.PP X.TP 8 X.B \-fibd \fIcolor\fP XSet fatal level internal border color. X.PP X.TP 8 X.B \-fp \fIprogram\fP X.I program Xshould be the name of a program to be invoked when the monitored host is Xdown. X.I program Xwill be passed 3 arguments, oldstate, newstate and the hostname being Xmonitored. Oldstate and newstate will be integers ranging from 0 to X3, corresponding to levels OK, WARN, ERROR and FATAL. X.PP X.TP 8 X.B \-h \fIpixels\fP XThis option specifies the height of each chart X.I xmeter Xwill display. The default is 80. X.PP X.TP 8 X.B \-lebg \fIcolor\fP XSet error level background color in menubutton. X.PP X.TP 8 X.B \-lefg \fIcolor\fP XSet error level foreground color in menubutton. X.PP X.TP 8 X.B \-lfbg \fIcolor\fP XSet fatal level background color in menubutton. X.PP X.TP 8 X.B \-lffg \fIcolor\fP XSet fatal level foreground color in menubutton. X.PP X.TP 8 X.B \-lobg \fIcolor\fP XSet ok level background color in menubutton. X.PP X.TP 8 X.B \-lofg \fIcolor\fP XSet ok level foreground color in menubutton. X.PP X.TP 8 X.B \-lwbg \fIcolor\fP XSet warn level background color in menubutton. X.PP X.TP 8 X.B \-lwfg \fIcolor\fP XSet warn level foreground color in menubutton. X.PP X.TP 8 X.B \-obd \fIcolor\fP XSet ok level border color. X.PP X.TP 8 X.B \-obg \fIcolor\fP XSet ok level background color. X.PP X.TP 8 X.B \-ofg \fIcolor\fP XSet ok level foreground color. X.PP X.TP 8 X.B \-ohl \fIcolor\fP XSet ok level highlight color. X.PP X.TP 8 X.B \-oibd \fIcolor\fP XSet ok level internal border color. X.PP X.TP 8 X.B \-op \fIprogram\fP X.I program Xshould be the name of a program to be invoked when the meter enters WARN Xstate. X.I program Xwill be passed 3 arguments, oldstate, newstate and the hostname being Xmonitored. Oldstate and newstate will be integers ranging from 0 to X3, corresponding to levels OK, WARN, ERROR and FATAL. X.PP X.TP 8 X.B \-rows \fIrows\fP XThis option specifies the number of rows the meters should be Xdisplayed in. If both X.I cols Xand X.I rows Xare specified, X.I cols Xtakes precedence. The default is 1 column. X.PP X.TP 8 X.B \-rt \fIretries\fP XThis option specifies the number of times to retry failed RPC calls. XThe default is 2. X.PP X.TP 8 X.B \-scoll \fIinteger\fP XSet scale for collisions. The default is 1. X.PP X.TP 8 X.B \-scpu \fIinteger\fP XSet scale for cpu time. The default is 20. X.PP X.TP 8 X.B \-sierr \fIinteger\fP XSet scale for input errors. The default is 1. X.PP X.TP 8 X.B \-sintr \fIinteger\fP XSet scale for interrupts. The default is 50. X.PP X.TP 8 X.B \-sipkt \fIinteger\fP XSet scale for input packets. The default is 20. X.PP X.TP 8 X.B \-sload \fIinteger\fP XSet scale for load average. The default is FSCALE (see param.h). X.PP X.TP 8 X.B \-sn XIf specified strips off domain part of host name in menubuttons. X.PP X.TP 8 X.B \-soerr \fIinteger\fP XSet scale for output errors. The default is 1. X.PP X.TP 8 X.B \-sopkt \fIinteger\fP XSet scale for output packets. The default is 20. X.PP X.TP 8 X.B \-spage \fIinteger\fP XSet scale for pages paged in and out. The default is 10. X.PP X.TP 8 X.B \-spgpgin \fIinteger\fP XSet scale for pages paged in. The default is 10. X.PP X.TP 8 X.B \-spgpgout \fIinteger\fP XSet scale for pages paged out. The default is 10. X.PP X.TP 8 X.B \-spswpin \fIinteger\fP XSet scale for pages swapped in. The default is 1. X.PP X.TP 8 X.B \-spswpout \fIinteger\fP XSet scale for pages swapped out. The default is 1. X.PP X.TP 8 X.B \-sswt \fIinteger\fP XSet scale for context switches. The default is 30. X.PP X.TP 8 X.B \-ssys \fIinteger\fP XSet scale for sys time. The default is 20. X.PP X.TP 8 X.B \-suser \fIinteger\fP XSet scale for user time. The default is 20. X.PP X.TP 8 X.B \-to \fIseconds\fP XThis option specifies the timeout for RPC calls. The default is 5 seconds. X.PP X.TP 8 X.B \-update \fIseconds\fP XThis option specifies the frequency in seconds at which X.I xmeter Xupdates its display. The minimum amount of time allowed between updates Xis 5 seconds. The default is 60 seconds. X.PP X.TP 8 X.B \-v XPrint version number and exit. X.PP X.TP 8 X.B \-w \fIpixels\fP XThis option specifies the width of each chart X.I xmeter Xwill display. The default is 80. X.PP X.TP 8 X.B \-wbd \fIcolor\fP XSet warn level border color. X.PP X.TP 8 X.B \-wbg \fIcolor\fP XSet warn level background color. X.PP X.TP 8 X.B \-wfg \fIcolor\fP XSet warn level foreground color. X.PP X.TP 8 X.B \-whl \fIcolor\fP XSet warn level highlight color. X.PP X.TP 8 X.B \-wibd \fIcolor\fP XSet warn level internal border color. X.PP X.TP 8 X.B \-wlevel \fIinteger\fP XThis option specifies the level at which the background color is changed Xto wbg. The default is 3. X.PP X.TP 8 X.B \-wp \fIprogram\fP X.I program Xshould be the name of a program to be invoked when the meter enters XWARN state. X.I program Xwill be passed 3 arguments, oldstate, newstate and the hostname being Xmonitored. Oldstate and newstate will be integers ranging from 0 to X3, corresponding to levels OK, WARN, ERROR and FATAL. X.SH STATISTICS X.PP X.TP 8 X.B \-coll XGraph number of collisions per second. X.PP X.TP 8 X.B \-cpu XGraph percentage of non idle time for the specified host. X.PP X.TP 8 X.B \-ierr XGraph number of input errors per second. X.PP X.TP 8 X.B \-intr XGraph number of interrupts per second. X.PP X.TP 8 X.B \-ipkt XGraph number of input packets per second. X.PP X.TP 8 X.B \-load XGraph 1 minute load average. X.PP X.TP 8 X.B \-oerr XGraph number of output errors per second. X.PP X.TP 8 X.B \-opkt XGraph number of output packets per second. X.PP X.TP 8 X.B \-page XSum of pgpgin and pgpgout values. X.PP X.TP 8 X.B \-pgpgin XGraph number of pages paged in per second. X.PP X.TP 8 X.B \-pgpgout XGraph number of pages paged out per second. X.PP X.TP 8 X.B \-pswpin XGraph number of swapins per second. X.PP X.TP 8 X.B \-pswpout XGraph number of swapouts per second. X.PP X.TP 8 X.B \-swt XGraph number of context switches per second. X.PP X.TP 8 X.B \-sys XGraph percentage of system time for the specified host. X.PP X.TP 8 X.B \-user XGraph percentage of user time for the specified host. X.SH "WIDGET HIERARCHY" XThe widget hierarchy for X.I xmeter Xis given below. Class names are given first, followed by instance Xnames. X.sp X.nf XXMeter xmeter X Form form X SimpleMenu statmenu X SmeBSB <stat> X Paned <hostname> X MenuButton menu X StripChart load X.SH "RESOURCES" XThe following resources are defined. Resource instance names Xare specified first, followed by class name. X.PP X.TP 8 X.B columns Columns XSet number of columns of display. X.PP X.TP 8 X.B defStat DefStat XDefault statistic to graph, the default is \fBload\fP. X.PP X.TP 8 X.B errorBack Background XError level background color. X.PP X.TP 8 X.B errorBd Foreground XError level border color. X.PP X.TP 8 X.B errorBitmap Bitmap XError level background bitmap. X.PP X.TP 8 X.B errorFore Foreground XError level foreground color. X.PP X.TP 8 X.B errorHl Foreground XError level highlight color. X.PP X.TP 8 X.B errorIbd Foreground XError level internal border color. X.PP X.TP 8 X.B errorLevel ErrorLevel XWhen a statistic is above this value colors and bitmaps are Xset to the appropriate error level value. X.PP X.TP 8 X.B errorProg Program XProgram to be invoked when a meter enters error state. X.PP X.TP 8 X.B fatalBack Background XBackground color of dead hosts. X.PP X.TP 8 X.B fatalBd Foreground XBorder color of dead hosts. X.PP X.TP 8 X.B fatalBitmap Bitmap XBackground bitmap of dead hosts. X.PP X.TP 8 X.B fatalFore Foreground XForeground color of dead hosts. X.PP X.TP 8 X.B fatalHl Foreground XHighlight color of dead hosts. X.PP X.TP 8 X.B fatalIbd Foreground XInternal border color of dead hosts. X.PP X.TP 8 X.B fatalProg Program XProgram to be invoked when a meter enters fatal state. X.PP X.TP 8 X.B lErrorBack Background XError level background color of menubutton widget. X.PP X.TP 8 X.B lErrorFore Foreground XError level foreground color of menubutton widget. X.PP X.TP 8 X.B lFatalBack Background XFatal level background color of menubutton widget. X.PP X.TP 8 X.B lFatalFore Foreground XFatal level foreground color of menubutton widget. X.PP X.TP 8 X.B lOkBack Background XOk level background color of menubutton widget. X.PP X.TP 8 X.B lOkFore Foreground XOk level foreground color of menubutton widget. X.PP X.TP 8 X.B lWarnBack Background XWarn level background color of menubutton widget. X.PP X.TP 8 X.B lWarnFore Foreground XWarn level foreground color of menubutton widget. X.PP X.TP 8 X.B okBack Background XOk level background color. X.PP X.TP 8 X.B okBd Foreground XOk level border color. X.PP X.TP 8 X.B okBitmap Bitmap XOk level background bitmap. X.PP X.TP 8 X.B okFore Foreground XOk level foreground color. X.PP X.TP 8 X.B okHl Foreground XOk level highlight color. X.PP X.TP 8 X.B okIbd Foreground XOk level internal border color. X.PP X.TP 8 X.B okProg Program XProgram to be invoked when a meter enters ok state. X.PP X.TP 8 X.B retries Retries XNumber of retries for RPC calls. X.PP X.TP 8 X.B rows Rows XNumber of rows to display. X.PP X.TP 8 X.B scaleColl ScaleColl XScale for interface collisions. X.PP X.TP 8 X.B scaleCpu ScaleCpu XScale for percentage cpu usage. X.PP X.TP 8 X.B scaleIerr ScaleIerr XScale for interface input errors. X.PP X.TP 8 X.B scaleIerr ScaleIntr XScale for interface interrupts. X.PP X.TP 8 X.B scaleIpkt ScaleIpkt XScale for interface input packets. X.PP X.TP 8 X.B scaleLoad ScaleLoad XScale for load average. X.PP X.TP 8 X.B scaleOerr ScaleOerr XScale for interface output errors. X.PP X.TP 8 X.B scaleOpkt ScaleOpkt XScale for interface output packets. X.PP X.TP 8 X.B scalePage ScalePage XScale for paging (sum of pageins and pageouts). X.PP X.TP 8 X.B scalePgpgin ScalePgpgin XScale for pages paged in. X.PP X.TP 8 X.B scalePgpgout ScalePgpgout XScale for pages paged out. X.PP X.TP 8 X.B scalePswpin ScalePswpin XScale for swap ins. X.PP X.TP 8 X.B scalePswpout ScalePswpout XScale for swap outs. X.PP X.TP 8 X.B scaleSwt ScaleSwt XScale for context switches. X.PP X.TP 8 X.B scaleSys ScaleSys XScale for percentage system time. X.PP X.TP 8 X.B scaleUser ScaleUser XScale for percentage user time. X.PP X.TP 8 X.B shortName ShortName XTrim domains off host names. X.PP X.TP 8 X.B timeout Timeout XTimeout for RPC calls. X.PP X.TP 8 X.B update Interval XInterval between updates. X.PP X.TP 8 X.B warnBack Background XWarn level background color. X.PP X.TP 8 X.B warnBd Foreground XWarn level border color. X.PP X.TP 8 X.B warnBitmap Bitmap XWarn level Background bitmap. Xbelow ErrorLevel. X.PP X.TP 8 X.B warnFore Foreground XWarn level foreground color. X.PP X.TP 8 X.B warnHl Foreground XWarn level highlight color. X.PP X.TP 8 X.B warnIbd Foreground XWarn level internal border. X.PP X.TP 8 X.B warnLevel WarnLevel XWhen statistic is above this level and below ErrorLevel background colors Xand bitmaps are set to WarnBack and WarnBitmap. X.PP X.TP 8 X.B warnProg Program XProgram to be invoked when a meter enters warn state. X.SH BUGS XWhen a host doesn't respond it can sometimes take awhile for the labels Xin the menubuttons to update. X.LP XIf a height for the meters is specified but not a width, the error X"Widget has zero width and/or height" is printed by the X toolkit. XThe converse is not true. I suspect the problem is in the Paned Xwidget but xmeter could be doing something wrong. The supplied Xapplication defaults file initializes both width and height, as long Xas this is installed there shouldn't be a problem unless the user Xexplicitly sets width to 0. X.SH AUTHOR XBob Schwartzkopf, The RAND Corporation. Based on xload from MIT. END_OF_FILE if test 14019 -ne `wc -c <'xmeter.man'`; then echo shar: \"'xmeter.man'\" unpacked with wrong size! fi # end of 'xmeter.man' fi if test -f 'XMeter.ad' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'XMeter.ad'\" else echo shar: Extracting \"'XMeter.ad'\" \(80 characters\) sed "s/^X//" >'XMeter.ad' <<'END_OF_FILE' XXMeter*Paned.Width: 80 XXMeter*Paned.Height: 80 XXMeter*StripChart.Interval: 60 END_OF_FILE if test 80 -ne `wc -c <'XMeter.ad'`; then echo shar: \"'XMeter.ad'\" unpacked with wrong size! fi # end of 'XMeter.ad' fi echo shar: End of shell archive. exit 0 -- Dan Heller O'Reilly && Associates Z-Code Software Comp-sources-x: Senior Writer President comp-sources-x@uunet.uu.net argv@ora.com argv@zipcode.com