home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume3 / xnetload / part01 next >
Encoding:
Text File  |  1989-05-07  |  21.8 KB  |  706 lines

  1. Path: uunet!island!argv
  2. From: argv@island.uu.net (Dan Heller)
  3. Newsgroups: comp.sources.x
  4. Subject: v03i103:  xnetload -- multiple host xload program, Part01/01
  5. Message-ID: <744@island.uu.net>
  6. Date: 8 May 89 06:22:03 GMT
  7. Sender: news@island.uu.net
  8. Organization: Island Graphics, Marin County, California
  9. Lines: 694
  10. Approved: island!argv@sun.com
  11.  
  12. Submitted-by: Mike Berkley <jmberkley@watnext.waterloo.edu>
  13. Posting-number: Volume 3, Issue 103
  14. Archive-name: xnetload/part01
  15.  
  16. [ I compiled, but didn't run this (we don't use rwhod here).  Check the
  17.   makefile before compiling or use the imakefile.  The shar given makes
  18.   its own directory.   --argv ]
  19.  
  20. What follows was written by the author:
  21.  
  22. xnetload gives the system load for a list of remote machines by using
  23. rwhod statistics.  The load for the local machine is also displayed,
  24. but is calculated using the standard Load widget routines, (this means
  25. that xnetload needs to be setgid kmem.)
  26.  
  27. xnetload was written mostly as a tool to learning how to use the
  28. toolkit.  I was amazed at what the toolkit can do in not very many
  29. lines of code.
  30.  
  31. Don't forget to read the man page (there's a caveat about
  32. "*Load*update").  Send comments, bug reports, etc.  to
  33. jmberkley@watnext.waterloo.edu.
  34.  
  35. ---------------------------------------------------------------------------
  36. # This is a shell archive.  Remove anything before this line,
  37. # then unpack it by saving it in a file and typing "sh file".
  38. #
  39. # Wrapped by watnext!jmberkley on Tue May  2 10:56:54 EDT 1989
  40. # Contents:  xnetload/ xnetload/README xnetload/Imakefile xnetload/xnetload.c
  41. #    xnetload/xnetload.1 xnetload/Makefile xnetload/AUTHOR
  42. #    xnetload/patchlevel.h
  43.  
  44. echo mkdir - xnetload
  45. mkdir xnetload
  46. chmod u=rwx,g=rx,o=rx xnetload
  47.  
  48. echo x - xnetload/README
  49. sed 's/^@//' > "xnetload/README" <<'@//E*O*F xnetload/README//'
  50. README for xnetload
  51. Mike Berkley, April 1989
  52.  
  53. xnetload gives the system load for a list of remote machines by using
  54. rwhod statistics.  The load for the local machine is also displayed,
  55. but is calculated using the standard Load widget routines, (this means
  56. that xnetload needs to be setgid kmem.)
  57.  
  58. There's an option to turn off the local load, -nolocal, which would
  59. allow you to run with xnetload non-setgid.  Alternatively, you can
  60. compile xnetload with -DNOLOCAL (see the Imakefile and Makefile).
  61.  
  62. xnetload was developed on a uVax running Ultrix.  It also compiles and
  63. runs on Suns (both SunOS 3.5 and 4) and Sequents running Dynix.  Of
  64. course, there are some little glitches: the Makefile needs to be
  65. altered and you may need to find a memcpy() somewhere.
  66.  
  67. xnetload was written mostly as a tool to learning how to use the
  68. toolkit.  I was amazed at what the toolkit can do in not very many
  69. lines of code.
  70.  
  71. Since this was an experiment/learning tool, I'm sure that I did not
  72. follow all of the correct X guidelines.
  73.  
  74. The getload() routine is just my own kludge to read rwhod stats.  It
  75. works, but it is replaceable.  Ideally, I would like to use some kind
  76. of system call like Sun 4's RPC versions of rwho and rup command, then
  77. there would not be any dependency on rwhod.  If you are living on a
  78. system that does not use rwhod, or you would like a more efficient way
  79. of determining system load, then you can replace getload() without
  80. breaking the rest of the program.
  81.  
  82. ** Note - if you define "*Load*update", but not  **
  83. ** "xnetload*remote*update", then xnetload will  **
  84. ** set both the remote and local update times to **
  85. ** the "*Load*update" value.  If this time is    **
  86. ** much less than the rwhod update period, then  **
  87. ** the remote load displays will look more like  **
  88. ** bar graphs.                                   **
  89.  
  90. Send comments, bug reports, etc. to jmberkley@watnext.waterloo.edu.
  91.  
  92.  
  93. ******************************************
  94. * Mike Berkley, University of Waterloo   *
  95. * PAMI Lab                               *
  96. * jmberkley@watnext.waterloo.edu         *
  97. * {utai,uunet}!watmath!watnext!jmberkley *
  98. ******************************************
  99. @//E*O*F xnetload/README//
  100. chmod u=rw,g=r,o=r xnetload/README
  101.  
  102. echo x - xnetload/Imakefile
  103. sed 's/^@//' > "xnetload/Imakefile" <<'@//E*O*F xnetload/Imakefile//'
  104. #
  105. # Imakefile for xnetload
  106. #
  107. # Written by: Mike Berkley, jmberkley@watnext.waterloo.edu, 1989
  108. #
  109. # Permission to use, copy, modify and distribute (without charge) this
  110. # software and its documentation is granted, provided that this comment
  111. # is retained.
  112.  
  113. #
  114. # Since xnetload finds the local machine's load using the standard Load
  115. # widget stuff, it needs to be able to read kmem, i.e.  setgid kmem.  If
  116. # you do not want this, then define NOLOCAL
  117. #        DEFINES = -O -DNOLOCAL
  118.  
  119.        INCLUDES = -I$(TOP) -I$(TOP)/X11
  120.  
  121. # Dynix doesn't have -L option on load, but I have left changing the
  122. # XLIB specification up to individual sites.  Dynix and our Sun 3.5
  123. # don't come with a memcpy, so you'll have to add in whichever library
  124. # has memcpy.
  125. /* LOCAL_LIBRARIES = $(XAWLIB) $(XMULIB) $(XTOOLLIB) $(XLIB) */
  126. LOCAL_LIBRARIES = -L/usr/software/X11/lib -lXaw -lXmu -lXt -lX11
  127.  
  128.            SRCS = xnetload.c status.c
  129.  
  130.    INSTALLFLAGS = $(INSTKMEMFLAGS)
  131.  
  132. all: xnetload
  133.  
  134. SingleProgramTarget(xnetload,xnetload.o,,$(LOCAL_LIBRARIES))
  135. @//E*O*F xnetload/Imakefile//
  136. chmod u=rw,g=r,o=r xnetload/Imakefile
  137.  
  138. echo x - xnetload/xnetload.c
  139. sed 's/^@//' > "xnetload/xnetload.c" <<'@//E*O*F xnetload/xnetload.c//'
  140. /* 
  141.  * xnetload.c: multiple xload, using rwho statistics
  142.  *
  143.  * Written by: Mike Berkley, jmberkley@watnext.waterloo.edu, 1989
  144.  *
  145.  * Permission to use, copy, modify and distribute (without charge) this
  146.  * software and its documentation is granted, provided that this comment
  147.  * is retained.
  148.  *
  149.  * The X Window system is a copyright of the Massachusetts
  150.  * Institute of Technology
  151.  *
  152.  */
  153.  
  154. /*
  155.  * xnetload uses the Load widget load proc to get the local
  156.  * machine load.  This means that xnetload needs to be setgid
  157.  * kmem.  If you do not want this, then define NOLOCAL when compiling.
  158.  */
  159.  
  160. #include <stdio.h>
  161. #include <ctype.h>
  162. #include <netdb.h>
  163. #include <X11/Xos.h>
  164. #include <X11/Xlib.h>
  165. #include <X11/IntrinsicP.h>
  166. #include <X11/LoadP.h>
  167. #include <X11/StringDefs.h>
  168. #include <X11/Shell.h>
  169. #include <X11/Form.h>
  170. #include "patchlevel.h"
  171.  
  172.  
  173. extern void GetStatus();         /* gets rwho load */
  174. extern char *XtMalloc();
  175. extern time_t time();
  176. static Widget Toplevel, Formwin, Statuswin;
  177.  
  178. #define DEFREMUPDATE 60          /* remote update defaults to 60 seconds */
  179. #define DOWNTIME     (DEFREMUPDATE * 5)
  180. #define DOWNMSG      " DOWN"
  181. #define RWHODHD      "/usr/spool/rwho/whod"
  182.  
  183. /* arguments to Form widget */
  184. static Arg Formargs[] = {
  185.     { XtNfromVert, (XtArgVal) NULL },       /* Chain vert from value widget */
  186.     { XtNdefaultDistance, (XtArgVal) 1 },   /* default spacing */
  187.     { XtNresizable, (XtArgVal) TRUE },      /* allow resize */
  188. };
  189.  
  190. /* Arguments to load windows */
  191. static Arg Statusargs[] = {
  192.     { XtNfromVert, (XtArgVal) NULL },       /* Chain vert from .value wid */
  193.     { XtNresizable, (XtArgVal) TRUE },      /* allow resize */
  194.     { XtNlabel, (XtArgVal) NULL },          /* Load title */
  195.     { XtNborderWidth, (XtArgVal) 0 },       /* width for each load wid  */
  196. };
  197.  
  198. /* Application specific resources - turn off local load display */
  199. static Boolean Localload;
  200. static XtResource app_resources[] = {
  201.     { "localload", "LocalLoad", XtRBoolean, sizeof(Boolean),
  202.         (Cardinal) &Localload, XtRString,
  203. /* if NOLOCAL is defined, then no local is displayed, by default */
  204. #ifdef NOLOCAL
  205. "off"
  206. #else
  207. "on"
  208. #endif
  209. },
  210. };
  211.  
  212. /* command line options for local load display */
  213. /* If compiled NOLOCAL, then off is default, but on still allowed */
  214. static XrmOptionDescRec app_options[] = {
  215. #ifdef NOLOCAL
  216.     { "-local", "localload", XrmoptionNoArg, "on" },
  217. #else
  218.     { "-nolocal", "localload", XrmoptionNoArg, "off" },
  219. #endif
  220. };
  221.  
  222. /* resources specific to the remote load displays */
  223. /*
  224.  * You're wondering why I'm doing this, right?  Well, the default update
  225.  * for the Load widget is 5 seconds (I think), but if rwhod updates the
  226.  * files every 60 seconds, then the load displays will look weird.  So, I
  227.  * don't force the user to have a 60 second update, but I at least make
  228.  * this the default.
  229.  */
  230. static int Remupdate = DEFREMUPDATE;
  231. static XtResource rem_resources[] = {
  232.     { XtNupdate, XtCInterval, XtRInt, sizeof(int),
  233.         (Cardinal) &Remupdate, XtRInt, (caddr_t) &Remupdate },
  234. };
  235.  
  236. /* GetStatus() global vars */
  237. static char *Label;
  238. static Arg Labelarg;
  239.  
  240. /* getload includes */
  241. /* Dynix doesn't have an rwhod.h file, so here's the struct for that system */
  242. #ifdef sequent
  243. struct  outmp {
  244.     char  out_line[8];    /* tty name */
  245.     char  out_name[8];    /* user id */
  246.     long  out_time;       /* time on */
  247. };
  248. struct  whod {
  249.     char  wd_vers;
  250.     char  wd_type;
  251.     char  wd_fill[2];
  252.     int   wd_sendtime;
  253.     int   wd_recvtime;
  254.     char  wd_hostname[32];
  255.     int   wd_loadav[3];
  256.     int   wd_boottime;
  257.     struct whoent {
  258.         struct outmp    we_utmp;
  259.         int             we_idle;
  260.     } wd_we[1024 / sizeof (struct whoent)];
  261. };
  262. #else
  263. #include <protocols/rwhod.h>
  264. #endif
  265.  
  266. main(argc,argv)
  267. int argc;
  268. char *argv[];
  269. {
  270.     int currarg = 1;             /* arg counter to walk through hosts */
  271.     char
  272.       *hostname,                 /* raw host name */
  273.       *labelname;                /* label, could be "machine DOWN" */
  274.     struct hostent *host;        /* for gethostbyname() */
  275.  
  276.     /* The toolkit tries to open your display if you use -help */
  277.     /* so let's do it the other way */
  278.     if((argc > 1) && !strncmp(argv[1],"-h",2)) {
  279.         usage();
  280.         exit(1);
  281.     }
  282.  
  283.     /* Initialize the top level */
  284.     Toplevel = XtInitialize(*argv[0], "XNetload",
  285.                             app_options, XtNumber(app_options), &argc, argv);
  286.     /* Get local vs nolocal */
  287.     XtGetApplicationResources( (Widget)Toplevel, (caddr_t)NULL,
  288.                               app_resources, XtNumber(app_resources),
  289.                               NULL, (Cardinal) 0);
  290.       
  291.     /* Create a Form widget to contain all of the Loads */
  292.     Formwin =
  293.       XtCreateManagedWidget("shell",
  294.                             formWidgetClass,
  295.                             Toplevel,
  296.                             Formargs,
  297.                             XtNumber(Formargs));
  298.  
  299. /*
  300.  * Load widget reads kmem for local load.  Define NOLOCAL if you
  301.  * don't want this.
  302.  */
  303.     if(Localload) {
  304.         /* Get and set label name */
  305.         labelname = XtMalloc(BUFSIZ*sizeof(char));
  306.         gethostname(labelname,BUFSIZ);
  307.         XtSetArg(Statusargs[XtNumber(Statusargs)-1],
  308.                  XtNlabel,(XtArgVal)labelname);
  309.  
  310.         /* Create the local load widget */
  311.         Statuswin = XtCreateManagedWidget("local",
  312.                                           loadWidgetClass,
  313.                                           Formwin,
  314.                                           Statusargs,
  315.                                           XtNumber(Statusargs));
  316.     }
  317.  
  318.     /* Remote Loads */
  319.     /* currarg initialized above */
  320.     for(;currarg < argc;currarg++) {
  321.         /* translate command arg to a hostname */
  322.         host = gethostbyname(argv[currarg]);
  323.         /* if host == NULL, then hostname is junk for some reason */
  324.         if(host) {
  325.             /* allocate memory for hostname */
  326.             if(!(hostname=XtMalloc((strlen(host->h_name)+1)*sizeof(char)))) {
  327.                 perror("xnetload: Ran out of memory for name");
  328.                 exit(1);
  329.             }
  330.             /* allocate memory for name and downmsg for label */
  331.             if(!(labelname=XtMalloc((strlen(host->h_name)
  332.                                           +strlen(DOWNMSG)+1)*sizeof(char))
  333.                       )) {
  334.                 perror("xnetload: Ran out of memory for labelname");
  335.                 exit(1);
  336.             }
  337.             /* set up chain to previous Load widget */
  338.             XtSetArg(Statusargs[0],XtNfromVert, (XtArgVal)Statuswin);
  339.  
  340.             /* set label name */
  341.             strcpy(labelname,host->h_name);
  342.             XtSetArg(Statusargs[XtNumber(Statusargs)-1],
  343.                      XtNlabel,(XtArgVal)labelname);
  344.  
  345.             /* create the remote load widget, taking into account */
  346.             /* modified label and vertical chaining */
  347.             Statuswin = XtCreateManagedWidget("remote",
  348.                                               loadWidgetClass,
  349.                                               Formwin,
  350.                                               Statusargs,
  351.                                               XtNumber(Statusargs));
  352.  
  353.             /* This makes sure of 60 second default, without forcing! */
  354.             XtGetApplicationResources( (Widget)Statuswin, (caddr_t)NULL,
  355.                                       rem_resources, XtNumber(rem_resources),
  356.                                       NULL, (Cardinal) 0);
  357.  
  358.             /* Set up hostname, and load callback (GetStatus()) */
  359.             strcpy(hostname,host->h_name);
  360.             XtRemoveAllCallbacks(Statuswin, XtNgetLoadProc);
  361.             XtAddCallback(Statuswin,XtNgetLoadProc,
  362.                           GetStatus,(caddr_t)hostname);
  363.         }
  364.     }
  365.  
  366.     /* if there are no loads to display, then should stop   */
  367.     /* Note, Statuswin is static, guaranteed to start at 0, */
  368.     /* so it's non-zero only if a load widget was created   */
  369.     if(!Statuswin) {
  370.         fprintf(stderr,"xnetload: No machines to display\n");
  371.         usage();
  372.         exit(0);
  373.     }
  374.  
  375.     /* draw the widgets, and look for new events */
  376.     XtRealizeWidget(Toplevel);
  377.     XtMainLoop();
  378. }
  379.  
  380. /*
  381.  * Load callback function
  382.  *
  383.  */
  384. void
  385. GetStatus(w,closure,call_data)
  386. Widget w;                        /* load widget */
  387. caddr_t closure;                 /* name of host, char*  */
  388. caddr_t call_data;               /* load, float*  */
  389. {
  390.     int load;                    /* current load for this machine */
  391.     char fname[BUFSIZ];          /* name of rwhod file */
  392.  
  393.     /* get current label for widget */
  394.     XtSetArg(Labelarg,XtNlabel,(XtArgVal)&Label);
  395.     XtGetValues(w,&Labelarg,(Cardinal)1);
  396.  
  397.     sprintf(fname,"%s.%s",RWHODHD,(char *)closure);
  398.  
  399.     /* if load is less than zero, then machine is down or something */
  400.     if((load = getload(fname)) < 0) {
  401.         *(double *)call_data = 0.0;
  402.         /* update label with DOWN message */
  403.         if(!matchstr(Label,DOWNMSG))
  404.           updatelabel(w,(char *)closure,DOWNMSG);
  405.     }
  406.     /* otherwise we found a good load, so use it */
  407.     else {
  408.         *(double *)call_data = (double)load/100.0;
  409.         /* hate to do this everytime, but we have to check */
  410.         if(matchstr(Label,DOWNMSG))
  411.           updatelabel(w,(char *)closure,"");
  412.         return;
  413.     }
  414. }
  415.  
  416. /*
  417.  * look for pat in str - exact match, no wild cards here
  418.  */
  419. static int
  420. matchstr(str,pat)
  421. register char *str, *pat;
  422. {
  423.     while(str = index(str,*pat))
  424.       if(! strcmp(str++,pat))
  425.         return(TRUE);
  426.     return(FALSE);
  427. }
  428.  
  429. /*
  430.  * replace label with str and msg
  431.  */
  432. static int
  433. updatelabel(w,str,msg)
  434. Widget w;
  435. register char *str, *msg;
  436. {
  437.     XEvent Sendevent;
  438.  
  439.     sprintf(Label,"%s%s",str,msg);
  440.     XtSetArg(Labelarg,XtNlabel, (XtArgVal)Label);
  441.     XtSetValues(w,&Labelarg, (Cardinal)1);
  442.  
  443.     /* Load widget doesn't redraw when label is changed.  Force it! */
  444.     Sendevent.xexpose.x = 0;
  445.     Sendevent.xexpose.width = ((LoadWidget)w)->core.width;
  446.     XClearWindow(XtDisplay(w),XtWindow(w));
  447.     (*((LoadWidgetClass)&loadClassRec)->core_class.expose)
  448.       (w, &Sendevent, (Region) NULL);
  449. }
  450.  
  451. #define ISDOWN(now,wd) (((now) - (wd).wd_recvtime) > DOWNTIME)
  452. /*
  453.  * actual function to get the load
  454.  * reads rwhod stats to find the load average of a machine
  455.  */
  456. static int
  457. getload(fname)
  458. char *fname;
  459. {
  460.     int nbytes;      /* number of bytes read */
  461.     int fd;          /* file descriptor */
  462.     int counter;                 /* loop counter */
  463.     time_t currtime;             /* current time */
  464.     struct whod    wd;
  465.     char buf[sizeof(struct whod)];
  466.  
  467.     (void) time(&currtime);
  468.  
  469.     /* Loop 3 times, looking for a non-zero load. */
  470.     /* This keeps us from getting a zero load if rwhod is in */
  471.     /* the process of doing something to the file.  This is */
  472.     /* important, since we'll get strange looking zero gaps */
  473.     /* in the graph if we don't try our best to get a non-zero load. */
  474.     for(counter=0;counter<=3;counter++) {
  475.         /* open and read from the file */
  476.         if((fd = open(fname, O_RDONLY, 0)) < 0)
  477.           /* we can't open file, so it's down or something */
  478.           return(-1);
  479.  
  480.         nbytes = read(fd, buf, sizeof(struct whod));
  481.         close(fd);
  482.         /* if we got enough bytes, then copy it to wd */
  483.         if(nbytes >= (sizeof (wd) - sizeof(wd.wd_we))) {
  484.  
  485.             /* NOT everbody has memcpy, but can't use strncpy() */
  486.             memcpy(&wd,buf,(sizeof (wd) - sizeof(wd.wd_we)));
  487.  
  488.             /* ISDOWN macro, if machine is really down or faking */
  489.             if(ISDOWN(currtime,wd))
  490.               return(-1);
  491.             else if(wd.wd_loadav[0] > 0)
  492.               return(wd.wd_loadav[0]);
  493.         }
  494.  
  495.         /* If we got to here, then we need to loop again */
  496.         sleep(1);
  497.     }
  498. }
  499.  
  500. static int
  501. usage()
  502. {
  503.     fprintf(stderr,"usage:\n xnetload [-nolocal] [machine] ...\n");
  504. }
  505. @//E*O*F xnetload/xnetload.c//
  506. chmod u=rw,g=r,o=r xnetload/xnetload.c
  507.  
  508. echo x - xnetload/xnetload.1
  509. sed 's/^@//' > "xnetload/xnetload.1" <<'@//E*O*F xnetload/xnetload.1//'
  510. @.TH XNETLOAD l "April 1989" "X Version 11"
  511. @.SH NAME
  512. xnetload - display load averages from local network machines
  513. @.SH SYNOPSIS
  514. @.B xnetload
  515. [-\fInolocal\fP] [\fImachine\fP] ...
  516. @.SH DESCRIPTION
  517. @.I xnetload 
  518. uses the Athena Load widget and
  519. @.B rwhod
  520. statistics to display the
  521. load average of a number of machines on a local network.
  522. @.SH OPTIONS
  523. @.PP
  524. @.I xnetload
  525. accepts all of the standard X Toolkit command line options along with the 
  526. following additional options:
  527. @.PP
  528. @.TP 8
  529. @.B \-nolocal
  530. By default, the load for the local machine is displayed and the
  531. load calculated using the
  532. Load widget's standard LoadProc.  With this option,
  533. @.I xnetload
  534. will NOT display
  535. the local machine's load unless the hostname is listed
  536. on the command line.  When
  537. @.B \-nolocal
  538. is used,
  539. @.I xnetload
  540. will not try to read
  541. @.I kmem.
  542. @.PP
  543. @.TP 8
  544. @.B \-local
  545. If
  546. @.I xnetload
  547. is compiled with
  548. @.B \-DNOLOCAL,
  549. then no local load will
  550. be displayed by default.
  551. @.B \-local
  552. will turn the local load back on, and make
  553. @.I xnetload
  554. read
  555. @.I kmem.
  556. @.PP
  557. @.TP 8
  558. @.B [machine] ...
  559. The load for each machine listed will be displayed.
  560. @.SH RESOURCES
  561. @.I xnetload
  562. uses the standard toolkit resources.  These are some of the ones that
  563. I find useful:
  564. @.br
  565. @.sp
  566. !**** XLOAD ****
  567. @.br
  568. *Load*font:                          6x10
  569. @.br
  570. *Load*height:                        35
  571. @.br
  572. *Load*width:                         90
  573. @.br
  574. !**** XMULTIMETER ****
  575. @.br
  576. xnetload.geometry:                   -0+0
  577. @.br
  578. ! Display the local machine load by reading kmem
  579. @.br
  580. xnetload.localload:                  on
  581. @.br
  582. ! number of seconds between updates for local machine
  583. @.br
  584. xnetload*local*update:               15
  585. @.br
  586. ! number of seconds between updates for remote machines
  587. @.br
  588. xnetload*remote*update:              40
  589. @.sp
  590. @.PP
  591. Note - if you define "*Load*update", but not "xnetload*remote*update",
  592. then
  593. @.I xnetload
  594. will set both the remote and local update times to the "*Load*update"
  595. value.  If this time is much less than the
  596. @.B rwhod
  597. update period, then the remote load displays will look more like bar graphs.
  598. @.SH SEE ALSO
  599. X(1), xload(1), Athena Load widget
  600. @.SH BUGS
  601. @.I xnetload
  602. uses the Load widget's normal load function for the local
  603. system, therefore
  604. @.I xnetload
  605. should be setgid
  606. @.I kmem.
  607. If
  608. @.I xnetload
  609. cannot be setgid
  610. @.I kmem,
  611. then either compile with
  612. @.B \-DNOLOCAL
  613. or use the
  614. @.B \-nolocal
  615. option.
  616. @.PP
  617. @.I xnetload
  618. will also take a width and height on the application
  619. geometry specification, but sometimes the
  620. @.I Form
  621. widget will leave small gaps between the loads.
  622. @.PP
  623. A very wide
  624. @.I xnetload
  625. will often have wide margins.  I think the
  626. @.I Form
  627. widget is doing this.
  628. @.SH AUTHOR
  629. J. Michael Berkley
  630. (jmberkley@watnext.waterloo.edu)
  631. @//E*O*F xnetload/xnetload.1//
  632. chmod u=rw,g=r,o=r xnetload/xnetload.1
  633.  
  634. echo x - xnetload/Makefile
  635. sed 's/^@//' > "xnetload/Makefile" <<'@//E*O*F xnetload/Makefile//'
  636. #
  637. # Makefile for xnetload
  638. #
  639. # Written by: Mike Berkley, jmberkley@watnext.waterloo.edu, 1989
  640. #
  641. # Permission to use, copy, modify and distribute (without charge) this
  642. # software and its documentation is granted, provided that this comment
  643. # is retained.
  644. #
  645.  
  646. # Since xnetload finds the local machine's load using the standard Load
  647. # widget stuff, it needs to be able to read kmem, i.e.  setgid kmem.  If
  648. # you do not want this, then define NOLOCAL
  649. # CFLAGS = -O -DNOLOCAL
  650. CFLAGS = -O
  651.  
  652. XINC = /usr/software/X11/include
  653. XLIB = /usr/software/X11/lib
  654.  
  655. # Dynix doesn't have -L option on load, but I have left changing the
  656. # XLIB specification up to individual sites.  Dynix and our Sun 3.5
  657. # don't come with a memcpy, so you'll have to add in whichever library
  658. # has memcpy.
  659.  
  660. INCLUDES = -I$(XINC)
  661. LIBS = -L$(XLIB) -lXaw -lXmu -lXt -lX11
  662.  
  663. xnetload: xnetload.o
  664.     $(CC) $(CFLAGS) -o xnetload xnetload.o $(LIBS)
  665.  
  666. @.c.o:
  667.     $(CC) $(CFLAGS) -c $(INCLUDES) $<
  668. @//E*O*F xnetload/Makefile//
  669. chmod u=rw,g=r,o=r xnetload/Makefile
  670.  
  671. echo x - xnetload/AUTHOR
  672. sed 's/^@//' > "xnetload/AUTHOR" <<'@//E*O*F xnetload/AUTHOR//'
  673. xnetload was written by Mike Berkley, jmberkley@watnext.waterloo.edu
  674.  
  675. Permission to use, copy, modify and distribute (without charge) this
  676. software and its documentation is granted, provided that this comment
  677. is retained.
  678. @//E*O*F xnetload/AUTHOR//
  679. chmod u=rw,g=r,o=r xnetload/AUTHOR
  680.  
  681. echo x - xnetload/patchlevel.h
  682. sed 's/^@//' > "xnetload/patchlevel.h" <<'@//E*O*F xnetload/patchlevel.h//'
  683. #define PATCHLEVEL 0
  684. @//E*O*F xnetload/patchlevel.h//
  685. chmod u=rw,g=r,o=r xnetload/patchlevel.h
  686.  
  687. echo Inspecting for damage in transit...
  688. temp=/tmp/shar$$; dtemp=/tmp/.shar$$
  689. trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
  690. cat > $temp <<\!!!
  691.       49     345    2160 README
  692.       31     153    1023 Imakefile
  693.      365    1371   11622 xnetload.c
  694.      121     421    2644 xnetload.1
  695.       32     157     941 Makefile
  696.        5      29     222 AUTHOR
  697.        1       3      21 patchlevel.h
  698.      604    2479   18633 total
  699. !!!
  700. wc  xnetload/README xnetload/Imakefile xnetload/xnetload.c xnetload/xnetload.1 xnetload/Makefile xnetload/AUTHOR xnetload/patchlevel.h | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
  701. if [ -s $dtemp ]
  702. then echo "Ouch [diff of wc output]:" ; cat $dtemp
  703. else echo "No problems found."
  704. fi
  705. exit 0
  706.