home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume21 / xsystats / part01 < prev    next >
Encoding:
Text File  |  1993-11-23  |  57.6 KB  |  1,752 lines

  1. Newsgroups: comp.sources.x
  2. From: master@rahul.net (Mark Wedel)
  3. Subject: v21i045:  xsysstats2 - A partial perfmeter clone, Part01/01
  4. Message-ID: <1993Nov23.163325.15246@sparky.sterling.com>
  5. X-Md4-Signature: b76d93a690e1cf67fce03700611330e6
  6. Sender: chris@sparky.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Tue, 23 Nov 1993 16:33:25 GMT
  9. Approved: chris@sterling.com
  10.  
  11. Submitted-by: master@rahul.net (Mark Wedel)
  12. Posting-number: Volume 21, Issue 45
  13. Archive-name: xsysstats2/part01
  14. Environment: X11, ANSI
  15. Supersedes: xsysstats: Volume 21, Issue 11
  16.  
  17.  
  18. XSysStats is a system information display tool similar to perfmeter.  It
  19. displays its information in the form of a strip chart.  It can also display
  20. information about remote hosts, as perfmeter can do.
  21.  
  22. XSysStats can display any number of graphs at one time in the same window.
  23. Information being displayed in the window need not be all of the same host.
  24. For example, you could have it display the percentage of cpu being utilized
  25. of half a dozen (or more) different hosts.
  26.  
  27. As of this writing, the only system this has been tested on is a Sun 3/60
  28. running SunOs 4.1.1 and X11R5.  It should run on most any sun with SunOs
  29. 4.1.1.  For other systems, some porting may be required for it to work.
  30. XSysStats use the 'rstat' function to get information.  This probably
  31. does not exist on all machines, and the structure it uses may vary
  32. between different machines.  See the PORTING file for more information
  33. on how to port to different systems.
  34.  
  35. XSysStats require an ANSI capable compiler.  Gcc works fine, and
  36. Sun's acc also work (but may result in warnings at compile time.)
  37.  
  38.  
  39. #! /bin/sh
  40. # This is a shell archive.  Remove anything before this line, then unpack
  41. # it by saving it into a file and typing "sh file".  To overwrite existing
  42. # files, type "sh file -c".  You can also feed this as standard input via
  43. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  44. # will see the following message at the end:
  45. #        "End of shell archive."
  46. # Contents:  CHANGES Imakefile Makefile.noIm PORTING README TODO
  47. #   headers.h patchlevel.h porting.c xsysstats.c xsysstats.h
  48. #   xsysstats.man
  49. # Wrapped by master@sleipner on Wed Oct 27 17:50:55 1993
  50. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  51. if test -f 'CHANGES' -a "${1}" != "-c" ; then 
  52.   echo shar: Will not clobber existing file \"'CHANGES'\"
  53. else
  54. echo shar: Extracting \"'CHANGES'\" \(1817 characters\)
  55. sed "s/^X//" >'CHANGES' <<'END_OF_FILE'
  56. XChanges from 1.10 to 1.11
  57. X    Now handles MappingNotify events.
  58. X    -geometry flag now works properly with negative X or Y positions
  59. X    and non default sized window.
  60. X
  61. X
  62. XChanges from 1.01 to 1.10
  63. X    All malloc calls are now cast to prevent warnings with acc.
  64. X    Width and Height parametes to XParseGeometry now cast to prevent
  65. X    warnings with acc.
  66. X    Scale is now displayed properly when displaying load.  Before, the
  67. X    graph was accurate, but the scale was high. (Thanks for patch
  68. X    from Gvran Larsson (hoh@lorelei.approve.se)
  69. X    Changed code to handle the possibility interrupt total being less than
  70. X    the previously reported value.  Previously, when this happened,
  71. X    XSysStats got into an infinite loop.
  72. X    XCOMM line removed from Imakefile
  73. X    Window type now requests a backing store.  This fixes a display problem
  74. X    if the right side of the window is obscured.
  75. X    -allnames arguement added to force display of all host names, including
  76. X    the local host.
  77. X    -same_scale arguement added to force graphs of the same type to be
  78. X    displayed with the same scale.
  79. X    graph type load has been renamed to load1.  Graph type load5 and load15
  80. X    have been added.  load1 corresponds to load average for last minute,
  81. X    load5 for last 5 minutes, and load15 for last 15 minutes.
  82. X    -hidelabels option added to prevent labels with scale from being
  83. X    drawn at bottom of screen.  Label display can also be toggled
  84. X    by pressing 'l' in the XSysStats window.
  85. X    fixed minor bug that would cause double thick lines to be drawn at
  86. X    times when a graph changed scale.
  87. X    fixed bug in which all the graph labels were not displayed.  The
  88. X    size of the window determined if things were displayed properly
  89. X    or not.
  90. X    -scale arguement added to draw dotted horizontal lines.  Can make
  91. X    it easier to tell when a graph goes beyond a certain value.
  92. END_OF_FILE
  93. if test 1817 -ne `wc -c <'CHANGES'`; then
  94.     echo shar: \"'CHANGES'\" unpacked with wrong size!
  95. fi
  96. # end of 'CHANGES'
  97. fi
  98. if test -f 'Imakefile' -a "${1}" != "-c" ; then 
  99.   echo shar: Will not clobber existing file \"'Imakefile'\"
  100. else
  101. echo shar: Extracting \"'Imakefile'\" \(697 characters\)
  102. sed "s/^X//" >'Imakefile' <<'END_OF_FILE'
  103. X/* Change BINDIR and MANDIR (uncomment them first) if you want to install
  104. X * XSysStats other than the standard BINDIR and MANDIR, as defined by
  105. X * X11, on your system.
  106. X */
  107. X
  108. X/* XSysStats require an ansi capable compiler.  Change and uncomment CFLAGS and
  109. X * CC below to override default values used to compile X programs on your
  110. X * system as required.
  111. X */
  112. X
  113. X/*
  114. XCFLAGS = -g
  115. XCC = gcc -Wall
  116. X*/
  117. X
  118. X        DEPLIBS = $(DEPXLIB)
  119. XLOCAL_LIBRARIES = $(XLIB)
  120. X           SRCS = porting.c xsysstats.c
  121. X           OBJS = porting.o xsysstats.o
  122. X
  123. XAllTarget(xsysstats)
  124. XNormalProgramTarget(xsysstats,$(OBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),-lrpcsvc)
  125. XInstallProgram(xsysstats,$(BINDIR))
  126. XInstallManPage(xsysstats, $(MANDIR))
  127. END_OF_FILE
  128. if test 697 -ne `wc -c <'Imakefile'`; then
  129.     echo shar: \"'Imakefile'\" unpacked with wrong size!
  130. fi
  131. # end of 'Imakefile'
  132. fi
  133. if test -f 'Makefile.noIm' -a "${1}" != "-c" ; then 
  134.   echo shar: Will not clobber existing file \"'Makefile.noIm'\"
  135. else
  136. echo shar: Extracting \"'Makefile.noIm'\" \(631 characters\)
  137. sed "s/^X//" >'Makefile.noIm' <<'END_OF_FILE'
  138. XCC = gcc
  139. XCFLAGS = -g -O -Wall
  140. XLDFLAGS = 
  141. X
  142. XSRCS = xsysstats.c porting.c
  143. XOBJS = xsysstats.o porting.o
  144. XHDRS = xsysstats.h
  145. X
  146. XLIBS = -lX11 -lrpcsvc
  147. X
  148. X# program to install with.  cp would probably work
  149. XINSTALL = install
  150. X
  151. X#where to install the program
  152. XBINDIR = /usr/bin/X11
  153. X
  154. X#where to put the man page, and its extension
  155. XMANDIR = /usr/local/man/man1
  156. XMANEXT = 1
  157. X
  158. Xxsysstats: ${HDRS} ${OBJS} ${SRCS}
  159. X    $(CC) $(CFLAGS) $(LDFLAGS) ${OBJS} -o xsysstats ${LIBS} 
  160. X
  161. Xinstall:
  162. X    $(INSTALL) xsysstats ${BINDIR}/xsysstats
  163. X    $(INSTALL) xsysstats.man ${MANDIR}/xsysstats.${MANEXT}
  164. X
  165. Xdepend:
  166. X    makedepend -- $(SRCS) -- $(HDRS)
  167. X
  168. Xclean:
  169. X    rm -f *.o core xsysstats
  170. END_OF_FILE
  171. if test 631 -ne `wc -c <'Makefile.noIm'`; then
  172.     echo shar: \"'Makefile.noIm'\" unpacked with wrong size!
  173. fi
  174. # end of 'Makefile.noIm'
  175. fi
  176. if test -f 'PORTING' -a "${1}" != "-c" ; then 
  177.   echo shar: Will not clobber existing file \"'PORTING'\"
  178. else
  179. echo shar: Extracting \"'PORTING'\" \(3192 characters\)
  180. sed "s/^X//" >'PORTING' <<'END_OF_FILE'
  181. XThe default version uses the rstat call to get information.  The
  182. Xformat of the rstat call is:
  183. X
  184. Xrstat(host, stats)
  185. X
  186. Xwhere host is a string, and stats is a pointer to a statstime structure.
  187. X
  188. XProbably the easiest way to port to a new system that lacks rstat
  189. Xwould be to a new version of rstat.  In this file, I try to document
  190. Xthe members of the statstime structure, and how the program uses
  191. Xthe information.  Note that gathering of this information takes
  192. Xplace in the porting.c file.
  193. X
  194. XAfter that information is gathered (via rstat), it is then processed.
  195. XSince rstat reports the total number of events since the system started
  196. Xup, the number of events since the last time we updated the graph
  197. Xis the value just returned minus the value that was returned last.
  198. XThis is why there are two statstime structures in porting.c.  A variable
  199. X(new_stat) is used to keep track of which structure the new information
  200. Xwill be loaded into.
  201. X
  202. XThis data is then put into the points[][] array. Values should never
  203. Xbe less than zero.  The values are integers.  CPU time being used
  204. Xshould range from 0 to 100.  Number of disk transfers can be anything
  205. Xabove zero.
  206. X
  207. XXSysStats averages most information per second.  This means that if the
  208. Xupdate time is every 5 seconds, the number of events since the last
  209. Xgraph will be divided by 5 before.
  210. X
  211. XSTATSTIME STRUCTURE:
  212. X
  213. Xstats.cp_time[0]    user time
  214. Xstats.cp_time[1]    nice time
  215. Xstats.cp_time[2]    system time
  216. Xstats.cp_time[3]    idle time
  217. X
  218. Xthese are cumulative totals.  To find the percentage any one of
  219. Xthese is using, first find the difference between the new value
  220. Xand the old value.  Then, sum them all up.  The percentage any one of
  221. Xthem is using since the last request is the element divided by
  222. Xthe total.  XStatsTime uses the idle time (cp_time[3]) to determine
  223. Xthe amount being utilized.  Let delta[0-3] represent the difference
  224. Xsince the last update of the values above.  This means that for
  225. XXSysStat, the percent of cpu being used is 100 - 100*k[3]/(sum(k[0-3]).
  226. X
  227. X
  228. X
  229. Xstats.avenrun[0]    Divide value by 256 and this is the load
  230. Xstats.avenrun[1]    average over the last 1,5, and 15 minutes.
  231. Xstats.avenrun[2]
  232. X
  233. Xstats.v_swtch        total context switches
  234. X
  235. Xstats.if_collisions    ethernet activity - cumulative totals.
  236. Xstats.if_oerrors    XSysStat uses the ierrors and ipackets
  237. Xstats.if_opackets    elements. it might be better to sum
  238. Xstats.if_ierrors    ipackets+opackets and ierrors+oerrors for
  239. Xstats.if_ipackets    reporting.
  240. X
  241. Xstats.v_pgpgin        page in/out, swap in/out cumulative totals
  242. Xstats.v_pgpgout        XSysStat uses the pgpgin and pswpin elements.
  243. Xstats.v_pswpin        XSysStat does not average these over times.  IT will
  244. Xstats.v_pswpout        instead plot the total number of occurances of these
  245. X            since the last update.  Since these are usually
  246. X            fairly low occuring events, I prefered it this way.
  247. X
  248. Xstats.v_intr        cumulative # of interrupts.  Although it
  249. X            probably should no happen, at times a more
  250. X            recently reported value is less than the
  251. X            previous reported value.
  252. X
  253. Xstats.dk_xfer[0]    disk transfers.  Only the first seems to have
  254. Xstats.dk_xfer[1]    any real useful (nonzero) value?  If these are
  255. Xstats.dk_xfer[2]    similiar to what vmstat reports, these can
  256. Xstats.dk_xfer[3]    be for different disks.
  257. X
  258. END_OF_FILE
  259. if test 3192 -ne `wc -c <'PORTING'`; then
  260.     echo shar: \"'PORTING'\" unpacked with wrong size!
  261. fi
  262. # end of 'PORTING'
  263. fi
  264. if test -f 'README' -a "${1}" != "-c" ; then 
  265.   echo shar: Will not clobber existing file \"'README'\"
  266. else
  267. echo shar: Extracting \"'README'\" \(3882 characters\)
  268. sed "s/^X//" >'README' <<'END_OF_FILE'
  269. XXSysStats README:
  270. X
  271. XDESCRIPTION:
  272. X
  273. XXSysStats is a system information display tool similar to perfmeter.  It
  274. Xdisplays its information in the form of a strip chart.  It can also display
  275. Xinformation about remote hosts, as perfmeter can do.
  276. X
  277. XXSysStats can display any number of graphs at one time in the same window.
  278. XInformation being displayed in the window need not be all of the same host.
  279. XFor example, you could have it display the percentage of cpu being utilized
  280. Xof half a dozen (or more) different hosts.
  281. X
  282. XAs of this writing, the only system this has been tested on is a Sun 3/60
  283. Xrunning SunOs 4.1.1 and X11R5.  It should run on most any sun with SunOs
  284. X4.1.1.  For other systems, some porting may be required for it to work.
  285. XXSysStats use the 'rstat' function to get information.  This probably
  286. Xdoes not exist on all machines, and the structure it uses may vary
  287. Xbetween different machines.  See the PORTING file for more information
  288. Xon how to port to different systems.
  289. X
  290. XXSysStats require an ANSI capable compiler.  Gcc works fine, and
  291. XSun's acc also work (but may result in warnings at compile time.)
  292. X
  293. XThere are some things that perfmeter (Openwindows 2 version) is able to do
  294. Xthat XSysStats can not do.  Perfmeter in its iconic form displays a meter
  295. Xwith hands. XSysStats only displays information while in its open state.
  296. XAlso, perfmeter allows the user to change what information it displays, or
  297. Xhow frequently it updates it.  Once XSysStats has been run, what it displays
  298. Xis locked into place.
  299. X
  300. XHowever, XSysStats has the advantage that the only X library it uses is
  301. Xthe base X11 library.  This means the resident size is smaller than
  302. Xperfmeter (a lot of space can be saved if you run several perfmeters,
  303. Xas these could then be combined into one XSysStats window)
  304. XXSysStats in general consumes less CPU time than perfmeter does (an
  305. XXSysStat program displaying four graphs about one machine takes less than
  306. Xhalf the time a perfmeter took displaying just one graph.)
  307. XHowever, for reasons I have not figured out, it seems to consume more
  308. XCPU time than perfmeter if reporting on remote hosts.  Even with this
  309. Xincreased cost, it only accounted for about 1.5% of the cpu time on
  310. Xmy sun 3/60.
  311. X
  312. XNote:  The multiple graphs in one window will probably not be of much
  313. Xuse on a black/white system.  You really need to have the graphs different
  314. Xcolor (or perhaps scale of gray) to make much sense of them.
  315. X
  316. XLICENSE:
  317. X
  318. XXSysStats is Copyright (C) 1993 by Mark Wedel.
  319. X
  320. XXSysStats can be redistributed provided it is done free of charge.
  321. XXSysStats can also be modified, but original credit must be given to
  322. XMark Wedel.
  323. X
  324. XXSysStats is provided as is.  I take no responsibility for damage
  325. Xor problems caused by the use of XSysStats.
  326. X
  327. XTO BUILD:
  328. X
  329. X    Note:  An ANSI C compiler is required.  Changes to the Imakefile
  330. X    or Makefile may be needed depending on what the default compiler on
  331. X    your system can handle.
  332. X
  333. X    If using imake, the following should work fine:
  334. X
  335. X    1) xmkmf
  336. X    2) make
  337. X    3) make install
  338. X    4) make install.man
  339. X
  340. X    If you are instead using make, try:
  341. X
  342. X    1) cp Makefile.noIm Makefile
  343. X    2) Edit the Makefile.  Most things are pretty standard and clear.
  344. X    3) make
  345. X    4) make install
  346. X
  347. XBUGS/PROBLEMS/FIXES:
  348. X
  349. XIf you have fixed some problem, or added support for another machine,
  350. Xyou can send me the patch at master@rahul.net.
  351. X
  352. XIf you notice a bug, you can send me mail at the same address.  Please
  353. Xdo not send bug reports of it not compiling on a specific machine because
  354. Xrstat does not exist (or most other problems if they are in the porting.c
  355. Xfile.)  I likely will not have access to the hardware necessary to track
  356. Xthem down, so I will be able to do nothing about it.
  357. X
  358. XNOTES:
  359. X
  360. XIf you send me mail, please include a valid mail address I can reach
  361. Xyou at.
  362. X
  363. X Looking for a C/C++/X11 programmer in preferable the Silicon Valley?
  364. XSend me some mail.
  365. X
  366. XMark Wedel
  367. Xmaster@rahul.net
  368. XOctober 18, 1993
  369. END_OF_FILE
  370. if test 3882 -ne `wc -c <'README'`; then
  371.     echo shar: \"'README'\" unpacked with wrong size!
  372. fi
  373. # end of 'README'
  374. fi
  375. if test -f 'TODO' -a "${1}" != "-c" ; then 
  376.   echo shar: Will not clobber existing file \"'TODO'\"
  377. else
  378. echo shar: Extracting \"'TODO'\" \(954 characters\)
  379. sed "s/^X//" >'TODO' <<'END_OF_FILE'
  380. XThings that would be nice to have done, but may be difficult to do.
  381. X
  382. XSome way to tell in the window what the scale division lines (as
  383. Xselected by the -scale) arguement are.  Writing them along the left
  384. Xedge would require that the entire graph be redrawn, or a smart way to
  385. Xerase the values and then redraw them.  Perhaps they can be written at
  386. Xthe bottom of the screen, as another number after the scale of the graph.
  387. XIe, "disk    20/5" would should that the scale of the graph is 20,
  388. Xbut the division lines are drawn in increments of 5.
  389. X
  390. XStoring all -type values for all hosts, and allow switching of the graph
  391. Xtype (by keyboard).  This will cause more memory use and probably also
  392. Xmore cpu use to set and store all these values.
  393. X
  394. XAbility to have one XSysStats program control several windows or split
  395. Xthe one window into several subwindows.  In this way, a mininum amount
  396. Xof space and rstats calls would be used to display possibly all the
  397. Xdata gathered.
  398. END_OF_FILE
  399. if test 954 -ne `wc -c <'TODO'`; then
  400.     echo shar: \"'TODO'\" unpacked with wrong size!
  401. fi
  402. # end of 'TODO'
  403. fi
  404. if test -f 'headers.h' -a "${1}" != "-c" ; then 
  405.   echo shar: Will not clobber existing file \"'headers.h'\"
  406. else
  407. echo shar: Extracting \"'headers.h'\" \(502 characters\)
  408. sed "s/^X//" >'headers.h' <<'END_OF_FILE'
  409. X/* These are really included so that I can use gcc -Wall and not see
  410. X * warnings that these are undefined.  If your system has function
  411. X * prototypes, this is unneeded.
  412. X */
  413. X
  414. X#ifdef __GNUC__
  415. X/* These do not seem to be needed with gcc-2.5.0.  In fact, having
  416. X * them declared causes errors.
  417. X */
  418. X
  419. X/*
  420. Xvoid    printf(char* , ...);
  421. Xvoid    puts(char *);
  422. Xvoid    fprintf(FILE*, char *, ...);
  423. X*/
  424. Xint     sleep(unsigned);
  425. Xint     atoi(char *);
  426. Xint    gethostname(char *, int);
  427. Xchar     *strcat(char *, char*);
  428. X#endif
  429. END_OF_FILE
  430. if test 502 -ne `wc -c <'headers.h'`; then
  431.     echo shar: \"'headers.h'\" unpacked with wrong size!
  432. fi
  433. # end of 'headers.h'
  434. fi
  435. if test -f 'patchlevel.h' -a "${1}" != "-c" ; then 
  436.   echo shar: Will not clobber existing file \"'patchlevel.h'\"
  437. else
  438. echo shar: Extracting \"'patchlevel.h'\" \(33 characters\)
  439. sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
  440. X#define VERSION "XSysStats 1.10"
  441. END_OF_FILE
  442. if test 33 -ne `wc -c <'patchlevel.h'`; then
  443.     echo shar: \"'patchlevel.h'\" unpacked with wrong size!
  444. fi
  445. # end of 'patchlevel.h'
  446. fi
  447. if test -f 'porting.c' -a "${1}" != "-c" ; then 
  448.   echo shar: Will not clobber existing file \"'porting.c'\"
  449. else
  450. echo shar: Extracting \"'porting.c'\" \(6896 characters\)
  451. sed "s/^X//" >'porting.c' <<'END_OF_FILE'
  452. X#include <rpcsvc/rstat.h>
  453. X#include "xsysstats.h"
  454. X#include "headers.h"
  455. X
  456. X/* add a function prototype for clean compiles with -Wall */
  457. X#ifdef __GNUC__
  458. Xint    rstat(char *, struct statstime *);
  459. X#endif
  460. X
  461. Xstruct statstime    *our_stats;
  462. Xstatic int new_stat=0;
  463. X
  464. X/* set_first_values allocates the space to actually store the values,
  465. X * add then reads in a first set into them.
  466. X */
  467. Xvoid set_first_values()
  468. X{
  469. X    int    i;
  470. X
  471. X    our_stats = (struct statstime *)
  472. X        malloc(sizeof(struct statstime) * num_hosts * 2);
  473. X    for (i=0; i<num_hosts; i++)
  474. X        rstat(hosts[i], &our_stats[i*2 + new_stat]);
  475. X
  476. X    new_stat++;
  477. X    new_stat %=2;
  478. X}
  479. X
  480. X/* This sets the scale of similiar graphs to the same value.  The highest
  481. X * scale value is used.  The graph arguement that is passed is the graph
  482. X * value that has just changed.  It may or may not be more efficient to wait
  483. X * until all the graphs have changed scale before going through and 
  484. X * synchronizing the other graphs to match.  It depends on the circumstances.
  485. X * of rescaling.
  486. X * Since any call to this function means that the scale has changed,
  487. X * a redraw will happen at some point after the return.
  488. X * It may also be better to make it so that a re-draw will only be done
  489. X * if the scale actually changes.  Right now, a downscale attempt may
  490. X * be made, but because the scales are synchronized, the scale does not
  491. X * change.  However, it will re-draw the window when there was no need
  492. X * to.
  493. X */
  494. Xstatic void sync_scales(struct graph_info graph)
  495. X{
  496. X    int max=0,num_match=0,i;
  497. X
  498. X    for (i=0; i<num_graphs; i++) 
  499. X        if (graphs[i].type == graph.type) {
  500. X        num_match++;
  501. X        if (graphs[i].true_scale>max)
  502. X            max=graphs[i].true_scale;
  503. X        }
  504. X    if (num_match>1) {
  505. X        for (i=0; i<num_graphs; i++)
  506. X            if (graphs[i].type == graph.type)
  507. X            graphs[i].scale = max;
  508. X    }
  509. X}
  510. X
  511. X/* return value is if we redrew the graph (true if we did) */
  512. Xint set_values()
  513. X{
  514. X    int i,graph_redraw_needed=FALSE,newstat,oldstat;
  515. X    static int num_ticks=0;
  516. X
  517. X    num_ticks++;
  518. X    for (i=0; i<num_hosts; i++)
  519. X        rstat(hosts[i], &our_stats[i*2 + new_stat]);
  520. X
  521. X    new_stat++;
  522. X    new_stat %= 2;
  523. X    point_pos++;
  524. X    point_pos %= width;
  525. X    for (i=0; i<num_graphs; i++) {
  526. X        newstat = graphs[i].host_offset * 2 + ((1 + new_stat) % 2);
  527. X        oldstat = graphs[i].host_offset * 2 + new_stat;
  528. X
  529. X        switch (graphs[i].type) {
  530. X        case CPU: {
  531. X            int    j[4],k;
  532. X
  533. X            for (k=0; k<4; k++)
  534. X                j[k] = our_stats[newstat].cp_time[k] - our_stats[oldstat].cp_time[k];
  535. X            points[i][point_pos] = 100 - 
  536. X            (100 * j[3]) / (j[0]+j[1]+j[2]+j[3]);
  537. X            break;
  538. X        }
  539. X        case PACKETS:
  540. X            points[i][point_pos] = (our_stats[newstat].if_ipackets
  541. X                 - our_stats[oldstat].if_ipackets) / sleep_time;
  542. X            break;
  543. X        case PAGE:
  544. X            points[i][point_pos] = our_stats[newstat].v_pgpgin
  545. X                 - our_stats[oldstat].v_pgpgin;
  546. X            break;
  547. X        case SWAP:
  548. X            points[i][point_pos] = our_stats[newstat].v_pswpin
  549. X                 - our_stats[oldstat].v_pswpin;
  550. X            break;
  551. X        case INT:
  552. X            points[i][point_pos] = ((signed)our_stats[newstat].v_intr
  553. X                 - (signed)our_stats[oldstat].v_intr)/sleep_time;
  554. X            if (points[i][point_pos] < 0)
  555. X                points[i][point_pos] = 0;
  556. X            break;
  557. X        case DISK:
  558. X            points[i][point_pos] = (our_stats[newstat].dk_xfer[0]
  559. X                +our_stats[newstat].dk_xfer[1]
  560. X                +our_stats[newstat].dk_xfer[2]
  561. X                +our_stats[newstat].dk_xfer[3]
  562. X                -our_stats[oldstat].dk_xfer[0]
  563. X                -our_stats[oldstat].dk_xfer[1]
  564. X                -our_stats[oldstat].dk_xfer[2]
  565. X                -our_stats[oldstat].dk_xfer[3])
  566. X                /sleep_time;
  567. X            break;
  568. X        case CONTEXT:
  569. X            points[i][point_pos] = (our_stats[newstat].v_swtch
  570. X                 - our_stats[oldstat].v_swtch)/sleep_time;
  571. X            break;
  572. X
  573. X        /* Load averages get handles a bit differently.  By default,
  574. X         * dividign the avenrun[] by 256 gets you the load average.
  575. X         * However, often load average is fairly low - under 5.
  576. X         * This does not give very good resolution in decimal form.
  577. X         * So it is multiplied by LOAD_FACTOR and then divided.
  578. X         * For scale, the same thing is true.  When display the
  579. X         * legend at the bottom of the screen, scale is then
  580. X         * divided by LOAD_FACTOR.  If LOAD_FACTOR is 100, is
  581. X         * effectively keeps two decimal points, making for
  582. X         * a fairly fine graph.
  583. X         * graphs[i].scale_mult has the same value as LOAD_FACTOR
  584. X         * for the load average graphs.
  585. X         */
  586. X        case LOAD1:
  587. X            points[i][point_pos] =
  588. X                (our_stats[newstat].avenrun[0] * LOAD_FACTOR) / 256;
  589. X            break;
  590. X        case LOAD5:
  591. X            points[i][point_pos] =
  592. X                (our_stats[newstat].avenrun[1] * LOAD_FACTOR) / 256;
  593. X            break;
  594. X        case LOAD15:
  595. X            points[i][point_pos] =
  596. X                (our_stats[newstat].avenrun[2] * LOAD_FACTOR) / 256;
  597. X            break;
  598. X        case COLL:
  599. X            points[i][point_pos] = our_stats[newstat].if_collisions
  600. X                 - our_stats[oldstat].if_collisions;
  601. X            break;
  602. X        case ERRORS:
  603. X            points[i][point_pos] = our_stats[newstat].if_ierrors
  604. X                 - our_stats[oldstat].if_ierrors;
  605. X            break;
  606. X        default:
  607. X            fprintf(stderr,"Unknown graph type: %d, graph %d\n",graphs[i].type, i);
  608. X        
  609. X        }
  610. X        if (points[i][point_pos]<0) points[i][point_pos]=0;
  611. X        graphs[i].running_avg += points[i][point_pos] -
  612. X            graphs[i].running_avg;
  613. X
  614. X        /* Check to see if the graph needs to be downscaled.  Only actually
  615. X         * attempt to do downscaling once every 10 ticks.  This is to
  616. X         * prevent excessive runthroughs of the points array, finding
  617. X         * the max value it holds.
  618. X         * We do the check on true_scale.  IF graphs are synchronized,
  619. X         * there is no point seeing if we can downscale when we know
  620. X         * that we should, but another graph has a higher scale.
  621. X         */
  622. X        
  623. X        if (!(num_ticks % DOWNSCALE_OCCURANCE) &&
  624. X        graphs[i].running_avg<graphs[i].true_scale*graphs[i].scale_mult
  625. X        && graphs[i].true_scale>graphs[i].min_scale) {
  626. X            int    k,max=0;
  627. X
  628. X            for (k=0; k<width; k++)
  629. X            if (points[i][k]>max) max=points[i][k];
  630. X            if (graphs[i].true_scale*graphs[i].scale_mult / 2 > max) {
  631. X            while (graphs[i].running_avg<graphs[i].true_scale * graphs[i].scale_mult &&
  632. X                graphs[i].true_scale * graphs[i].scale_mult/2 > max &&
  633. X                graphs[i].true_scale > graphs[i].min_scale)
  634. X                graphs[i].true_scale /=2;
  635. X
  636. X            if (graphs[i].true_scale < graphs[i].min_scale)
  637. X                graphs[i].true_scale = graphs[i].min_scale;
  638. X            graphs[i].scale = graphs[i].true_scale;
  639. X            graph_redraw_needed = TRUE;
  640. X            if (scale_sync) sync_scales(graphs[i]);
  641. X            }
  642. X        }
  643. X
  644. X        if (points[i][point_pos]>graphs[i].true_scale*graphs[i].scale_mult &&
  645. X        graphs[i].true_scale<graphs[i].max_scale) {
  646. X            do {
  647. X            graphs[i].true_scale *= 2;
  648. X            } while (points[i][point_pos]>=graphs[i].true_scale * graphs[i].scale_mult &&
  649. X            graphs[i].true_scale < graphs[i].max_scale);
  650. X            if (graphs[i].true_scale>graphs[i].max_scale)
  651. X            graphs[i].true_scale = graphs[i].max_scale;
  652. X        graphs[i].scale = graphs[i].true_scale;
  653. X        graph_redraw_needed = TRUE;
  654. X        if (scale_sync) sync_scales(graphs[i]);
  655. X        }
  656. X    }
  657. X    
  658. X    /* Only re-draw it once.  That is why graph_redraw_needed is set
  659. X     * above, and not just a call to redraw_graph
  660. X     */
  661. X    if (graph_redraw_needed)
  662. X        redraw_graph();
  663. X
  664. X    return graph_redraw_needed;
  665. X}
  666. END_OF_FILE
  667. if test 6896 -ne `wc -c <'porting.c'`; then
  668.     echo shar: \"'porting.c'\" unpacked with wrong size!
  669. fi
  670. # end of 'porting.c'
  671. fi
  672. if test -f 'xsysstats.c' -a "${1}" != "-c" ; then 
  673.   echo shar: Will not clobber existing file \"'xsysstats.c'\"
  674. else
  675. echo shar: Extracting \"'xsysstats.c'\" \(22822 characters\)
  676. sed "s/^X//" >'xsysstats.c' <<'END_OF_FILE'
  677. X#include "xsysstats.h"
  678. X#include "headers.h"
  679. X#include "patchlevel.h"
  680. X
  681. Xstruct base_types {
  682. X    char    *cmd_option;    /* how it is called on the command line */
  683. X    char    *window_name;    /* what we call it on the window */
  684. X    int    def_scale;    /* default scale for that graph type */
  685. X};
  686. X
  687. X/* It is important that the n'th placement of this array corresponds
  688. X * to the n'th value type in xsysstats.h (ie, 9'th value corresponds to errors)
  689. X */
  690. Xstruct base_types types[NUM_TYPES+1] = {
  691. X{"cpu", "cpu", 100}, {"packets", "pkts",32}, {"page", "page",16},
  692. X{"swap", "swap",16},{"interrupts", "intr",200}, {"disk", "disk",40},
  693. X{"context", "ctxt",128},
  694. X{"load1", "load1",2},
  695. X{"load5", "load5", 2},
  696. X{"load15", "load15", 2},
  697. X{"collisions", "coll",8},
  698. X{"errors", "errs",8}
  699. X};
  700. X
  701. X
  702. X/* Various notes:
  703. X * we store the values in the 'points' variable.  They are stored in the
  704. X * form we get from rstat.  To figure out where the point should be plotted,
  705. X * it is rstat_value * vertical_size / scale.
  706. X */
  707. X
  708. Xint        screen_num, num_graphs=0, **points,point_pos=-1,sleep_time=2,
  709. X        height,width, xpos,font_height=0, num_info_lines,
  710. X        draw_baseline=FALSE,scale_sync=FALSE,allnames=FALSE,
  711. X        num_hosts=0,localhost=-1,hide_labels=FALSE;
  712. Xunsigned long    whitepixel,blackpixel;
  713. XDisplay    *display;
  714. XWindow    win;
  715. XXFontStruct    *font_info;
  716. XGC    gc;
  717. XXColor    background, foreground,baseline;
  718. XPixmap    new_win;    /* used for scrolling */
  719. Xchar    **hosts;
  720. X
  721. X
  722. X
  723. XXSizeHints size_hints = { PMinSize | PWinGravity,0,0,DEFAULT_SIZE,
  724. X    DEFAULT_SIZE,DEFAULT_SIZE, DEFAULT_SIZE, 0,0,0,0,{0,0},{0,0},0,0,
  725. X    NorthWestGravity};
  726. X
  727. Xvoid redraw_graph()
  728. X{
  729. X    int    i,pp,x,max_x,font_line=0,fontx=0,fonts_per_line,deltax,pp1;
  730. X    char    tmp[256];
  731. X    XCharStruct    scale_info;
  732. X
  733. X    XClearWindow(display, win);
  734. X    if (draw_baseline) {
  735. X        XSetForeground(display, gc, baseline.pixel);
  736. X        XDrawLine(display, win, gc, INSIDE_BORDER_WIDTH,
  737. X            height+INSIDE_BORDER_WIDTH, xpos, height + INSIDE_BORDER_WIDTH);
  738. X    }
  739. X    fonts_per_line = width / TEXT_WIDTH;
  740. X    deltax = width / fonts_per_line;
  741. X
  742. X    for (i=0; i<num_graphs; i++) {
  743. X        XSetForeground(display, gc, graphs[i].color_pixel);
  744. X        if (!hide_labels) {
  745. X        XDrawImageString(display, win, gc, fontx * deltax + 
  746. X            INSIDE_BORDER_WIDTH, height + 2 + font_height*font_line +
  747. X            INSIDE_BORDER_WIDTH + font_info->max_bounds.ascent,
  748. X            graphs[i].name, graphs[i].name_len);
  749. X
  750. X        sprintf(tmp, "%d", graphs[i].scale);
  751. X
  752. X        XTextExtents(font_info, tmp, strlen(tmp), 
  753. X            &x, &x, &x, &scale_info);
  754. X        XDrawImageString(display, win, gc, (fontx + 1) * deltax -
  755. X            INSIDE_BORDER_WIDTH - scale_info.width, height + 2 +
  756. X            font_height * font_line + INSIDE_BORDER_WIDTH +
  757. X            font_info->max_bounds.ascent,
  758. X            tmp, strlen(tmp));
  759. X        fontx++;
  760. X        if (fontx==fonts_per_line) {
  761. X            fontx=0;
  762. X            font_line++;
  763. X        }
  764. X        }
  765. X        if (xpos<width) {
  766. X        pp=0;
  767. X        max_x = xpos-1;
  768. X        }
  769. X        else {
  770. X        pp = (point_pos + 1) % width;
  771. X        max_x = width;
  772. X        }
  773. X        for (x=INSIDE_BORDER_WIDTH; x<max_x; x++) {
  774. X        pp1 = (pp +1) % width;
  775. X        XDrawLine(display,win, gc, x, INSIDE_BORDER_WIDTH+
  776. X            height-points[i][pp] * height/(graphs[i].scale *
  777. X            graphs[i].scale_mult), x+1,
  778. X            INSIDE_BORDER_WIDTH +height -
  779. X            (points[i][pp1] * height) / (graphs[i].scale *
  780. X            graphs[i].scale_mult));
  781. X        pp = pp1;
  782. X        /* point_pos %2 is to draw it every other point. */
  783. X        if (graphs[i].scale_lines>0 && !(pp % 2) &&
  784. X            graphs[i].scale_lines<graphs[i].scale) {
  785. X            int    sline,slineinc=1;
  786. X
  787. X            while ((graphs[i].scale_lines*slineinc*height / graphs[i].scale) < PTSSCALELINE)
  788. X                slineinc*=2;
  789. X            sline = slineinc;
  790. X            /* Yes, it is supposed to be just less than scale,
  791. X             * not less than equal.  No point drawing a line at
  792. X             * the top of the window.
  793. X             */
  794. X            while (sline*graphs[i].scale_lines < graphs[i].scale) {
  795. X                XDrawPoint(display, win, gc, x,
  796. X                height - (sline * graphs[i].scale_lines * height) /
  797. X                graphs[i].scale + INSIDE_BORDER_WIDTH);
  798. X                sline+=slineinc;
  799. X            }
  800. X            }
  801. X        }
  802. X    }
  803. X    XFlush(display);
  804. X}
  805. X
  806. Xvoid resize_window(XEvent event)
  807. X{
  808. X    int redraw_needed = FALSE,i, redo_height = FALSE;
  809. X
  810. X    /* Width changes are a little tricky.  We need
  811. X     * malloc new structures, copy the data into
  812. X     * it, and the free the old ones.
  813. X     */
  814. X
  815. X    if (event.xconfigure.width !=size_hints.width &&
  816. X        event.xconfigure.width>=DEFAULT_SIZE) {
  817. X        int    new_width,*new_points,q,new_info_lines,fonts_per_line;
  818. X
  819. X        size_hints.width = event.xconfigure.width;
  820. X        new_width = size_hints.width - 2*INSIDE_BORDER_WIDTH;
  821. X        for (i=0; i<num_graphs; i++) {
  822. X            int    z=0;
  823. X
  824. X            new_points =  (int *) malloc(sizeof(int) *new_width);
  825. X
  826. X            /* If the window is larger, we need to copy all
  827. X             * the old points.
  828. X             */
  829. X
  830. X            if (new_width>width) {
  831. X                if (xpos<width) {
  832. X                for (q=0; q<=point_pos; q++)
  833. X                    new_points[q] = points[i][q];
  834. X                }
  835. X                else {
  836. X                for (q=point_pos+1; q<=point_pos+width; q++)
  837. X                    new_points[z++]=points[i][q%width];
  838. X                }
  839. X            }
  840. X            /* if the new window is smaller, we only want to
  841. X             * copy the newest points.
  842. X             */
  843. X            else {
  844. X                if (xpos<width) {
  845. X                int xstart;
  846. X
  847. X                if (point_pos>new_width)
  848. X                    xstart=point_pos-new_width;
  849. X                else xstart=0;
  850. X                for (q=xstart; q<=point_pos; q++)
  851. X                    new_points[z++]=points[i][q];
  852. X                }
  853. X                else {
  854. X                for (q=0; q<new_width; q++)
  855. X                    new_points[z++]=
  856. X                    points[i][(q+width-new_width)%width];
  857. X                }
  858. X            }
  859. X            free(points[i]);
  860. X            points[i] = new_points;
  861. X        }
  862. X
  863. X        /* If we had more points than the new window can display,
  864. X         * then set the number of points we have to the max the
  865. X         * window can handle. 
  866. X         * Otherwise, if the old window was filled up, set the
  867. X         * next point to be drawn at the end of the old window.
  868. X         * Remember, after the copy, the oldest point will be point
  869. X         * #0.
  870. X         * Otherwise, if the old window wasn't filled up and
  871. X         * the number of points would not fill up the new
  872. X         * window, keep the point_pos value the same.
  873. X         */
  874. X
  875. X        if (point_pos > new_width) point_pos = new_width-1;
  876. X        else if (xpos>=width) point_pos=width-1;
  877. X
  878. X        if (new_width<xpos) xpos=new_width;
  879. X        width = new_width;
  880. X        redraw_needed = TRUE;
  881. X        fonts_per_line = width/TEXT_WIDTH;
  882. X        new_info_lines = num_graphs / fonts_per_line;
  883. X        if (new_info_lines * fonts_per_line < num_graphs)
  884. X            new_info_lines ++;
  885. X        if (new_info_lines != num_info_lines) {
  886. X            num_info_lines = new_info_lines;
  887. X            redo_height = TRUE;
  888. X            if (event.xconfigure.height < DEFAULT_SIZE) 
  889. X                event.xconfigure.height = DEFAULT_SIZE;
  890. X        }
  891. X
  892. X        }
  893. X
  894. X    /* height change is simple.  Just update our
  895. X     * values, and the re-draw function will scale
  896. X     * everything to the new height.
  897. X     */
  898. X    if ((event.xconfigure.height !=size_hints.height &&
  899. X        event.xconfigure.height>=DEFAULT_SIZE) || (redo_height)) {
  900. X        size_hints.height = event.xconfigure.height;
  901. X        if (hide_labels)
  902. X            height = size_hints.height - INSIDE_BORDER_WIDTH*2;
  903. X        else
  904. X            height = size_hints.height- font_height*num_info_lines
  905. X                 - INSIDE_BORDER_WIDTH*2;
  906. X        redraw_needed = TRUE;
  907. X        }
  908. X
  909. X    /* This is true only if width or height actually
  910. X     * changed in any way.
  911. X     */
  912. X    if (redraw_needed) {
  913. X        redraw_graph();
  914. X        XFreePixmap(display, new_win);
  915. X        new_win = XCreatePixmap(display, win, width-1,size_hints.height+INSIDE_BORDER_WIDTH,
  916. X            DefaultDepth(display, screen_num));
  917. X    }
  918. X}
  919. X
  920. X/* This function process various keypresses.  If an unknown/unsupported
  921. X * key is pressed, it is just ignored.  As of now, only 1 character
  922. X * codes are used, so only the first character of keypress holds any
  923. X * relevance.
  924. X */
  925. Xvoid process_keypress(char *keypress)
  926. X{
  927. X    switch (keypress[0]) {
  928. X    case 'l':
  929. X    case 'L':
  930. X        if (hide_labels) {
  931. X            height = size_hints.height- font_height*num_info_lines
  932. X                 - INSIDE_BORDER_WIDTH*2;
  933. X            hide_labels = FALSE;
  934. X        }
  935. X        else {
  936. X            height = size_hints.height - INSIDE_BORDER_WIDTH*2;
  937. X            hide_labels = TRUE;
  938. X        }
  939. X        redraw_graph();
  940. X        break;
  941. X    }
  942. X}
  943. X
  944. Xvoid check_events()
  945. X{
  946. X    XEvent    event;
  947. X    char    keystring[10];
  948. X
  949. X    while (XEventsQueued(display,QueuedAfterFlush)) {
  950. X        XNextEvent(display, &event);
  951. X
  952. X        switch (event.type) {
  953. X        case Expose:
  954. X            if (event.xexpose.count==0)
  955. X                redraw_graph();
  956. X            break;
  957. X
  958. X        case ConfigureNotify:
  959. X            resize_window(event);
  960. X            break;
  961. X
  962. X        case KeyPress:
  963. X            XLookupString((XKeyEvent *) &event, keystring,10, NULL, NULL);
  964. X            process_keypress(keystring);
  965. X            break;
  966. X
  967. X        /* We don't really care about these, but they might
  968. X         * be generated with the StructureNotifyMask.
  969. X         */
  970. X        case CirculateNotify:
  971. X        case GravityNotify:
  972. X        case MapNotify:
  973. X        case ReparentNotify:
  974. X        case UnmapNotify:
  975. X        case MappingNotify:
  976. X            break;
  977. X
  978. X        default:
  979. X            printf("unknown event: %d\n", event.type);
  980. X        }
  981. X    }
  982. X}
  983. X
  984. X
  985. Xvoid graph_loop()
  986. X{
  987. X    int    i,*lasty,fonts_per_line;
  988. X
  989. X    width = size_hints.width - 2*INSIDE_BORDER_WIDTH;
  990. X    fonts_per_line = width/TEXT_WIDTH;
  991. X    num_info_lines = num_graphs / fonts_per_line;
  992. X    if (num_info_lines * fonts_per_line < num_graphs)
  993. X            num_info_lines ++;
  994. X
  995. X    if (hide_labels)
  996. X        height = size_hints.height - INSIDE_BORDER_WIDTH*2;
  997. X    else
  998. X        height = size_hints.height- font_height*num_info_lines -
  999. X             INSIDE_BORDER_WIDTH*2;
  1000. X
  1001. X    points =(int **)  malloc(sizeof(int * )  * num_graphs);
  1002. X    lasty = (int *) malloc(sizeof(int) * num_graphs);
  1003. X
  1004. X    for (i=0; i<num_graphs; i++) {
  1005. X        points[i] =  (int *) malloc(sizeof(int) *width);
  1006. X        graphs[i].running_avg = (graphs[i].scale+1)*width *
  1007. X            graphs[i].scale_mult;
  1008. X        if (graphs[i].host_offset != localhost || allnames) {
  1009. X            strcat(graphs[i].name,"@");
  1010. X            strcat(graphs[i].name,hosts[graphs[i].host_offset]);
  1011. X        }
  1012. X        graphs[i].name_len = strlen(graphs[i].name);
  1013. X    }
  1014. X
  1015. X    /* Create a pixmap for scrolling just about the size of the
  1016. X     * window. size_hints.height is used instead of the height
  1017. X     * variable because the labels can be turned on and off.  So
  1018. X     * we create a pixmap that is large enough in case the labels
  1019. X     * are turned off.
  1020. X     */
  1021. X    new_win = XCreatePixmap(display, win, width-1,size_hints.height+
  1022. X        INSIDE_BORDER_WIDTH, DefaultDepth(display, screen_num));
  1023. X
  1024. X    set_first_values();
  1025. X    sleep(sleep_time);
  1026. X    set_values();        /* this call sets the starting point */
  1027. X    sleep(sleep_time);
  1028. X    if (draw_baseline) {
  1029. X        XSetForeground(display,gc, baseline.pixel);
  1030. X        XDrawPoint(display,win,gc, xpos,INSIDE_BORDER_WIDTH + height);
  1031. X    }
  1032. X    xpos=INSIDE_BORDER_WIDTH + 1;
  1033. X    for (i=0; i<num_graphs; i++)
  1034. X        lasty[i] = points[i][0];
  1035. X
  1036. X    while (1) {
  1037. X        /* set_values returns true if the graph has been re-drawn.
  1038. X         * If a the graph has been re-drawn and we are at the
  1039. X         * edge of the screen, decrease xpos.  We do not need to
  1040. X         * to scroll over, however, because that will have been taken
  1041. X         * care of by the redraw function.
  1042. X         */
  1043. X        if (set_values() && xpos>width)
  1044. X        xpos--;
  1045. X        if (xpos>width) {
  1046. X        XCopyArea(display, win, new_win, gc,
  1047. X             INSIDE_BORDER_WIDTH+1,0,
  1048. X             width-1, height+INSIDE_BORDER_WIDTH*2, 0,0);
  1049. X        XClearArea(display, win, width-1 - INSIDE_BORDER_WIDTH,0,
  1050. X            width-INSIDE_BORDER_WIDTH, height+INSIDE_BORDER_WIDTH, False);
  1051. X        XCopyArea(display, new_win, win, gc, 0, 0, width-1,
  1052. X            height+INSIDE_BORDER_WIDTH*2,
  1053. X            INSIDE_BORDER_WIDTH,0);
  1054. X        xpos--;
  1055. X        }
  1056. X        if (draw_baseline) {
  1057. X        XSetForeground(display,gc, baseline.pixel);
  1058. X        XDrawPoint(display,win,gc, xpos,INSIDE_BORDER_WIDTH + height);
  1059. X        }
  1060. X        for (i=0; i<num_graphs; i++) {
  1061. X        XSetForeground(display, gc, graphs[i].color_pixel);
  1062. X
  1063. X        XDrawLine(display,win, gc, xpos-1, INSIDE_BORDER_WIDTH +
  1064. X            height- lasty[i] * height/(graphs[i].scale *
  1065. X            graphs[i].scale_mult), xpos,
  1066. X            INSIDE_BORDER_WIDTH +height - (points[i][point_pos] *
  1067. X            height) / (graphs[i].scale * graphs[i].scale_mult));
  1068. X        lasty[i] = points[i][point_pos];
  1069. X        /* point_pos %2 is to draw it every other point. */
  1070. X        if (graphs[i].scale_lines>0 && !(point_pos % 2) &&
  1071. X            graphs[i].scale_lines<graphs[i].scale) {
  1072. X            int    sline,slineinc=1;
  1073. X
  1074. X            /* Keep is so that the number of horizontal lines is
  1075. X             * at least somewhat reasonable.
  1076. X             */
  1077. X            while ((graphs[i].scale_lines*slineinc*height / graphs[i].scale) < PTSSCALELINE)
  1078. X                slineinc*=2;
  1079. X            sline = slineinc;
  1080. X
  1081. X            /* Yes, it is supposed to be just less than scale,
  1082. X             * not less than equal.  No point drawing a line at
  1083. X             * the top of the window.
  1084. X             */
  1085. X            while (sline*graphs[i].scale_lines < graphs[i].scale) {
  1086. X                XDrawPoint(display, win, gc, xpos -1,
  1087. X                height - (sline * graphs[i].scale_lines * height) /
  1088. X                graphs[i].scale + INSIDE_BORDER_WIDTH);
  1089. X                sline+=slineinc;
  1090. X            }
  1091. X            }
  1092. X        }
  1093. X        xpos++;
  1094. X        /* Sleep for 1 second at a time, then check for events.
  1095. X         * This is done so that there will never be more than
  1096. X         * 1 second before events are handled.  The program does
  1097. X         * assume that all other processing time is negligable
  1098. X         * in respect to the sleep amount
  1099. X         */
  1100. X        for (i=0; i<sleep_time; i++) {
  1101. X        sleep(1);
  1102. X        check_events();
  1103. X        }
  1104. X    }
  1105. X}
  1106. X
  1107. Xvoid set_up_graph(char *graphtype)
  1108. X{
  1109. X    int    i;
  1110. X
  1111. X    for (i=0; i <= NUM_TYPES; i++) {
  1112. X        if (!strcmp(graphtype, types[i].cmd_option)) {
  1113. X        if (num_graphs==0)
  1114. X            graphs = (struct graph_info *)
  1115. X                malloc(sizeof(struct graph_info));
  1116. X        else
  1117. X            graphs = (struct graph_info *)
  1118. X                realloc(graphs, sizeof(struct graph_info)*
  1119. X                (num_graphs+1));
  1120. X        graphs[num_graphs].type = i;
  1121. X        graphs[num_graphs].scale = types[i].def_scale;
  1122. X        graphs[num_graphs].true_scale = types[i].def_scale;
  1123. X        graphs[num_graphs].color_pixel = foreground.pixel;
  1124. X        strcpy(graphs[num_graphs].name,types[i].window_name);
  1125. X        graphs[num_graphs].host_offset = -1;
  1126. X        graphs[num_graphs].scale_lines = 0;
  1127. X        if (i==CPU) {
  1128. X            graphs[num_graphs].max_scale = 100;
  1129. X            graphs[num_graphs].min_scale = 100;
  1130. X        }
  1131. X        else {
  1132. X            graphs[num_graphs].max_scale = 0x7fffffff;
  1133. X            graphs[num_graphs].min_scale = 2;
  1134. X        }
  1135. X        if (i>=LOAD1 && i<=LOAD15)
  1136. X            graphs[num_graphs].scale_mult = LOAD_FACTOR;
  1137. X        else
  1138. X            graphs[num_graphs].scale_mult = 1;
  1139. X
  1140. X        break;
  1141. X        }
  1142. X    }
  1143. X    if (i>NUM_TYPES) {
  1144. X        fprintf(stderr,"Unknown graph type: %s\n", graphtype);
  1145. X        exit(1);
  1146. X    }
  1147. X    else num_graphs++;
  1148. X}
  1149. X
  1150. Xvoid usage()
  1151. X{
  1152. X    printf("%s Usage:\n",VERSION);
  1153. X    puts("-allnames        Display names of all hosts, even localhost");
  1154. X    puts("-background color     background color");
  1155. X    puts("-baseline color        draw baseline of color 'color'");
  1156. X    puts("-color color        color of last graph specified by -type");
  1157. X    puts("-display displayname    X server to contact");
  1158. X    puts("-foreground color    foreground color");
  1159. X    puts("-geometry geom        size (in pixels) and position");
  1160. X    puts("-hidelabels        do not display labels at bottom of graph.");
  1161. X    puts("-host string        machine to report statistics on");
  1162. X    puts("-min number        minimum scale of last graph specified by -type");
  1163. X    puts("-max number        maximum scale of last graph specified by -type");
  1164. X    puts("-samescale        Synchronize scales of similar graphs");
  1165. X    puts("-sample number        how many seconds between each update");
  1166. X    puts("-scale number        draw dotted horizontal lines of the last graph");
  1167. X    puts("            at value specified.");
  1168. X    puts("-type string        type of graph to display: Choices of cpu,");
  1169. X    puts("            packets, page, swap, interrupts, disk, context, load,");
  1170. X    puts("            collisions, or errors.");
  1171. X    
  1172. X    exit(1);
  1173. X}
  1174. X
  1175. Xvoid parse_args(argc, argv)
  1176. Xint argc;
  1177. Xchar *argv[];
  1178. X{
  1179. X
  1180. X    int    i=1;
  1181. X    XColor        exact,screen_def;
  1182. X
  1183. X    while (i<argc) {
  1184. X
  1185. X        /* Display has been processed in main.  Just ignore it here */
  1186. X        if (!strcmp(argv[i],"-display"))
  1187. X            i++;
  1188. X        else if (!strcmp(argv[i],"-geometry")) {
  1189. X            int    geomask;
  1190. X            /* Would be nice if in the size_hints structure
  1191. X             * declaration in the X11 header files that width
  1192. X             * and height would be declared the same as what
  1193. X             * most calls use..
  1194. X             */
  1195. X            geomask = XParseGeometry(argv[++i], &size_hints.x,
  1196. X            &size_hints.y, (unsigned *)&size_hints.width,
  1197. X            (unsigned *)&size_hints.height);
  1198. X            if (size_hints.width<DEFAULT_SIZE) size_hints.width=DEFAULT_SIZE;
  1199. X            if (size_hints.height<DEFAULT_SIZE) size_hints.height=DEFAULT_SIZE;
  1200. X            if (geomask & XNegative)
  1201. X            size_hints.x += WidthOfScreen(ScreenOfDisplay(display,screen_num))
  1202. X             - size_hints.width;
  1203. X            if (geomask & YNegative)
  1204. X            size_hints.y += HeightOfScreen(ScreenOfDisplay(display,screen_num))
  1205. X             - size_hints.height;
  1206. X            if (geomask & (XValue | YValue))
  1207. X            size_hints.flags |= USPosition;
  1208. X            if ((geomask & XNegative) && (geomask & YNegative))
  1209. X            size_hints.win_gravity = SouthEastGravity;
  1210. X            else if (geomask & XNegative)
  1211. X            size_hints.win_gravity = NorthEastGravity;
  1212. X            else if (geomask & YNegative)
  1213. X            size_hints.win_gravity = SouthWestGravity;
  1214. X        }
  1215. X
  1216. X        else if (!strcmp(argv[i],"-background") || !strcmp(argv[i],"-bg")) {
  1217. X            if (!XAllocNamedColor(display, DefaultColormap(display, screen_num),
  1218. X            argv[++i], &background,&exact))
  1219. X                fprintf(stderr,"Could not allocated color %s\n",argv[i]);
  1220. X        }
  1221. X        else if (!strcmp(argv[i],"-foreground") || !strcmp(argv[i],"-fg"))  {
  1222. X            if (!XAllocNamedColor(display, DefaultColormap(display, screen_num),
  1223. X            argv[++i], &foreground,&exact))
  1224. X                fprintf(stderr,"Could not allocated color %s\n",argv[i]);
  1225. X        }
  1226. X        else if (!strcmp(argv[i],"-sample")) {
  1227. X            sleep_time = atoi(argv[++i]);
  1228. X            if (sleep_time < 1)
  1229. X                usage();
  1230. X        }
  1231. X        else if (!strcmp(argv[i],"-baseline"))  {
  1232. X            if (!XAllocNamedColor(display, DefaultColormap(display, screen_num),
  1233. X            argv[++i], &baseline,&exact))
  1234. X                fprintf(stderr,"Could not allocated color %s\n",argv[i]);
  1235. X            else draw_baseline = TRUE;
  1236. X        }
  1237. X        else if (!strcmp(argv[i],"-type")) {
  1238. X            set_up_graph(argv[++i]);
  1239. X        }
  1240. X        else if (!strcmp(argv[i],"-color")) {
  1241. X            if (!XAllocNamedColor(display, DefaultColormap(display, screen_num),
  1242. X            argv[++i], &screen_def,&exact))
  1243. X                fprintf(stderr,"Could not allocated color %s\n",argv[i]);
  1244. X            else {
  1245. X            if (!num_graphs) {
  1246. X                fprintf(stderr,"No graphs have been specified");
  1247. X                exit(1);
  1248. X            }
  1249. X            else
  1250. X                graphs[num_graphs-1].color_pixel =
  1251. X                    screen_def.pixel;
  1252. X            }
  1253. X        }
  1254. X        else if (!strcmp(argv[i],"-min")) {
  1255. X            if (!num_graphs) {
  1256. X                fprintf(stderr, "No graphs have been specified\n");
  1257. X                exit(1);
  1258. X            }
  1259. X            else {
  1260. X                graphs[num_graphs-1].min_scale = atoi(argv[++i]);
  1261. X                if (graphs[num_graphs-1].min_scale < 2)
  1262. X                    graphs[num_graphs-1].min_scale = 2;
  1263. X            }
  1264. X        }
  1265. X        else if (!strcmp(argv[i],"-max")) {
  1266. X            if (!num_graphs) {
  1267. X                fprintf(stderr, "No graphs have been specified\n");
  1268. X                exit(1);
  1269. X            }
  1270. X            else {
  1271. X                graphs[num_graphs-1].max_scale = atoi(argv[++i]);
  1272. X                if (graphs[num_graphs-1].max_scale < graphs[num_graphs-1].min_scale)
  1273. X                    graphs[num_graphs-1].max_scale =
  1274. X                        graphs[num_graphs-1].min_scale;
  1275. X            }
  1276. X        }
  1277. X        else if (!strcmp(argv[i],"-host")) {
  1278. X            if (!num_graphs) {
  1279. X            fprintf(stderr, "No graphs have been specified\n");
  1280. X            exit(1);
  1281. X            }
  1282. X            else {
  1283. X            i++;
  1284. X            if (!num_hosts) {
  1285. X                hosts = (char **) malloc(sizeof(char *));
  1286. X                hosts[0] = argv[i];
  1287. X                
  1288. X                graphs[num_graphs-1].host_offset = 0;
  1289. X                num_hosts++;
  1290. X            }
  1291. X            else {
  1292. X                int s;
  1293. X
  1294. X                for (s=0; s<num_hosts; ++s)
  1295. X                    if (!strcmp(hosts[s],argv[i])) break;
  1296. X                if (s==num_hosts) {
  1297. X                    hosts =(char**)realloc(hosts, (num_hosts+1) * sizeof(char *));
  1298. X                    hosts[num_hosts++] = argv[i];
  1299. X                }
  1300. X                graphs[num_graphs-1].host_offset = s;
  1301. X            }
  1302. X            }
  1303. X        }
  1304. X        else if (!strcmp(argv[i],"-samescale")) {
  1305. X            scale_sync = TRUE;
  1306. X        }
  1307. X        else if (!strcmp(argv[i],"-allnames")) {
  1308. X            allnames = TRUE;
  1309. X        }
  1310. X        else if (!strcmp(argv[i],"-hidelabels")) {
  1311. X            hide_labels = TRUE;
  1312. X        }
  1313. X        else if (!strcmp(argv[i], "-scale")) {
  1314. X            if (!num_graphs) {
  1315. X                fprintf(stderr, "No graphs have been specified\n");
  1316. X                exit(1);
  1317. X            }
  1318. X            else {
  1319. X                graphs[num_graphs-1].scale_lines = atoi(argv[++i]);
  1320. X            }
  1321. X        }
  1322. X        else usage();
  1323. X        i++;
  1324. X    }
  1325. X}
  1326. X
  1327. X
  1328. X
  1329. Xvoid main( argc, argv )
  1330. X    int             argc;
  1331. X    char           *argv[];
  1332. X
  1333. X{
  1334. X    XGCValues    xgcvalues;
  1335. X    XWMHints    wm_hints;
  1336. X    XClassHint    class_hints;
  1337. X    XTextProperty    window_name;
  1338. X    XSetWindowAttributes    window_attributes;
  1339. X    int        i;
  1340. X    char        *disp="",*prog_name=VERSION;
  1341. X
  1342. X    /* localhost needs to be static because we set a pointer to it. */
  1343. X    static char    localhostname[MAXHOSTNAMELEN];
  1344. X
  1345. X    if (argc==1) usage();
  1346. X
  1347. X    /* Find the display (and screen number) first.  Once we have that
  1348. X     * information, we can process the other arguements better as
  1349. X     * we read them.
  1350. X     */
  1351. X
  1352. X    for (i=1; i<(argc-1); i++)
  1353. X        if (!strcmp(argv[i],"-display")) {
  1354. X        disp = argv[i+1];
  1355. X        break;
  1356. X        }
  1357. X    if ((display=XOpenDisplay(disp))==NULL) {
  1358. X        fprintf(stderr, "Unable to open display: %s\n",
  1359. X            XDisplayName(disp));
  1360. X        exit(1);
  1361. X    }
  1362. X    screen_num = DefaultScreen(display);
  1363. X
  1364. X    whitepixel = WhitePixel(display, screen_num);
  1365. X    blackpixel = BlackPixel(display, screen_num);
  1366. X
  1367. X    foreground.pixel = blackpixel;
  1368. X    foreground.red = foreground.blue = foreground.green = 0;
  1369. X    background.pixel = whitepixel;
  1370. X    background.red = foreground.blue = foreground.green = 65535;
  1371. X    parse_args(argc, argv);
  1372. X
  1373. X    if (!num_graphs) {
  1374. X        fprintf(stderr,"At least one graph type needs to be specified\n");
  1375. X        exit(1);
  1376. X    }
  1377. X
  1378. X
  1379. X/* Following sets up the graphs where a hostname was not specified.  First
  1380. X * find out if the local host was specified for at least one graph.
  1381. X * Then, go through the graph types.  If there are graphs in which a
  1382. X * host has not been specified, then set it the localhost, and allocate
  1383. X * the space for it, if that is required.
  1384. X */
  1385. X
  1386. X    gethostname(localhostname, MAXHOSTNAMELEN);
  1387. X    for (i=0; i<num_hosts; i++) {
  1388. X        if (!strcmp(hosts[i],localhostname)) {
  1389. X            localhost = i;
  1390. X            break;
  1391. X        }
  1392. X    }
  1393. X    for (i=0; i<num_graphs; i++) {
  1394. X        if (graphs[i].host_offset == -1) {
  1395. X            if (localhost==-1) {
  1396. X                if (num_hosts==0)
  1397. X                    hosts = (char **)malloc(sizeof(char *));
  1398. X                else 
  1399. X                    hosts=(char**)realloc(hosts, (1+num_hosts) * sizeof(char *));
  1400. X                hosts[num_hosts] = localhostname;
  1401. X                localhost = num_hosts++;
  1402. X            }
  1403. X            graphs[i].host_offset = localhost;
  1404. X        }
  1405. X    }
  1406. X
  1407. X    window_attributes.background_pixel = background.pixel;
  1408. X    window_attributes.backing_store = WhenMapped;
  1409. X    win = XCreateWindow(display, RootWindow(display, screen_num),
  1410. X        size_hints.x, size_hints.y, size_hints.width, size_hints.height,
  1411. X        0, CopyFromParent, InputOutput,  CopyFromParent,
  1412. X        CWBackPixel | CWBackingStore, &window_attributes);
  1413. X
  1414. X    XSelectInput(display, win, StructureNotifyMask | ExposureMask |
  1415. X        KeyPressMask);
  1416. X
  1417. X
  1418. X    if ((font_info = XLoadQueryFont(display, FONT))==NULL) {
  1419. X        fprintf(stderr,"Unable to load font %s\n",FONT);
  1420. X        exit(1);
  1421. X    }
  1422. X    font_height=font_info->max_bounds.ascent +
  1423. X        font_info->max_bounds.descent;
  1424. X
  1425. X    xgcvalues.foreground = foreground.pixel;
  1426. X    xgcvalues.background = background.pixel;
  1427. X    xgcvalues.line_width = 1;
  1428. X    
  1429. X    xgcvalues.graphics_exposures = False;
  1430. X    xgcvalues.font = font_info->fid;
  1431. X
  1432. X    /* create the various graphic contexts we need. gc and gc_color
  1433. X    differ only in the we only change the colors on the gc_color context,
  1434. X    and thus, it is only used for brick drawing.  gc_color really has no
  1435. X    use on a black & white system */
  1436. X
  1437. X    gc = XCreateGC(display, win, GCFont | GCLineWidth |
  1438. X        GCForeground | GCBackground | GCGraphicsExposures, &xgcvalues);
  1439. X
  1440. X    wm_hints.flags = InputHint;
  1441. X    wm_hints.input = False;
  1442. X
  1443. X    class_hints.res_name = "XSysStats";
  1444. X    class_hints.res_class =  "XSysStats";
  1445. X
  1446. X    XStringListToTextProperty(&prog_name, 1, &window_name);
  1447. X    XSetWMProperties(display, win, &window_name, &window_name,
  1448. X        argv,argc, &size_hints, &wm_hints, &class_hints);
  1449. X
  1450. X
  1451. X    XMapWindow(display, win);
  1452. X    XFlush(display);
  1453. X
  1454. X    /* initialize random (used to determine next stage) */
  1455. X    graph_loop();
  1456. X
  1457. X}
  1458. X
  1459. END_OF_FILE
  1460. if test 22822 -ne `wc -c <'xsysstats.c'`; then
  1461.     echo shar: \"'xsysstats.c'\" unpacked with wrong size!
  1462. fi
  1463. # end of 'xsysstats.c'
  1464. fi
  1465. if test -f 'xsysstats.h' -a "${1}" != "-c" ; then 
  1466.   echo shar: Will not clobber existing file \"'xsysstats.h'\"
  1467. else
  1468. echo shar: Extracting \"'xsysstats.h'\" \(2710 characters\)
  1469. sed "s/^X//" >'xsysstats.h' <<'END_OF_FILE'
  1470. X#include <X11/Xlib.h>
  1471. X#include <X11/Xutil.h>
  1472. X#include <stdio.h>
  1473. X#include <sys/param.h>
  1474. X#include <malloc.h>
  1475. X
  1476. X
  1477. X/* Font is a nice small font. */
  1478. X#define FONT "-adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1"
  1479. X#define    DEFAULT_SIZE    64    /* default width & height of the window */
  1480. X#define    TEXT_WIDTH    60    /* How many pixels (width) is the minimum
  1481. X                 * to display the text at the bottom.
  1482. X                 * Number is sort of arbitrarily chosen.
  1483. X                 * It must be less than DEFAULT_SIZE however.
  1484. X                 */
  1485. X#define PTSSCALELINE    5    /* If scale lines (by -scale arguement)
  1486. X                 * are closer than this many pixels together,
  1487. X                 * fewer scale lines are drawn.  If you always
  1488. X                 * want scale lines drawn, even if they are
  1489. X                 * right next to each other, set this to 0.
  1490. X                 * If the lines would be within this range,
  1491. X                 * -scale value is doubled, then quadrapuled,
  1492. X                 * and so on until it it can be drawn properly.
  1493. X                 */
  1494. X
  1495. X#define CPU        0    /* % of cpu being used */
  1496. X#define PACKETS        1    /* average number of incoming packets */
  1497. X#define PAGE        2
  1498. X#define SWAP        3
  1499. X#define INT        4
  1500. X#define DISK        5
  1501. X#define CONTEXT        6
  1502. X#define LOAD1        7    /* LOAD1, LOAD5 and LOAD15 need to be */
  1503. X#define LOAD5        8    /* number consecutively. */
  1504. X#define LOAD15        9
  1505. X#define COLL        10
  1506. X#define ERRORS        11
  1507. X#define NUM_TYPES    11    /* should be the same as the last graph type
  1508. X                 * above
  1509. X                 */
  1510. X#define INSIDE_BORDER_WIDTH    1
  1511. X#define DOWNSCALE_OCCURANCE    30    /* How many ticks between each
  1512. X                     * downscale attempt */
  1513. X#define LOAD_FACTOR 100               /* internal representation of load is
  1514. X                       * this many times bigger */
  1515. X
  1516. X#ifndef TRUE
  1517. X#define TRUE 1
  1518. X#endif
  1519. X#ifndef FALSE
  1520. X#define FALSE 0
  1521. X#endif
  1522. X
  1523. Xstruct graph_info {
  1524. X    int    scale,true_scale;    /* true_scale is the scale that would
  1525. X                     * be used if this graph was not
  1526. X                     * synced with another graph.
  1527. X                     */
  1528. X    unsigned char    type;
  1529. X    unsigned long    color_pixel;
  1530. X    char    name[MAXHOSTNAMELEN + 10];
  1531. X    short    name_len;
  1532. X    int    max_scale;
  1533. X    int    min_scale;
  1534. X    int    scale_mult;        /* How much to multiply the
  1535. X                     * scale by for it to correspond
  1536. X                     * to the point values.  This is used
  1537. X                     * only for load to give good
  1538. X                     * resolution.
  1539. X                     */
  1540. X    int    scale_lines;    /* Dashed horizontal lines.  will be
  1541. X                 * drawn at the value this variable
  1542. X                 * holds.  Ie, if this is 32, and the
  1543. X                 * scale of the graph is 64, there will
  1544. X                 * be 1 line in the center of the window.
  1545. X                 * if the scale is 128, there will be
  1546. X                 * 3 lines, equally spaced.
  1547. X                 */
  1548. X    int    running_avg;    /* use this as a guide for re-sizes */
  1549. X    short    host_offset;
  1550. X} *graphs;
  1551. X
  1552. Xextern int    num_hosts,point_pos,width,num_graphs,**points,sleep_time,
  1553. X    scale_sync,hide_labels;
  1554. Xextern char    **hosts;
  1555. X
  1556. Xvoid set_first_values();
  1557. Xint set_values();
  1558. Xvoid redraw_graph();
  1559. END_OF_FILE
  1560. if test 2710 -ne `wc -c <'xsysstats.h'`; then
  1561.     echo shar: \"'xsysstats.h'\" unpacked with wrong size!
  1562. fi
  1563. # end of 'xsysstats.h'
  1564. fi
  1565. if test -f 'xsysstats.man' -a "${1}" != "-c" ; then 
  1566.   echo shar: Will not clobber existing file \"'xsysstats.man'\"
  1567. else
  1568. echo shar: Extracting \"'xsysstats.man'\" \(6369 characters\)
  1569. sed "s/^X//" >'xsysstats.man' <<'END_OF_FILE'
  1570. X.TH XSysStats 1 "August 26, 1993"
  1571. X.br
  1572. X.SH NAME
  1573. Xxsysstats
  1574. X.SH SYNOPSIS
  1575. X.B xsysstats -type \fItype\fR -geometry \fIgeometry\fR
  1576. X-display \fIdisplay\fR
  1577. X-background \fIcolor\fR -baseline \fIcolor\fR -color \fIcolor\fR 
  1578. X-foreground \fIcolor\fR -host \fIhostname\fR -min \fImin\fR 
  1579. X-max \fImax\fR -sample \fIsample_time\fR -allnames -samescale
  1580. X-hidelabels -scale \fIvalue\fR
  1581. X
  1582. X.SH DESCRIPTION
  1583. XXSysStats is a tool to show various system statistics.  It shows them in
  1584. Xthe form of a strip graph in a window.
  1585. X
  1586. XIt can show multiple graphs in one window, and the graphs can be
  1587. Xdetailing information about several machines.
  1588. X
  1589. XAt the bottom of the window, what graph types and their scale is displayed.
  1590. XThese are displayed in the color of the graph.
  1591. X
  1592. XWhile XSysStats is running, graphs will be downscaled and upscaled
  1593. Xas require.  And upscale doubles the graph scale, and only occurs when
  1594. Xa new point is beyond the graph bounds.
  1595. X
  1596. XDownscaling occurs when the running average falls below the scale, and
  1597. Xall points on the graph are less than half the present scale.  Downscaling
  1598. Xhalves the scale of the graph.
  1599. X
  1600. XUpscaling and Downscaling by default do not occur on graphs of cpu time.
  1601. XScaling can further be controlled by the -min and -max arguments.
  1602. X
  1603. XA black and white display system will not likely be able to make much sense
  1604. Xof multiple graphs in the same window.  However, several xsysstats
  1605. Xprograms could be run, each detailing a different statistic.
  1606. X
  1607. X.SH COMMAND LINE OPTIONS
  1608. XNote: unlike many programs, the order the command line arguments are
  1609. Xgiven in is relevant.  The -host, -color, -min and -max operate on the last
  1610. X-type argument given.  Only graphs specified given after -foreground
  1611. Xwill inherit that color.  Also, at least one -type arguements needs to be
  1612. Xsupplied before -host, -color, -min or -max can be used, otherwise an
  1613. Xerror will result.
  1614. X.TP 8
  1615. X-type \fItype\fR
  1616. XThis is the type of graph to display. The types are:
  1617. X
  1618. Xcollisions: number of incoming ethernet collisions since last update
  1619. X
  1620. Xcontext: number of context switches per second
  1621. X
  1622. Xcpu: percentage of cpu time being used
  1623. X
  1624. Xdisk: number of disk transfers per second
  1625. X
  1626. Xerrors: number of incoming ethernet errors since last update
  1627. X
  1628. Xinterrupts: average number of device interrupts, per second
  1629. X
  1630. Xload1, load5, load15: The average number of jobs in the load queue for the
  1631. Xlast 1, 5, and 15 minutes.
  1632. X
  1633. Xpackets: number of incoming ethernet packets per second
  1634. X
  1635. Xpage: page ins since last update
  1636. X
  1637. Xswap: swap ins since last update
  1638. X
  1639. XMultiple graphs are selected by specifying multiple -type arguments.
  1640. XThe graphs are graphed in the order of the -type arguments.  This means
  1641. Xthat the first -type graph given will be drawn first, which means it
  1642. Xcan be overwritten with graph data from later graphs.  The graph
  1643. Xwhich you want to see most clearly should be the last -type argument.
  1644. X.TP
  1645. X-geometry \fIgeometry\fR
  1646. XThe geometry of the window.
  1647. X.TP
  1648. X-display \fIdisplay\fR
  1649. Xwhat screen/system to display the window on.
  1650. X.TP
  1651. X-background \fIcolor\fR
  1652. Xbackground color of the window.
  1653. X.TP
  1654. X-baseline \fIcolor\fR
  1655. Xthis tells XSysStats to draw a baseline of color \fIcolor\fR.  The baseline
  1656. Xis a zero line, the minimum value any graph can have.
  1657. X.TP
  1658. X-color \fIcolor\fR
  1659. Xthis sets the color of the last graph specified with the -type argument.
  1660. X.TP
  1661. X-foreground \fIcolor\fR
  1662. Xthis sets the default foreground color.  Any graphs specified after
  1663. Xthis argument in which a -color argument
  1664. Xis not set for it will have this color.
  1665. X.TP
  1666. X-host \fIhost\fR
  1667. Xthis specifies the host to report information on.  It applies to the last
  1668. X-type argument given.  There is no checking done to see if this is a valid
  1669. Xhost.  If no hosts exists with the \fIhost\fR name, then the graph for
  1670. Xwhich this host applied will not be graphed in any reasonable fashion.
  1671. X.TP
  1672. X-min \fImin\fR
  1673. Xthis is the minimum value the last graph specified by -type will downscale to.
  1674. X.TP
  1675. X-max \fImax\fR
  1676. Xthis is the maximum value the graph specified by -type will scale to.
  1677. XIf points are beyond
  1678. Xthis scale, they will be drawn out of bounds.
  1679. X
  1680. XIf both min and max are the same, the graph will never change scale.  By
  1681. Xdefault, most graphs have a min value of 2 and a very large max value.
  1682. XThe cpu graph is the one exception, both its min and max value is 100.
  1683. X.TP
  1684. X-sample \fIsample_time\fR
  1685. XThis is how long the program sleeps between each update.  The minimum
  1686. Xvalue is 1.  By default, it is 2.
  1687. X.TP
  1688. X-allnames
  1689. XThis forces the hostname for all hosts to be displayed along with the
  1690. Xgraph type at the bottom of the window, including the localhost.
  1691. X.TP
  1692. X-samescale
  1693. XGraphs of similar type will always have the same scale.  This can be useful
  1694. Xif the same -type is being used to graph information on multiple hosts.  It
  1695. Xallows for easy comparison of the graph data.
  1696. X.TP
  1697. X-hidelabels
  1698. XPrevent all graph labels and scale from being drawn at the bottom of the screen.
  1699. XMakes better use of space.  Limited use if you need to know the scale of
  1700. Xthe graph and the graphs scale changes.  Certain keys can toggle the labels
  1701. Xon or off while running.  See the section below on KEYBOARD CONTROL
  1702. Xfor more information.
  1703. X.TP
  1704. X-scale \fIvalue\fR
  1705. XCauses dotted horizontal scale lines every \fIvalue\fR points on the graph.
  1706. XThus, if \fIvalue\fR is 32 and the scale of the graph is 64, a dotted
  1707. Xline will be drawn in the middle of the window.  This operates on the
  1708. Xlast -type arguement given.  If scale lines become too close together
  1709. Xin the window, \fIvalue\fR will doubled until the lines are adequately
  1710. Xspread out.  The threshold value is about 5 pixels.  If two of these
  1711. Xlines would be drawn closer together than that, the doubling will
  1712. Xoccur.  The value of the lines are not drawn anyplace in the window.
  1713. X
  1714. X.SH X DEFAULTS
  1715. XXSysStats does not support any standard resource values.  This is based
  1716. Xsome on ease of programming and on usefulness of having resources.
  1717. X
  1718. XIt seems to me that very seldom will people want to have XSysStats run
  1719. Xwith all the same resources more than once.  If X Defaults were supported,
  1720. Xthen there would also need to be a way not to use them.
  1721. X
  1722. X.SH KEYBOARD CONTROL
  1723. XWhile XSysStats is running, the following keys will cause various
  1724. Xevents to happen:
  1725. X.TP
  1726. Xl,L: This will toggle the labels on or off.  This is the same behaviour
  1727. Xas the -hidelabels command line option.
  1728. X
  1729. X.SH BUGS
  1730. XValid host name checking should be done when the -host argument
  1731. Xis specified.
  1732. X
  1733. XTimeouts of rstat on remote hosts will pretty much stop all the graphs.
  1734. END_OF_FILE
  1735. if test 6369 -ne `wc -c <'xsysstats.man'`; then
  1736.     echo shar: \"'xsysstats.man'\" unpacked with wrong size!
  1737. fi
  1738. # end of 'xsysstats.man'
  1739. fi
  1740. echo shar: End of shell archive.
  1741. exit 0
  1742.  
  1743.    Mark Wedel
  1744. master@rahul.net
  1745.  
  1746. exit 0 # Just in case...
  1747. -- 
  1748.   // chris@Sterling.COM           | Send comp.sources.x submissions to:
  1749. \X/  Amiga - The only way to fly! |    sources-x@sterling.com
  1750.  "It's intuitively obvious to the |
  1751.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  1752.