home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-12-19 | 57.0 KB | 2,264 lines |
- Newsgroups: comp.sources.misc
- From: fitz@rpi.edu (Brian P. Fitzgerald)
- Subject: v41i040: rperf - performance monitoring of network hosts, v3.1, Part02/04
- Message-ID: <1993Dec19.205254.28433@sparky.sterling.com>
- X-Md4-Signature: 95bc25c2dbb48827cd63845ed5a00528
- Sender: kent@sparky.sterling.com (Kent Landfield)
- Organization: Rensselaer Polytechnic Institute, Troy NY
- Date: Sun, 19 Dec 1993 20:52:54 GMT
- Approved: kent@sparky.sterling.com
-
- Submitted-by: fitz@rpi.edu (Brian P. Fitzgerald)
- Posting-number: Volume 41, Issue 40
- Archive-name: rperf/part02
- Environment: UNIX
- Supersedes: rperf: Volume 39, Issue 69-71
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. The tool that generated this
- # shell archive is called "shar", and is available by anonymous ftp
- # from ftp.uu.net in subdirectory /usenet/comp.sources.unix, and from many
- # other places. Check 'archie' for the latest locations. If this archive
- # is complete, you will see the following message at the end:
- # "End of archive 2 (of 4)."
- # Contents: rstat_xdr.c rstat_xdr.ed rperf.8 rperf.h term.c rpc.c
- # common.h strdup.c hsearch.h
- # Wrapped by fitzgb@mml0.meche.rpi.edu on Wed Dec 15 13:06:54 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'rstat_xdr.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rstat_xdr.c'\"
- else
- echo shar: Extracting \"'rstat_xdr.c'\" \(5383 characters\)
- sed "s/^X//" >'rstat_xdr.c' <<'END_OF_FILE'
- X#include <stdio.h>
- X/*
- X * Please do not edit this file.
- X * It was generated using rpcgen.
- X */
- X
- X#include <rpc/rpc.h>
- X#include "rstat.h"
- Xextern int if_opackets_fixed;
- X
- Xbool_t
- Xxdr_rstat_timeval(xdrs, objp)
- X XDR *xdrs;
- X rstat_timeval *objp;
- X{
- X if (!xdr_u_int(xdrs, &objp->tv_sec)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->tv_usec)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- Xbool_t
- Xxdr_statsvar(xdrs, objp)
- X XDR *xdrs;
- X statsvar *objp;
- X{
- X if (!xdr_array(xdrs, (char **)&objp->cp_time.cp_time_val, (u_int *)&objp->cp_time.cp_time_len, ~0, sizeof(int), xdr_int)) {
- X return (FALSE);
- X }
- X if (!xdr_array(xdrs, (char **)&objp->dk_xfer.dk_xfer_val, (u_int *)&objp->dk_xfer.dk_xfer_len, ~0, sizeof(int), xdr_int)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_pgpgin)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_pgpgout)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_pswpin)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_pswpout)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_intr)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_ipackets)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_ierrors)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_opackets)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_oerrors)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_collisions)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_swtch)) {
- X return (FALSE);
- X }
- X if (!xdr_vector(xdrs, (char *)objp->avenrun, 3, sizeof(long), xdr_long)) {
- X return (FALSE);
- X }
- X if (!xdr_rstat_timeval(xdrs, &objp->boottime)) {
- X return (FALSE);
- X }
- X if (!xdr_rstat_timeval(xdrs, &objp->curtime)) {
- X return (FALSE);
- X }
- X return (TRUE);
- X}
- X
- Xbool_t
- Xxdr_statstime(xdrs, objp)
- X XDR *xdrs;
- X statstime *objp;
- X{
- X if (!xdr_vector(xdrs, (char *)objp->cp_time, CPUSTATES, sizeof(int), xdr_int)) {
- X return (FALSE);
- X }
- X if (!xdr_vector(xdrs, (char *)objp->dk_xfer, DK_NDRIVE, sizeof(int), xdr_int)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_pgpgin)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_pgpgout)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_pswpin)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_pswpout)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_intr)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_ipackets)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_ierrors)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_oerrors)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_collisions)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_swtch)) {
- X return (FALSE);
- X }
- X if (!xdr_vector(xdrs, (char *)objp->avenrun, 3, sizeof(int), xdr_int)) {
- X return (FALSE);
- X }
- X if (!xdr_rstat_timeval(xdrs, &objp->boottime)) {
- X return (FALSE);
- X }
- X if (!xdr_rstat_timeval(xdrs, &objp->curtime)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_opackets)) {
- X /**
- X * workaround for servers that
- X * do not report if_opackets
- X **/
- X if_opackets_fixed = 0;
- X objp->if_opackets = 0;
- X /* return (FALSE); */
- X }
- X return (TRUE);
- X}
- X
- Xbool_t
- Xxdr_statsswtch(xdrs, objp)
- X XDR *xdrs;
- X statsswtch *objp;
- X{
- X if (!xdr_vector(xdrs, (char *)objp->cp_time, CPUSTATES, sizeof(int), xdr_int)) {
- X return (FALSE);
- X }
- X if (!xdr_vector(xdrs, (char *)objp->dk_xfer, DK_NDRIVE, sizeof(int), xdr_int)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_pgpgin)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_pgpgout)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_pswpin)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_pswpout)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_intr)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_ipackets)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_ierrors)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_oerrors)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_collisions)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_swtch)) {
- X return (FALSE);
- X }
- X if (!xdr_vector(xdrs, (char *)objp->avenrun, 3, sizeof(u_int), xdr_u_int)) {
- X return (FALSE);
- X }
- X if (!xdr_rstat_timeval(xdrs, &objp->boottime)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_opackets)) {
- X /**
- X * workaround for servers that
- X * do not report if_opackets
- X **/
- X if_opackets_fixed = 0;
- X objp->if_opackets = 0;
- X /* return (FALSE); */
- X }
- X return (TRUE);
- X}
- X
- Xbool_t
- Xxdr_stats(xdrs, objp)
- X XDR *xdrs;
- X stats *objp;
- X{
- X if (!xdr_vector(xdrs, (char *)objp->cp_time, CPUSTATES, sizeof(int), xdr_int)) {
- X return (FALSE);
- X }
- X if (!xdr_vector(xdrs, (char *)objp->dk_xfer, DK_NDRIVE, sizeof(int), xdr_int)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_pgpgin)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_pgpgout)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_pswpin)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_pswpout)) {
- X return (FALSE);
- X }
- X if (!xdr_u_int(xdrs, &objp->v_intr)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_ipackets)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_ierrors)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_oerrors)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_collisions)) {
- X return (FALSE);
- X }
- X if (!xdr_int(xdrs, &objp->if_opackets)) {
- X /**
- X * workaround for servers that
- X * do not report if_opackets
- X **/
- X if_opackets_fixed = 0;
- X objp->if_opackets = 0;
- X /* return (FALSE); */
- X }
- X return (TRUE);
- X}
- END_OF_FILE
- if test 5383 -ne `wc -c <'rstat_xdr.c'`; then
- echo shar: \"'rstat_xdr.c'\" unpacked with wrong size!
- fi
- # end of 'rstat_xdr.c'
- fi
- if test -f 'rstat_xdr.ed' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rstat_xdr.ed'\"
- else
- echo shar: Extracting \"'rstat_xdr.ed'\" \(611 characters\)
- sed "s/^X//" >'rstat_xdr.ed' <<'END_OF_FILE'
- X/rstat.h/a
- Xextern int if_opackets_fixed;
- X.
- X/^xdr_statstime(/g\
- X/if_opackets/+1c
- X /**
- X * workaround for servers that
- X * do not report if_opackets
- X **/
- X if_opackets_fixed = 0;
- X objp->if_opackets = 0;
- X /* return (FALSE); */
- X.
- X/^xdr_statsswtch(/g\
- X/if_opackets/+1c
- X /**
- X * workaround for servers that
- X * do not report if_opackets
- X **/
- X if_opackets_fixed = 0;
- X objp->if_opackets = 0;
- X /* return (FALSE); */
- X.
- X/^xdr_stats(/g\
- X/if_opackets/+1c
- X /**
- X * workaround for servers that
- X * do not report if_opackets
- X **/
- X if_opackets_fixed = 0;
- X objp->if_opackets = 0;
- X /* return (FALSE); */
- X.
- Xw
- Xq
- END_OF_FILE
- if test 611 -ne `wc -c <'rstat_xdr.ed'`; then
- echo shar: \"'rstat_xdr.ed'\" unpacked with wrong size!
- fi
- # end of 'rstat_xdr.ed'
- fi
- if test -f 'rperf.8' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rperf.8'\"
- else
- echo shar: Extracting \"'rperf.8'\" \(12408 characters\)
- sed "s/^X//" >'rperf.8' <<'END_OF_FILE'
- X.\" t
- X.\" This program may be copied, redistributed in any form, source or
- X.\" binary, and used for any purpose, provided this copyright notice is
- X.\" retained.
- X.\"
- X.\" @(#)rperf.8 3.1 12/15/93 (c) Copyright Brian P. Fitzgerald
- X.\" Rensselaer Polytechnic Institute
- X.\"
- X.\"
- X.\" format this man page with:
- X.\" tbl rperf.8 | nroff -man
- X.\" tbl rperf.8 | troff -man
- X.\"
- X.\"
- X.TH RPERF 8 "8 May 1992"
- X.SH NAME
- Xrperf \- report statistics from network hosts
- X.SH SYNOPSIS
- X.B rperf
- X.RB [\ -aAcdivhnSTsbu1234BDrN?\ ]
- X.RI [\ interval
- X.RI [\ count\ ]]
- X.RI [\ +sortkey\ ]
- X.RI [\ host\ ...\ ]
- X
- X.B rup
- X.RB [\ \-hltnD\ ]
- X.RI [\ interval\ ]
- X.RI [\ host\ ...\ ]
- X.SH DESCRIPTION
- X.IX "rperf command" "" "\fLrperf\fP \(em report statistics from network hosts"
- X.B rperf
- Xobtains system statistics from network hosts and prints them to the
- Xstandard output at regular intervals.
- X.B rperf
- Xis similar to xmeter, or SunView perfmeter, but is intended for use on
- Xascii terminals, or for logging.
- X.LP
- XWithout options,
- X.B rperf
- Xbroadcasts to the local network,
- Xprints the uptime for each host that responds, then displays kernel statistics
- Xfor these hosts at 10 second intervals until the program is terminated. If
- X.I interval
- Xis specified,
- X.B rperf
- Xsummarizes activity every
- X.I interval
- Xseconds.
- X.I Interval
- Xmust be a positive integer.
- X.B rperf
- Xalways broadcasts for at least 4 seconds per version of rstatd. By
- Xdefault,
- X.B rperf
- Xbroadcasts using versions 4 and 3 of rstatd.
- XIf a
- X.I count
- Xis given, the statistics are repeated
- X.I count
- Xtimes. If the
- X.I count
- Xis given as zero, rperf displays the hostname,
- Xuptime and load average
- Xand then exits.
- XIf one or more
- X.I hosts
- Xare specified,
- X.B rperf
- Xqueries those hosts.
- X.LP
- XWhile receiving replies,
- X.B rperf
- Xindicates its progress by printing characters on the display as follows:
- X.TS
- Xl l .
- X+ added a new host to the list
- X\. received reply from host already on the list
- Xx deleted host from the list due to an error
- X.TE
- X.LP
- XIf invoked as
- X.B rup,
- Xthe program prints the hostname, uptime, and the
- Xload average once, and exits.
- X.SH OPTIONS
- X.TP
- X.B \-c
- X.SM CPU.
- XReport percent utilization of cpu time (user, nice, system, and idle),
- Xsimilar to
- X.B vmstat.
- XFor computers with multiple processors, the average
- Xcpu time and load average among all processors is shown.
- Xrpc.rstatd on
- Xprocessors with more than four cpu states may merge the cpustates
- Xin an implementation-defined way.
- X.\"
- X.\" Thanks Colin Wynd <colin@hpwrc03.mayfield.hp.com>
- XFor example, on an hp9000/800 with multiple cpu's,
- X"sys" represents cp_sys + cp_block + cp_swait + cp_intr + cp_ssys
- Xand
- X"idle" represents cp_idle + cp_wait.
- X.\"
- XFuture versions of rpc.rstatd may report the values individually.
- XAlso, the average number of processes in the run queue (load average) over
- Xthe past 1, 5, and 15 minutes is displayed, a` la
- X.B rup.
- X.TP
- X.B \-d
- XNumber of completed disk transfers per second.
- XReport operations on disks sd0
- Xthrough sd3, similar to
- X.B vmstat.
- XReport on additional disks if they are reported by the
- Xremote host being monitored (available from machines running
- Xversion 4 of the rpc.rstatd protocol.)
- XIt is assumed that the disks are numbered sequentially
- Xfrom zero.
- X.B rperf
- Xhas no way to determine the actual device number on the remote host.
- X.TP
- X.B \-i
- XNetwork interface activity, in events per second. Report incoming and
- Xoutgoing packets transferred, errors, and collisions; similar to
- X.B netstat.
- X.TP
- X.B \-v
- XVirtual memory activity, in events per second. Report pages paged
- Xin/out, pages swapped in/out, context switches, and device
- X(non-clock) interrupts; similar
- Xto
- X.B vmstat.
- X.TP
- X.B \-a
- XAll. Report all of the above.
- X.RB ( \-a
- Xis the default if only one host is monitored.)
- X.TP
- X.B \-u
- Xuptime. Report uptime in every data display.
- X.LP
- XIf more than one host is monitored, but no option flags are specified,
- Xeach hostname is printed at left, and the disk activity report is
- Xomitted, but this can be overridden by specifying options on the
- Xcommand line.
- X.LP
- XIf the standard output is attached to a terminal, the screen is cleared
- Xbefore each display, and as many lines of data that will fit on the
- Xscreen are shown, but this can be overridden with the -N option,
- Xdescribed below.
- XThe default display looks like:
- X.in 0
- X.nf
- Xbroadcasting +++++++++++++++++++....................
- Xmaxwell.ecse up 6 days, 14:13, load average: 0.69 0.73 0.83
- X ozone.meche up 15 days, 9:13, load average: 0.06 0.01 0.00
- X mml0.meche up 4 days, 2:18, load average: 0.12 0.41 0.26
- X\&...
- X %cpu loadavg (nrun) pg pg sw sw cx in i i o o co
- X host us ni sy id 1m 5m 15m in o in o sw tr pk er pk er ll
- Xmaxwell.ecse 9 0 15 77 1.0 0.8 0.9 0 0 0 0 59 68 20 0 19 0 0
- X ozone.meche 0 0 0 100 0.0 0.0 0.0 0 0 0 0 4 2 1 - 0 - 0
- X mml0.meche 2 6 6 86 0.1 0.4 0.2 0 0 0 0 13 6 4 - 2 - 0
- X\&...
- X.fi
- X.LP
- XThe '-' character means that there have been zero events since boot time,
- Xor that the remote host is not configured to report that statistic.
- X.LP
- XHere is an explanation of the field headings:
- X.TS
- Xl l.
- Xus percent cpu time in non-niced user processes
- Xni percent cpu time in niced user processes
- Xsy percent cpu time in system calls
- Xid percent cpu time idle
- X1m 1 minute load average
- X5m 5 minute load average
- X15m 15 minute load average
- X.TE
- X
- Xvirtual memory statistics (per second):
- X.TS
- Xl l.
- Xpgin pages paged in
- Xpgo pages paged out
- Xswin pages swapped in
- Xswo pages swapped out
- Xcxsw context switches
- Xintr device (non-clock) interrupts
- X.TE
- X
- Xnetwork interface statistics (summary, all interfaces), per second:
- X.TS
- Xl l.
- Xipk incoming packets
- Xier errors for incoming packets
- Xopk outgoing packets
- Xoer errors for outgoing packets
- Xcoll collisions
- X.TE
- X.LP
- XAlso, d0, d1, d2 ... (not shown above) are the completed disk transfers per second for each disk.
- XA '-' character in the disk display usually indicates the absence of a disk.
- X.SS Additional Options
- X.TP
- X.B \-n
- XDo not resolve host names. Print the internet address instead. The
- X.B \-n
- Xoption can save time and cut network load by eliminating name
- Xservice lookups.
- X.TP
- X.B \-h
- XSort by hostname. By default,
- X.B rperf
- Xsorts by address.
- X.TP
- X.B +sortkey
- XSort the output by this field in descending order
- X(highest value first).
- XMany abbreviations are recognized.
- XThe sort keys are:
- X
- X.TS
- Xl l l l l l.
- Xloadavg user pgpgin disk0 boottime ipackets
- Xav1 nice pgpgout disk1 uptime ierrors
- Xav5 sys pswpin disk2 curtime oerrors
- Xav15 idle pswpout disk3 opackets
- X intr collisions
- X swtch
- X.TE
- XFor example,
- X.I rperf -au +uptime
- Xis sorted by uptime, with the remote host with the longest uptime displayed
- Xfirst.
- X.I rperf -au +boottime
- Xis sorted by boot time, with the latest boot time displayed first.
- X.TP
- X.B \-r
- XSort in ascending order, lowest value first.
- X.SS Time Format Options
- X.LP
- XThe following options are useful for time stamping the output data.
- X.TP
- X.B \-S
- XSeconds since 00:00 Jan 1, 1970, GMT (Unix time)
- Xon the machine running
- X.B rperf.
- XThis format is
- Xappropriate if the time value is to be used for further analysis or
- Xdisplay plotting.
- X.TP
- X.B \-T
- XDate and local time on the remote machine monitored by
- X.B rperf.
- X.TP
- X.B \-s
- XElapsed run time of
- X.B rperf,
- Xin seconds.
- X.TP
- X.B \-A
- XEquivalent to the
- X.B \-a
- Xoption, and
- X.B \-STsu
- X.SS Miscellaneous Options
- X.TP
- X.B \-N
- XNever clear the screen. Display the data for all hosts, allowing
- Xthe data to scroll up the screen, if necessary.
- X.TP
- X.B \-B
- XBare. Do not print headers or uptime data.
- X.B \-B
- Ximplies
- X.B \-N.
- X.TP
- X.B \-b
- XBroadcast continuously. In broadcast mode without this option,
- X.B rperf
- Xbroadcasts to the local network once, and from then on calls the hosts
- Xthat responded. With the -b option,
- X.B rperf
- Xbroadcasts continuously.
- XSome remote hosts do not reply to every broadcast.
- XWhen a host that had previously replied fails to reply
- Xto a broadcast,
- X.B rperf
- Xattempts to create a client handle and call the
- Xremote host directly. For this reason, you may notice
- Xthat during the first few cycles of operation
- Xwith the
- X.B \-b option,
- X.B rperf's
- Xmemory usage will continue to grow slightly from its value after
- Xcompleting the first pass.
- XContinuous broadcasting is preferable to calling individual hosts
- Xbecause network and system load will be lower. AIX 3.1 users may find that
- Xcontinuous broadcasting will hang the machine.
- X.TP
- X.B \-4, \-3, \-2, -1
- XThe highest rstat version to use. By default,
- Xrperf broadcasts with version 4 (which supports variable number of
- Xdisks), then version 3 (which is found on almost all
- Xreleases of rpc.rstatd).
- XThe
- X.B \-3
- Xoption can save time and reduce network traffic slightly.
- XThe
- X.B \-2
- Xand
- X.B \-1
- Xoptions are useful mainly as diagnostics for
- X.B rpc.rstatd
- Xor
- X.B rperf.
- XBoot time, load average, and context switches are not available
- Xwith version 1. The remote host's local time is not available
- Xwith versions 1 and 2.
- XDue to an error in many rpc.rstatd implementations, if_opackets
- Xis sometimes not available for versions 1, 2 or 3.
- XThe presence of this bug is displayed when
- X.B rperf
- Xis run at debug level 1 or higher.
- X.TP
- X.B \-D
- XDebug level 1.
- X.B \-DD
- XDebug level 2, etc.
- XDisplay diagnostic information.
- X
- XDuring client calls at debug level 2 and higher,
- Xadditional status is displayed by the following characters:
- X.TS
- Xl l .
- X- no clnt_call made. already have data
- Xm made clnt ok
- XM rpc version mismatch
- Xc clnt_call ok
- Xv# rpc version
- X.TE
- X.SS rup options
- X.TP
- X.B \-t
- Xsort by uptime in descending order.
- X.TP
- X.B \-l
- Xsort by (one minute) load average in descending order.
- X.TP
- X.B \-?
- Xhelp. Print a summary of options and sort keys.
- X.TP
- XSee also -h, -n, and -D, above.
- X.SH EXAMPLES
- X.LP
- XUsually just:
- X.LP
- X.B rperf
- X.I host1 host2 ...
- X.LP
- Xor
- X.LP
- X.B rperf -b
- X(continuous broadcast mode)
- X.LP
- X.LP
- XYou can use
- X.B rperf
- Xto log data for later analysis or plotting. For example,
- X.LP
- X.B rperf -sBd 900
- X.I host > file1
- X.LP
- Xstores disk activity statistics on
- X.I host
- Xin a "bare" file (no header) every 15 minutes along with time, in
- Xseconds since
- X.B rperf
- Xwas started. The activity on disk 0 may then be
- Xplotted
- X.I vs.
- Xhours with:
- X.LP
- X.nf
- Xawk \'{print $1/3600, $2}' \fIfile1\fR > \fIfile2\fR
- Xgnuplot
- Xgnuplot> plot \fI'file2'\fR
- X.fi
- X.LP
- XThe command
- X.LP
- X.B rperf
- X-a +system
- X.LP
- Xgives all available statistics for all hosts on the local broadcast
- Xnetwork, sorted by system load, and repeats every 10 seconds.
- X.SH NOTES
- X.LP
- XAll hosts to be monitored with
- X.B rperf
- Xmust be running rpc.rstatd. On some systems,
- Xrstatd is started by uncommenting it from
- X/etc/inetd.conf, and sending the running
- Xinetd process a SIGHUP.
- X.LP
- XIf the output alternates between nonzero numbers and zeros, it is
- Xpossible that rstatd on the remote host samples the kernel over a
- Xlonger interval than you have chosen. Try running
- X.B rperf
- Xwith a longer
- X.I interval.
- X.LP
- XIf a host on the local broadcast network responds to rperf
- Xwhen the hostname is given on the command line (client call),
- Xbut not when
- X.B rperf
- Xis run in broadcast mode, the remote host's
- Xethernet interface netmask
- Xconfiguration may be set incorrectly.
- XOn some systems, the netmask is set with
- X.B ifconfig
- Xin /etc/rc.boot.
- XOn other systems, the relevant configuration
- Xis set in /etc/tcpip.params.
- XYou may be able to check the netmask with "netmask le0"
- X(substitute the actual device for "le0").
- X.LP
- XAlso, a host connected to a smart hub may not be able to broadcast to
- Xother hosts.
- X.SH DIAGNOSTICS
- X.LP
- X.B RPC: Program not registered.
- XThe remote host is not running rstatd.
- XLog in as root on the remote host and startup rpc.rstatd.
- X.LP
- X.B RPC: Remote system error
- X.B - Too many open files.
- X(This error message is misleading because it is
- Xactually a local error.) When
- X.B rperf
- Xstarts up, it increases its open file
- Xdescriptor limit to the maximum allowable, if it can.
- XIt may be that the local
- X.B rperf
- Xprocess still has
- Xtoo many open files because too many hosts were specified,
- Xthat there are too many hosts on the local area net(s)
- Xbeing monitored, or that
- X.B rperf
- Xdoes not know how to increase its
- Xopen file limit on your system. To find out
- Xyour file descriptor limit, type
- X.B % limit descriptors
- Xor
- X.B bash$ ulimit -n
- X.SH AUTHOR
- X.nf
- XBrian P. Fitzgerald
- XMechanics of Materials Laboratory
- XRensselaer Polytechnic Institute
- XTroy, New York
- X.fi
- X
- XSend bug reports and patches to fitz@rpi.edu. Please indicate the
- Xmanufacturer and model of your computer, the name and version of
- Xyour operating system and the version of
- X.B rperf
- Xthat you are using.
- END_OF_FILE
- if test 12408 -ne `wc -c <'rperf.8'`; then
- echo shar: \"'rperf.8'\" unpacked with wrong size!
- fi
- # end of 'rperf.8'
- fi
- if test -f 'rperf.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rperf.h'\"
- else
- echo shar: Extracting \"'rperf.h'\" \(4457 characters\)
- sed "s/^X//" >'rperf.h' <<'END_OF_FILE'
- X/**
- X * This program may be copied, redistributed in any form,
- X * source or binary, and used for any purpose, provided
- X * this copyright notice is retained.
- X * @(#)rperf.h 3.1 12/15/93 (c) Copyright Brian P. Fitzgerald
- X * Rensselaer Polytechnic Institute
- X **/
- X
- X#ifndef PORTMAP
- X#define PORTMAP
- X/**
- X * ... so that for Solaris 2, in <rpc/clnt.h>
- X * we include <rpc/clnt_soc.h>, which declares clntudp_create()
- X**/
- X#endif /* !PORTMAP */
- X/**
- X * <rpc/rpc.h> includes <rpc/types.h>
- X * <rpc/types.h> includes <sys/types.h>
- X * <rpc/types.h> includes <sys/time.h>
- X * <rpc/types.h> ifndef KERNEL includes <malloc.h>
- X * <rpc/rpc.h> includes <netinet/in.h>
- X * (I hope!)
- X**/
- X#include <rpc/rpc.h>
- X#include <rpc/pmap_clnt.h> /* declare clnt_broadcast() */
- X#include "rstat.h"
- X
- X#include <time.h>
- X#include <stdio.h>
- X#include <signal.h>
- X#include <string.h>
- X#include <ctype.h>
- X#include <sys/socket.h>
- X
- X#include <arpa/inet.h>
- X#include <netdb.h>
- X
- X/**
- X * The C library hsearch on some systems is incompatible.
- X * Use the hsearch that came with this package.
- X**/
- X#include "hsearch.h"
- X
- X#ifdef HAVE_SYS_RESOURCE_H
- X#include <sys/resource.h>
- X#endif /* HAVE_SYS_RESOURCE_H */
- X#ifdef RLIMIT_NOFILE
- X#define Rlimit rlimit
- X#else /* !RLIMIT_NOFILE */
- Xstruct Rlimit {
- X int rlim_cur; /* current (soft) limit */
- X int rlim_max; /* maximum value for rlim_cur */
- X};
- X#endif /* !RLIMIT_NOFILE */
- X
- Xtypedef statsvar stats_default;
- X
- X#define STATS_CONVERT(version) (stats_convert[(version)-1])
- X
- X#define EACH_RESULT(version) (each_result_vers[(version)-1])
- X
- X#define XDR_STATSPROC(version) (xdr_statsproc[(version)-1])
- X
- Xunion stats_all {
- X struct stats s1;
- X struct statsswtch s2;
- X struct statstime s3;
- X struct statsvar s4;
- X};
- Xtypedef union stats_all stats_all;
- X
- X/**
- X * the server's rpc.rstatd reports cp_time as clock ticks since boot time
- X * (cumulative), or clock ticks since the previous query (incremental).
- X**/
- Xenum cp_time_kind {
- X CP_TIME_CUM, /* Sun ... */
- X CP_TIME_INC /* IBM ... */
- X};
- Xtypedef enum cp_time_kind cp_time_kind;
- X
- Xstruct hash_info {
- X struct in_addr ident_addr;
- X struct data *datap;
- X};
- Xtypedef struct hash_info hash_info;
- X
- Xstruct data {
- X struct data *datap;
- X u_long nn;
- X u_long no;
- X struct in_addr addr;
- X char *host;
- X char *host_dup;
- X CLIENT *cl;
- X u_long clnt_vers;
- X u_long bcst_vers;
- X u_long ok_to_call;
- X stats_default sn;
- X stats_default so;
- X stats_default sd; /* delta or rate. uptime = sd.boottime */
- X cp_time_kind cp_kind;
- X};
- Xextern struct data *dp;
- X
- Xstruct array {
- X u_int len;
- X int *val;
- X};
- Xtypedef struct array array;
- X
- X/* <sys/dk.h> */
- X#define CP_USER 0
- X#define CP_NICE 1
- X#define CP_SYS 2
- X#define CP_IDLE 3
- X
- X#define cpu(dt) (dcpu ? ((dt) * 100 + hdcpu ) / dcpu : 0)
- X#define loadav(nrun) ( (float) (nrun) / FSCALE )
- X#define delta(x) ((*dpp)->sn.x - (*dpp)->so.x) /* use this macro with care */
- X#define rate(x) (dt ? ((x) * 1000L + hdt ) / dt : 0)
- X
- X#define t_d(j) tbl[(j)].dp->sd
- X#define t_o(j) tbl[(j)].dp->so
- X#define t_n(j) tbl[(j)].dp->sn
- X
- Xstruct key {
- X char *k_name;
- X int k_noffset;
- X int k_doffset;
- X int k_flag;
- X int k_index;
- X};
- Xtypedef struct key key;
- X
- X#define K_DELTA 0x1 /* need delta before sorting */
- X#define K_NZERO 0x2 /* must be nonzero for sorting */
- X#define K_ARRAY 0x4 /* the member is an xdr_array */
- X
- X/* C faq */
- X#ifndef offsetof
- X#define offsetof(type, mem) ((size_t) \
- X ((char *)&((type *) 0)->mem - (char *)((type *) 0)))
- X#endif /* !offsetof */
- X#define sd_offset(mem) offsetof(struct data,sd.mem)
- X#define sn_offset(mem) offsetof(struct data,sn.mem)
- X
- X#define AV1 0
- X#define AV5 1
- X#define AV15 2
- X
- Xstruct datatbl {
- X int val;
- X struct data *dp;
- X};
- X
- X#define P_DATA 0
- X#define P_UP 1
- X
- X#define cp_val cp_time.cp_time_val
- X#define cp_len cp_time.cp_time_len
- X#define dk_val dk_xfer.dk_xfer_val
- X#define dk_len dk_xfer.dk_xfer_len
- X
- X#define MODE_BCST 0 /* no host args were supplied. */
- X#define MODE_CALL 1 /* one or more host args was supplied. */
- Xextern unsigned long mode;
- Xextern unsigned long thiscount;
- Xextern unsigned long nhosts;
- X
- Xstruct data *new_host();
- Xvoid create_array();
- Xvoid destroy_array();
- Xvoid doclnt_calls();
- Xvoid do_broadcast();
- END_OF_FILE
- if test 4457 -ne `wc -c <'rperf.h'`; then
- echo shar: \"'rperf.h'\" unpacked with wrong size!
- fi
- # end of 'rperf.h'
- fi
- if test -f 'term.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'term.c'\"
- else
- echo shar: Extracting \"'term.c'\" \(3424 characters\)
- sed "s/^X//" >'term.c' <<'END_OF_FILE'
- X/**
- X * Derived from screen.c in "top", by Paul Vixie
- X**/
- X#include "common.h"
- X#include <stdio.h>
- X#include <sys/ioctl.h>
- X#ifndef TIOCGWINSZ
- X#ifdef HAVE_SYS_TERMIOS_H
- X#include <sys/termios.h>
- X#else /* !HAVE_SYS_TERMIOS_H */
- X#ifdef HAVE_SYS_TERMIO_H
- X#include <sys/termio.h>
- X#endif /* HAVE_SYS_TERMIO_H */
- X#endif /* !HAVE_SYS_TERMIOS_H */
- X#endif /* !TIOCGWINSZ */
- X#ifdef HAVE_SYS_BSD_TTY_H
- X#include <sys/bsd_tty.h>
- X#endif /* HAVE_SYS_BSD_TTY_H */
- X
- X#include "term.h"
- X
- X/* <sys/ioctl.h> or <sys/ttycom.h> */
- Xstruct Winsize {
- X unsigned short ws_row; /* rows, in characters */
- X unsigned short ws_col; /* columns, in characters */
- X unsigned short ws_xpixel; /* horizontal size, pixels - not used */
- X unsigned short ws_ypixel; /* vertical size, pixels - not used */
- X};
- X
- X/* system functions */
- X
- Xchar *getenv();
- X
- Xchar *tgetstr();
- Xint tgetent();
- Xint tgetnum();
- X
- X/* macros */
- X
- X#define TCputs(str) tputs(str, 1, putstdout)
- X#define putcap(str) (void)((str) != NULL ? TCputs(str) : 0)
- X
- Xchar termcap_buf[1024];
- Xchar string_buffer[1024];
- Xint termcap_status;
- Xint t_rows;
- Xint t_cols;
- Xchar *clear_screen;
- Xstatic int smart_terminal;
- X
- X/* This has to be defined as a subroutine for tputs (instead of a macro) */
- Xint
- Xputstdout(ch)
- X char ch;
- X{
- X return putchar(ch);
- X}
- X
- Xvoid
- Xinit_termcap()
- X{
- X char *efmt = "Can't get terminal size because\n%s";
- X char *term;
- X char *bufptr;
- X
- X bufptr = string_buffer;
- X
- X term = getenv("TERM");
- X if (!term) {
- X (void) fprintf(stderr, efmt, "TERM environment variable not set.\n");
- X return;
- X }
- X termcap_status = tgetent(termcap_buf, term);
- X switch (termcap_status) {
- X case -1:
- X (void) fprintf(stderr, efmt, "can't open termcap file.\n");
- X return;
- X case 0:
- X (void) fprintf(stderr, efmt, "no termcap entry for a ");
- X (void) fprintf(stderr, "`%s' terminal\n", term);
- X return;
- X case 1:
- X smart_terminal = 1; /* assume */
- X t_rows = tgetnum("li");
- X if (t_rows == -1)
- X t_rows = 0;
- X t_cols = tgetnum("co");
- X if (t_cols == -1)
- X t_cols = 0;
- X
- X clear_screen = tgetstr("cl", &bufptr);
- X smart_terminal = clear_screen ? 1 : 0;
- X
- X return;
- X }
- X}
- X
- Xvoid
- Xclear()
- X{
- X if (smart_terminal) {
- X putcap(clear_screen);
- X (void) fflush(stdout);
- X }
- X}
- X
- X
- X/**
- X * get terminal size
- X**/
- Xvoid
- Xcheck_term(t_rowp, t_colp)
- X unsigned short *t_rowp, *t_colp;
- X{
- X struct Winsize winsize;
- X
- X winsize.ws_row = 0;
- X winsize.ws_col = 0;
- X
- X if (ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *) &winsize) == -1) {
- X /* if error, then assume not a terminal */
- X if (t_rowp)
- X *t_rowp = t_rows;
- X if (t_colp)
- X *t_colp = t_cols;
- X
- X switch (errno) {
- X static int einvalseen;
- X static int enodevseen;
- X static int eopnotsuppseen;
- X static int enottyseen;
- X
- X case EINVAL:
- X if (einvalseen)
- X return;
- X einvalseen = 1;
- X break;
- X case ENODEV:
- X if (enodevseen)
- X return;
- X enodevseen = 1;
- X break;
- X case EOPNOTSUPP:
- X if (eopnotsuppseen)
- X return;
- X eopnotsuppseen = 1;
- X break;
- X case ENOTTY:
- X if (enottyseen)
- X return;
- X enottyseen = 1;
- X break;
- X }
- X if (dbg_lvl >= 1)
- X perror("ioctl: TIOCGWINSZ");
- X return;
- X }
- X if (t_rowp)
- X *t_rowp = winsize.ws_row ? winsize.ws_row : t_rows;
- X if (t_colp)
- X *t_colp = winsize.ws_col ? winsize.ws_col : t_cols;
- X}
- END_OF_FILE
- if test 3424 -ne `wc -c <'term.c'`; then
- echo shar: \"'term.c'\" unpacked with wrong size!
- fi
- # end of 'term.c'
- fi
- if test -f 'rpc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rpc.c'\"
- else
- echo shar: Extracting \"'rpc.c'\" \(21859 characters\)
- sed "s/^X//" >'rpc.c' <<'END_OF_FILE'
- X/**
- X * This program may be copied, redistributed in any form,
- X * source or binary, and used for any purpose, provided
- X * this copyright notice is retained.
- X *
- X * @(#)rpc.c 3.1 12/15/93 (c) Copyright Brian P. Fitzgerald
- X * Rensselaer Polytechnic Institute
- X *
- X**/
- X
- X#include "common.h"
- X#include "rperf.h"
- X
- Xstatic bool_t bcst_timo;
- X
- Xstatic struct timeval call_timo = {25, 0};
- X
- Xbool_t(*xdr_statsproc[]) () =
- X{
- X xdr_stats,
- X xdr_statsswtch,
- X xdr_statstime,
- X xdr_statsvar,
- X};
- X
- Xchar *emfilehelp[] = {
- X "You may be trying to monitor too many hosts at once.",
- X "Consider increasing the system per-process hard limit",
- X "on open files, or else monitor fewer hosts.",
- X "If you are using broadcast mode, try the -b option.",
- X 0
- X};
- X
- Xchar *doclnt_call_help[] = {
- X "",
- X "client call debug mode. key:",
- X "m made client\tc called client\t\tv4,v3,v2,v1 version called",
- X "- no call made\tM version mismatch\tx drop\t* down",
- X "",
- X 0
- X};
- X
- Xstruct data *dp; /* link list head */
- X
- Xint if_opackets_fixed = 1;
- X
- Xvoid
- Xdestroy_array(a)
- X array *a;
- X{
- X if (a->val) {
- X free((char *) a->val);
- X a->val = (int *) NULL;
- X }
- X}
- X
- X/**
- X * copy n ints from p to a->val
- X**/
- Xvoid
- Xcopy_to_array(a, p, n)
- X array *a;
- X int *p;
- X unsigned int n;
- X{
- X int i;
- X
- X if (n > a->len) {
- X (void) fprintf(stderr,
- X "copy_to_array: attempt to overwrite end of array\n");
- X exit(1);
- X }
- X if (!p) {
- X (void) fprintf(stderr,
- X "copy_to_array: no source array\n");
- X exit(1);
- X }
- X if (!a->val) {
- X (void) fprintf(stderr,
- X "copy_to_array: no destination array\n");
- X exit(1);
- X }
- X for (i = 0; i < n; i++)
- X a->val[i] = p[i];
- X return;
- X}
- X
- X/**
- X * allocate the value part of an array struct, size n
- X**/
- Xvoid
- Xcreate_array(a, n)
- X array *a;
- X unsigned int n;
- X{
- X a->len = n;
- X a->val = (int *) malloc((unsigned) n * sizeof(int));
- X if (a->val == NULL) {
- X perror("malloc");
- X exit(1);
- X }
- X return;
- X}
- X
- X/**
- X * convert and store the received data
- X**/
- Xstats_default *
- Xfrom_stats(s)
- X stats_all *s;
- X{
- X static stats_default r;
- X
- X bzero((char *) &r, sizeof(r));
- X create_array((array *) & r.cp_time, CPUSTATES);
- X copy_to_array((array *) & r.cp_time, s->s1.cp_time, CPUSTATES);
- X create_array((array *) & r.dk_xfer, DK_NDRIVE);
- X copy_to_array((array *) & r.dk_xfer, s->s1.dk_xfer, DK_NDRIVE);
- X r.v_pgpgin = s->s1.v_pgpgin;
- X r.v_pgpgout = s->s1.v_pgpgout;
- X r.v_pswpin = s->s1.v_pswpin;
- X r.v_pswpout = s->s1.v_pswpout;
- X r.v_intr = s->s1.v_intr;
- X r.if_ipackets = s->s1.if_ipackets;
- X r.if_ierrors = s->s1.if_ierrors;
- X r.if_opackets = s->s1.if_opackets;
- X r.if_oerrors = s->s1.if_oerrors;
- X r.if_collisions = s->s1.if_collisions;
- X if (gettimeofday((struct timeval *) & r.curtime,
- X (struct timezone *) NULL) == -1) {
- X perror("gettimeofday");
- X exit(1);
- X }
- X return &r;
- X}
- X
- Xstats_default *
- Xfrom_statsswtch(s)
- X stats_all *s;
- X{
- X int i;
- X static stats_default r;
- X
- X bzero((char *) &r, sizeof(r));
- X create_array((array *) & r.cp_time, CPUSTATES);
- X copy_to_array((array *) & r.cp_time, s->s2.cp_time, CPUSTATES);
- X create_array((array *) & r.dk_xfer, DK_NDRIVE);
- X copy_to_array((array *) & r.dk_xfer, s->s2.dk_xfer, DK_NDRIVE);
- X r.v_pgpgin = s->s2.v_pgpgin;
- X r.v_pgpgout = s->s2.v_pgpgout;
- X r.v_pswpin = s->s2.v_pswpin;
- X r.v_pswpout = s->s2.v_pswpout;
- X r.v_intr = s->s2.v_intr;
- X r.if_ipackets = s->s2.if_ipackets;
- X r.if_ierrors = s->s2.if_ierrors;
- X r.if_opackets = s->s2.if_opackets;
- X r.if_oerrors = s->s2.if_oerrors;
- X r.if_collisions = s->s2.if_collisions;
- X r.v_swtch = s->s2.v_swtch;
- X for (i = 0; i < 3; i++)
- X r.avenrun[i] = s->s2.avenrun[i];
- X r.boottime = s->s2.boottime;
- X if (gettimeofday((struct timeval *) & r.curtime,
- X (struct timezone *) NULL) == -1) {
- X perror("gettimeofday");
- X exit(1);
- X }
- X return &r;
- X}
- X
- Xstats_default *
- Xfrom_statstime(s)
- X stats_all *s;
- X{
- X int i;
- X static stats_default r;
- X
- X bzero((char *) &r, sizeof(r));
- X create_array((array *) & r.cp_time, CPUSTATES);
- X copy_to_array((array *) & r.cp_time, s->s3.cp_time, CPUSTATES);
- X create_array((array *) & r.dk_xfer, DK_NDRIVE);
- X copy_to_array((array *) & r.dk_xfer, s->s3.dk_xfer, DK_NDRIVE);
- X r.v_pgpgin = s->s3.v_pgpgin;
- X r.v_pgpgout = s->s3.v_pgpgout;
- X r.v_pswpin = s->s3.v_pswpin;
- X r.v_pswpout = s->s3.v_pswpout;
- X r.v_intr = s->s3.v_intr;
- X r.if_ipackets = s->s3.if_ipackets;
- X r.if_ierrors = s->s3.if_ierrors;
- X r.if_opackets = s->s3.if_opackets;
- X r.if_oerrors = s->s3.if_oerrors;
- X r.if_collisions = s->s3.if_collisions;
- X r.v_swtch = s->s3.v_swtch;
- X for (i = 0; i < 3; i++)
- X r.avenrun[i] = s->s3.avenrun[i];
- X r.boottime = s->s3.boottime;
- X r.curtime = s->s3.curtime;
- X return &r;
- X}
- X
- Xstats_default *
- Xfrom_statsvar(s)
- X stats_all *s;
- X{
- X int i;
- X static stats_default r;
- X
- X bzero((char *) &r, sizeof(r));
- X create_array((array *) & r.cp_time, s->s4.cp_len);
- X copy_to_array((array *) & r.cp_time, s->s4.cp_val, s->s4.cp_len);
- X create_array((array *) & r.dk_xfer, s->s4.dk_len);
- X copy_to_array((array *) & r.dk_xfer, s->s4.dk_val, s->s4.dk_len);
- X r.v_pgpgin = s->s4.v_pgpgin;
- X r.v_pgpgout = s->s4.v_pgpgout;
- X r.v_pswpin = s->s4.v_pswpin;
- X r.v_pswpout = s->s4.v_pswpout;
- X r.v_intr = s->s4.v_intr;
- X r.if_ipackets = s->s4.if_ipackets;
- X r.if_ierrors = s->s4.if_ierrors;
- X r.if_opackets = s->s4.if_opackets;
- X r.if_oerrors = s->s4.if_oerrors;
- X r.if_collisions = s->s4.if_collisions;
- X r.v_swtch = s->s4.v_swtch;
- X for (i = 0; i < 3; i++)
- X r.avenrun[i] = s->s4.avenrun[i];
- X r.boottime = s->s4.boottime;
- X r.curtime = s->s4.curtime;
- X return &r;
- X}
- X
- Xstats_default *((*stats_convert[]) ()) =
- X{
- X from_stats,
- X from_statsswtch,
- X from_statstime,
- X from_statsvar,
- X};
- X
- X/**
- X * free the cp_time and dk_xfer array in a stats_default struct
- X**/
- Xvoid
- Xfree_stats(s)
- X stats_default *s;
- X{
- X destroy_array((array *) & s->cp_time);
- X destroy_array((array *) & s->dk_xfer);
- X return;
- X}
- X
- X/**
- X * save the results in a data structure
- X * return 1 if the results were saved
- X * return 0 if the results were ignored
- X**/
- Xint
- Xsave_res(d, res)
- X struct data *d;
- X stats_default *res;
- X{
- X if (d->nn == thiscount) {
- X free_stats(res);
- X return 0; /* duplicate. ignore */
- X }
- X d->no = d->nn;
- X d->nn = thiscount;
- X if (!d->ok_to_call)
- X (void) fprintf(stderr, " %s is back up ", d->host);
- X d->ok_to_call = 1;
- X
- X free_stats(&d->so);
- X d->so = d->sn;
- X d->sn = *res;
- X return 1;
- X}
- X
- X/**
- X * this function may be called after (*dpp)->addr
- X * has been filled with a valid in_addr
- X * return: 1=success, 0=fail
- X**/
- Xint
- Xmake_client(dpp)
- X struct data **dpp;
- X{
- X int sock = RPC_ANYSOCK;
- X static int emfilewarned;
- X struct sockaddr_in server_addr;
- X struct timeval p_timo;
- X
- X p_timo.tv_sec = 3;
- X p_timo.tv_usec = 0;
- X
- X server_addr.sin_family = AF_INET;
- X server_addr.sin_port = 0;
- X server_addr.sin_addr = (*dpp)->addr;
- X
- X /**
- X * clntudp_create only determines whether the
- X * program is registered. It does not actually check
- X * whether the host supports the requested version.
- X * see the pmap_getport man page.
- X **/
- X errno = 0;
- X (*dpp)->cl = clntudp_create(&server_addr,
- X RSTATPROG,
- X (*dpp)->clnt_vers,
- X p_timo,
- X &sock);
- X
- X if ((*dpp)->cl == NULL) {
- X if (rpc_createerr.cf_stat == RPC_SYSTEMERROR
- X && rpc_createerr.cf_error.re_errno == EMFILE) {
- X if (!emfilewarned) {
- X (void) fprintf(stderr, "Can't contact rstatd on %s.\n",
- X (*dpp)->host);
- X (void) clnt_pcreateerror("clntudp_create");
- X (void) fprintf(stderr, "Open file descriptor limit now %d\n",
- X set_max_nofiles());
- X msg(emfilehelp, stderr);
- X emfilewarned = 1;
- X }
- X } else {
- X (void) fprintf(stderr, "Can't contact rstatd on %s. ",
- X (*dpp)->host);
- X (void) clnt_pcreateerror("clntudp_create");
- X }
- X return 0;
- X }
- X if (dbg_lvl >= 2) {
- X (void) putc('m', stderr);
- X (void) fflush(stderr);
- X }
- X return 1;
- X}
- X
- X/**
- X * for each host on the linked list that still needs data:
- X * loop over the rpc prog versions,
- X * starting with the highest known version,
- X * or highest previously successful version
- X * make a client, if necessary
- X * call the client
- X **/
- Xvoid
- Xdoclnt_calls(vers_max)
- X u_long vers_max;
- X{
- X u_long vers;
- X int good = 0;
- X int bad = 0;
- X static enum clnt_stat clnt_stat;
- X stats_default *sn;
- X struct data **dpp;
- X stats_all resbuf;
- X
- X if (dbg_lvl >= 2)
- X msg(doclnt_call_help, stderr);
- X
- X for (dpp = &dp; *dpp;) {
- X if (dbg_lvl >= 2)
- X (void) fprintf(stderr, "%s\t%s\t",
- X inet_ntoa((*dpp)->addr), (*dpp)->host);
- X if ((*dpp)->nn == thiscount) {
- X dpp = &(*dpp)->datap;
- X if (dbg_lvl >= 2) {
- X (void) fputs("-\n", stderr);
- X }
- X continue; /* already have data */
- X }
- X if (!(*dpp)->ok_to_call) {
- X dpp = &(*dpp)->datap;
- X if (dbg_lvl >= 2) {
- X (void) fputs("*\n", stderr);
- X }
- X continue; /* probably down */
- X }
- X if (!(*dpp)->clnt_vers)
- X (*dpp)->clnt_vers = vers_max; /* try first */
- X
- X for (vers = (*dpp)->clnt_vers; vers > 0; vers--) {
- X (*dpp)->clnt_vers = vers;
- X if (!(*dpp)->cl)
- X if (!make_client(dpp)) {
- X (*dpp)->ok_to_call = 0;
- X bad++;
- X break; /* vers */
- X }
- X if (dbg_lvl >= 2) {
- X (void) fprintf(stderr, "v%d", vers);
- X (void) fflush(stderr);
- X }
- X bzero((char *) &resbuf, sizeof(resbuf));
- X clnt_stat = clnt_call((*dpp)->cl,
- X RSTATPROC_STATS,
- X xdr_void,
- X NULL,
- X XDR_STATSPROC((*dpp)->clnt_vers),
- X (char *) &resbuf,
- X call_timo);
- X if (clnt_stat == RPC_SUCCESS) {
- X sn = STATS_CONVERT((*dpp)->clnt_vers) (&resbuf);
- X /**
- X * 11/3/93 I have checked that
- X * xdr_free is needed here, so don't delete it
- X **/
- X xdr_free(XDR_STATSPROC((*dpp)->clnt_vers), (char *) &resbuf);
- X (void) save_res(*dpp, sn);
- X
- X if (!(*dpp)->no && !if_opackets_fixed && dbg_lvl >= 1) {
- X (void) fprintf(stderr,
- X "%s: rpc.rstatd vers %d does not report if_opackets\n",
- X (*dpp)->host, (*dpp)->clnt_vers);
- X }
- X if_opackets_fixed = 1;
- X
- X if (dbg_lvl >= 2) {
- X (void) fputs("c\n", stderr);
- X }
- X good++;
- X dpp = &(*dpp)->datap;
- X break; /* vers */
- X }
- X xdr_free(XDR_STATSPROC((*dpp)->clnt_vers), (char *) &resbuf);
- X if (clnt_stat == RPC_PROGVERSMISMATCH && vers > 1) {
- X if (dbg_lvl >= 2) {
- X (void) fputs("M ", stderr);
- X (void) fflush(stderr);
- X }
- X clnt_destroy((*dpp)->cl);
- X (*dpp)->cl = NULL;
- X continue; /* vers-- */
- X }
- X (void) fprintf(stderr, "clnt_call: %s %s\n",
- X (*dpp)->host, clnt_sperrno(clnt_stat));
- X (*dpp)->ok_to_call = 0;
- X bad++;
- X break; /* vers */
- X } /* for(vers ... */
- X } /* for dpp */
- X
- X if (dbg_lvl >= 1) {
- X (void) fprintf(stderr, "done clnt calls good=%d bad=%d\n", good, bad);
- X }
- X if (mode == MODE_CALL && !good) {
- X if (nhosts > 1) {
- X (void) fprintf(stderr, "None of the hosts replied. Quitting.\n");
- X } else {
- X dpp = &dp;
- X (void) fprintf(stderr, "%s did not reply. Quitting.\n", (*dpp)->host);
- X }
- X exit(1);
- X }
- X return;
- X}
- X
- X/**
- X * create a new data structure
- X**/
- Xstruct data *
- Xnew_host(addr, hostname)
- X struct in_addr *addr;
- X char *hostname;
- X{
- X struct data *newdpp;
- X
- X newdpp = (struct data *) calloc(1, sizeof(struct data));
- X if (newdpp == NULL) {
- X perror("calloc");
- X exit(1);
- X }
- X newdpp->addr = *addr;
- X newdpp->host = strdup(hostname);
- X if (!newdpp->host) {
- X perror("strdup");
- X exit(1);
- X }
- X newdpp->host_dup = strdup(hostname);
- X if (!newdpp->host_dup) {
- X perror("strdup");
- X exit(1);
- X }
- X newdpp->ok_to_call = 1;
- X /**
- X * assume cp_time is cumulative since boot time
- X * until we find out otherwise
- X **/
- X newdpp->cp_kind = CP_TIME_CUM;
- X nhosts++;
- X if (mode == MODE_BCST) {
- X (void) putc('+', stderr);
- X (void) fflush(stderr);
- X }
- X return newdpp;
- X}
- X
- Xvoid
- Xdump_hostent(entry)
- X struct hostent *entry;
- X{
- X char **app;
- X struct in_addr in_addr;
- X
- X (void) fprintf(stderr, "Official name:\t%s\n", entry->h_name);
- X for (app = entry->h_aliases; *app; app++)
- X (void) fprintf(stderr, "Alias:\t\t%s\n", *app);
- X
- X for (app = entry->h_addr_list; *app; app++) {
- X bcopy(*app, (char *) &in_addr.s_addr, entry->h_length);
- X (void) fprintf(stderr, "Host address:\t%s\n", inet_ntoa(in_addr));
- X }
- X}
- X
- Xvoid
- Xinsert_dp(newdp)
- X struct data *newdp;
- X{
- X struct data **dpp;
- X struct data *tdp;
- X
- X tdp = NULL;
- X for (dpp = &dp; *dpp; dpp = &(*dpp)->datap) {
- X if (newdp->addr.s_addr == (*dpp)->addr.s_addr) {
- X /* already on the list */
- X (void) fprintf(stderr,
- X "This can't happen! %s already on list\n",
- X inet_ntoa(newdp->addr));
- X exit(1);
- X }
- X if (opts & O_SHOST ? strcmp(newdp->host, (*dpp)->host) < 0
- X : ntohl(newdp->addr.s_addr) < ntohl((*dpp)->addr.s_addr)) {
- X /* insert into list */
- X tdp = *dpp;
- X break; /* break => insert into list */
- X }
- X } /* fall-through => append to list */
- X *dpp = newdp;
- X (*dpp)->datap = tdp;
- X}
- X
- Xvoid
- Xenter_item(itemkey, addr, datap)
- X char *itemkey;
- X struct in_addr addr;
- X struct data *datap;
- X{
- X hash_info *hip;
- X ENTRY item;
- X
- X /*
- X * caution: do not use inet_ntoa() in this routine
- X */
- X
- X hip = (hash_info *) malloc(sizeof(hash_info));
- X item.key = strdup(itemkey);
- X if (!item.key) {
- X perror("strdup");
- X exit(1);
- X }
- X hip->ident_addr = addr;
- X hip->datap = datap;
- X item.data = (char *) hip;
- X /* put name into table */
- X if (!hsearch(item, ENTER)) {
- X (void) fprintf(stderr, "Hash table full.\n");
- X exit(1);
- X }
- X if (dbg_lvl >= 2)
- X (void) fprintf(stderr, "ENTER %s. hip: ident_addr.s_addr=0x%08x datap=0x%08x\n",
- X itemkey, ntohl(hip->ident_addr.s_addr), (u_long) hip->datap);
- X}
- X
- X/**
- X * handle each reply to the broadcast
- X * return FALSE to permit more broadcasting
- X * return TRUE to terminate broadcasting (after alarm has timed out)
- X *
- X * my profuse thanks Joe Beauchamp (JRB@CSI.compuserve.com)
- X * for patiently assisting me with debugging this routine.
- X *
- X**/
- X/**
- X * You are about to enter ...
- X**/
- Xbool_t
- Xeach_result(resp, raddr, version)
- X stats_all *resp;
- X struct sockaddr_in *raddr;
- X u_long version;
- X{
- X char *hostname;
- X char *dotquad1;
- X struct data *resdp;
- X stats_default *sn;
- X ENTRY *found_item1;
- X hash_info *fip;
- X struct hostent *host_entry;
- X char **app;
- X struct in_addr in_tmp;
- X ENTRY item;
- X
- X /**
- X * * * * *
- X * * * * * *
- X ... the coredump zone *
- X * * * * *
- X * * * *
- X **/
- X
- X /**
- X * use strdup for dotquad1 because inet_ntoa uses static storage,
- X * which is overwritten each call
- X *
- X **/
- X dotquad1 = strdup(inet_ntoa(raddr->sin_addr));
- X if (!dotquad1) {
- X perror("strdup");
- X exit(1);
- X }
- X item.key = dotquad1;
- X found_item1 = hsearch(item, FIND);
- X if (found_item1) { /* found_item1 */
- X /* already on the list */
- X fip = (hash_info *) found_item1->data;
- X in_tmp = fip->ident_addr;
- X if (in_tmp.s_addr) {
- X char *dotquad2;
- X ENTRY *found_item2;
- X /* machine has more than one network interface */
- X dotquad2 = inet_ntoa(in_tmp);
- X item.key = dotquad2;
- X found_item2 = hsearch(item, FIND);
- X if (!found_item2) {
- X (void) fprintf(stderr,
- X "This can't happen! %s not in hash table\n",
- X dotquad2);
- X exit(1);
- X }
- X fip = (hash_info *) found_item2->data;
- X } /* in_tmp.s_addr */
- X resdp = fip->datap;
- X (void) putc('.', stderr);
- X (void) fflush(stderr);
- X } else { /* ! found_item1 */
- X if (opts & O_NHOST) {
- X resdp = new_host(&raddr->sin_addr, dotquad1);
- X insert_dp(resdp);
- X in_tmp.s_addr = 0;
- X enter_item(dotquad1, in_tmp, resdp);
- X } else { /* !opts & O_NHOST */
- X ENTRY *found_item3;
- X host_entry = gethostbyaddr((char *) &raddr->sin_addr, 4, AF_INET);
- X if (host_entry) {
- X if (dbg_lvl >= 2)
- X dump_hostent(host_entry);
- X
- X hostname = host_entry->h_name;
- X if (!hostname) {
- X (void) fprintf(stderr,
- X "gethostbyaddr: null hostname %s\n",
- X dotquad1);
- X exit(1);
- X }
- X item.key = hostname;
- X } else { /* !host_entry */
- X hostname = (char *) NULL;
- X if (dbg_lvl >= 1)
- X (void) fprintf(stderr,
- X "gethostbyaddr failed %s\n", dotquad1);
- X item.key = dotquad1;
- X } /* !host_entry */
- X found_item3 = hsearch(item, FIND);
- X if (found_item3) {
- X char *dotquad2;
- X ENTRY *found_item4;
- X fip = (hash_info *) found_item3->data;
- X in_tmp = fip->ident_addr;
- X enter_item(dotquad1, in_tmp, (struct data *) NULL);
- X
- X if (dbg_lvl >= 1)
- X (void) fprintf(stderr,
- X "duplicate reply from %s received on interface %s\n",
- X hostname ? hostname : "(unknown)", dotquad1);
- X dotquad2 = inet_ntoa(in_tmp);
- X item.key = dotquad2;
- X found_item4 = hsearch(item, FIND);
- X if (!found_item4) {
- X (void) fprintf(stderr,
- X "This can't happen! %s not in hash table\n",
- X dotquad2);
- X exit(1);
- X }
- X fip = (hash_info *) found_item4->data;
- X resdp = fip->datap;
- X (void) putc('.', stderr);
- X (void) fflush(stderr);
- X } else { /* ! found_item2 */
- X resdp = (struct data *) NULL;
- X if (host_entry) {
- X enter_item(hostname, raddr->sin_addr, (struct data *) NULL);
- X for (app = host_entry->h_addr_list; *app; app++) {
- X bcopy(*app, (char *) &in_tmp, host_entry->h_length);
- X if (in_tmp.s_addr == raddr->sin_addr.s_addr) {
- X /* this is the normal branch */
- X resdp = new_host(&raddr->sin_addr, hostname);
- X insert_dp(resdp);
- X in_tmp.s_addr = 0;
- X enter_item(dotquad1, in_tmp, resdp);
- X } else {/* other addresses */
- X /* save other addresses found in host table */
- X char *dotquad2;
- X dotquad2 = inet_ntoa(in_tmp);
- X if (dbg_lvl >= 1)
- X (void) fprintf(stderr,
- X "Saving address %s for host %s\n",
- X dotquad2, hostname);
- X enter_item(dotquad2, raddr->sin_addr,
- X (struct data *) NULL);
- X } /* other addresses */
- X } /* for app */
- X } else { /* !host_entry */
- X resdp = new_host(&raddr->sin_addr, dotquad1);
- X insert_dp(resdp);
- X in_tmp.s_addr = 0;
- X enter_item(dotquad1, in_tmp, resdp);
- X } /* !host_entry */
- X } /* ! found_item2 */
- X } /* !opts & O_NHOST */
- X } /* ! found_item1 */
- X
- X sn = STATS_CONVERT(version) (resp);
- X /**
- X * 11/3/93 I have checked that no memory leak occurs if I do not use
- X * xdr_free here. (Leave this comment here, so I don't forget about it.)
- X **/
- X if (!resdp) {
- X (void) fprintf(stderr,
- X "This shouldn't happen %s resdp = NULL\n", dotquad1);
- X exit(1);
- X }
- X if (save_res(resdp, sn))
- X resdp->bcst_vers = version;
- X
- X if (!resdp->no && !if_opackets_fixed && dbg_lvl >= 1) {
- X (void) fprintf(stderr,
- X "%s: rpc.rstatd vers %d does not report if_opackets\n",
- X resdp->host, resdp->bcst_vers);
- X }
- X if_opackets_fixed = 1;
- X free(dotquad1);
- X
- X return bcst_timo;
- X}
- X
- Xbool_t
- Xeach_result_orig(resp, raddr)
- X stats_all *resp;
- X struct sockaddr_in *raddr;
- X{
- X return each_result(resp, raddr, RSTATVERS_ORIG);
- X}
- X
- Xbool_t
- Xeach_result_swtch(resp, raddr)
- X stats_all *resp;
- X struct sockaddr_in *raddr;
- X{
- X return each_result(resp, raddr, RSTATVERS_SWTCH);
- X}
- X
- Xbool_t
- Xeach_result_time(resp, raddr)
- X stats_all *resp;
- X struct sockaddr_in *raddr;
- X{
- X return each_result(resp, raddr, RSTATVERS_TIME);
- X}
- X
- Xbool_t
- Xeach_result_var(resp, raddr)
- X stats_all *resp;
- X struct sockaddr_in *raddr;
- X{
- X return each_result(resp, raddr, RSTATVERS_VAR);
- X}
- X
- Xbool_t(*each_result_vers[]) () =
- X{
- X each_result_orig,
- X each_result_swtch,
- X each_result_time,
- X each_result_var,
- X};
- X
- X/**
- X * force end of broadcasting
- X**/
- XRETSIGTYPE
- Xbcst_done()
- X{
- X bcst_timo = TRUE;
- X}
- X
- X/**
- X * calculate how long the alarm should be to get
- X * the desired interval
- X * example: desire 30 sec. use alarm(14)
- X**/
- Xunsigned
- Xget_bcst_alarm(interval)
- X unsigned interval;
- X{
- X int j, h = 0;
- X
- X if (interval <= 4)
- X return 1;
- X for (j = 4; j <= 64; j *= 2) {
- X h += j;
- X if (interval <= h)
- X break;
- X }
- X j /= 2;
- X return Min(h - j, interval) - j;
- X /* max is 60 */
- X}
- X
- Xvoid
- Xdo_broadcast(vers_max, interval)
- X u_long vers_max;
- X unsigned interval; /* desired broadcast interval. 92 max */
- X{
- X u_long vers;
- X static u_long vers_max_ok;
- X static enum clnt_stat clnt_stat;
- X stats_all resbuf;
- X
- X if (!vers_max_ok)
- X vers_max_ok = vers_max;
- X
- X (void) fputs("broadcasting ", stderr);
- X for (vers = vers_max_ok; vers >= Min(vers_max_ok, RSTATVERS_TIME); vers--) {
- X
- X if (dbg_lvl >= 1)
- X (void) fprintf(stderr, " vers %d: ", vers);
- X
- X (void) signal(SIGALRM, bcst_done);
- X (void) alarm(get_bcst_alarm(interval));
- X
- X bcst_timo = FALSE;
- X (void) fflush(stderr);
- X bzero((char *) &resbuf, sizeof resbuf);
- X clnt_stat = clnt_broadcast(RSTATPROG,
- X vers,
- X RSTATPROC_STATS,
- X xdr_void,
- X (char *) NULL,
- X XDR_STATSPROC(vers),
- X (char *) &resbuf,
- X EACH_RESULT(vers));
- X /**
- X * resultproc_t each_result in Solaris-2 (thanks
- X * cmc@apus.srg-ssr.ch (Colin M. Clark))
- X **/
- X
- X if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) {
- X (void) fprintf(stderr, "\nclnt_broadcast: %s\n",
- X clnt_sperrno(clnt_stat));
- X exit(1);
- X }
- X if (!nhosts) {
- X (void) fprintf(stderr,
- X "\nNo hosts found with rstatd version %d on this network\n",
- X vers);
- X vers_max_ok = vers - 1;
- X if (!vers_max_ok)
- X exit(1);
- X }
- X }
- X (void) putc('\n', stderr);
- X}
- END_OF_FILE
- if test 21859 -ne `wc -c <'rpc.c'`; then
- echo shar: \"'rpc.c'\" unpacked with wrong size!
- fi
- # end of 'rpc.c'
- fi
- if test -f 'common.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'common.h'\"
- else
- echo shar: Extracting \"'common.h'\" \(1816 characters\)
- sed "s/^X//" >'common.h' <<'END_OF_FILE'
- X/**
- X * This program may be copied, redistributed in any form,
- X * source or binary, and used for any purpose, provided
- X * this copyright notice is retained.
- X * @(#)common.h 3.1 12/15/93 (c) Copyright Brian P. Fitzgerald
- X * Rensselaer Polytechnic Institute
- X **/
- X#ifdef STDC_HEADERS
- X#include <stddef.h>
- X#endif /* STDC_HEADERS */
- X
- X#ifdef HAVE_STDLIB_H
- X#include <stdlib.h>
- X#else /* !HAVE_STDLIB_H */
- Xextern void exit();
- X#endif /* !HAVE_STDLIB_H */
- X
- X#include <string.h>
- X
- X#ifdef HAVE_UNISTD_H
- X#include <unistd.h>
- X#endif /* HAVE_UNISTD_H */
- X
- X/* <unistd.h> */
- X#ifndef STDOUT_FILENO
- X#define STDOUT_FILENO 1
- X#endif /* STDOUT_FILENO */
- X
- X#include <errno.h>
- X
- X#ifndef Abs
- X#define Abs(a) ((a)>= 0 ? (a) : -(a))
- X#endif /* Abs */
- X
- X#ifndef Min
- X#define Min(a, b) ((a) < (b) ? (a) : (b))
- X#endif /* Min */
- X
- X#ifndef Max
- X#define Max(a, b) ((a) > (b) ? (a) : (b))
- X#endif /* Max */
- X
- X#ifdef NO_BSTRING
- X#define bcopy(b1,b2,len) memmove(b2, b1, len)
- X#define bzero(b,len) memset(b, 0, len)
- X#define bcmp(b1,b2,len) memcmp(b1, b2, len)
- X#endif /* NO_BSTRING */
- X
- X#define O_CP 0x01
- X#define O_DK 0x02
- X#define O_VM 0x04
- X#define O_IF 0x08
- X#define O_TIME 0x10
- X#define O_DATE 0x20
- X#define O_SECS 0x40
- X#define O_MOST ( O_CP | O_DK | O_VM | O_IF )
- X#define O_DEFL ( O_CP | O_VM | O_IF )
- X#define O_DEFL1 ( O_CP | O_DK | O_VM | O_IF )
- X#define O_UP 0x100
- X#define O_ALL ( O_MOST | O_TIME | O_DATE | O_SECS | O_UP )
- X#define O_BCST 0x200
- X#define O_BARE 0x400
- X#define O_DBG 0x800
- X#define O_SHOST 0x1000
- X#define O_NHOST 0x8000
- X#define O_SORT 0x10000
- X#define O_RVRS 0x20000
- X#define O_NCLR 0x100000 /* never clear the screen */
- X
- Xextern int opterr, optind;
- X
- Xextern long strtol();
- Xextern char *strdup();
- X
- Xvoid msg();
- Xint set_max_nofiles();
- X
- Xextern unsigned long dbg_lvl;
- Xextern unsigned long opts;
- END_OF_FILE
- if test 1816 -ne `wc -c <'common.h'`; then
- echo shar: \"'common.h'\" unpacked with wrong size!
- fi
- # end of 'common.h'
- fi
- if test -f 'strdup.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'strdup.c'\"
- else
- echo shar: Extracting \"'strdup.c'\" \(718 characters\)
- sed "s/^X//" >'strdup.c' <<'END_OF_FILE'
- X#ifndef lint
- Xstatic char *RCSid = "$Header: /src/common/usc/lib/libgen/RCS/strdup.c,v 1.2 1992/04/16 01:28:02 mcooper Exp $";
- X#endif
- X
- X/*
- X * $Log: strdup.c,v $ Revision 1.2 1992/04/16 01:28:02 mcooper Some
- X * de-linting.
- X *
- X * Revision 1.2 1992/04/16 01:28:02 mcooper Some de-linting.
- X *
- X * Revision 1.1 1992/03/21 02:48:11 mcooper Initial revision
- X *
- X */
- X
- X#include <stdio.h>
- X
- X#ifdef HAVE_STDLIB_H
- X#include <stdlib.h>
- X#endif /* HAVE_STDLIB_H */
- X
- X/*
- X * Most systems don't have this (yet)
- X */
- Xchar *
- Xstrdup(str)
- X char *str;
- X{
- X char *p;
- X
- X if ((p = malloc((unsigned) strlen(str) + 1)) == NULL)
- X return ((char *) NULL);
- X
- X (void) strcpy(p, str);
- X
- X return (p);
- X}
- END_OF_FILE
- if test 718 -ne `wc -c <'strdup.c'`; then
- echo shar: \"'strdup.c'\" unpacked with wrong size!
- fi
- # end of 'strdup.c'
- fi
- if test -f 'hsearch.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'hsearch.h'\"
- else
- echo shar: Extracting \"'hsearch.h'\" \(456 characters\)
- sed "s/^X//" >'hsearch.h' <<'END_OF_FILE'
- X#include <stdio.h>
- X
- X#ifdef HAVE_STDLIB_H
- X#include <stdlib.h>
- X#endif /* HAVE_STDLIB_H */
- X
- X#include <string.h>
- X
- Xtypedef struct entry {
- X char *key;
- X char *data;
- X} ENTRY;
- X
- Xtypedef enum {
- X FIND,
- X ENTER
- X} ACTION;
- X
- Xtypedef struct element {
- X ENTRY item;
- X struct element *next;
- X} ELEMENT;
- X
- Xextern ENTRY *hsearch();
- Xextern void hdestroy();
- Xextern int hcreate();
- END_OF_FILE
- if test 456 -ne `wc -c <'hsearch.h'`; then
- echo shar: \"'hsearch.h'\" unpacked with wrong size!
- fi
- # end of 'hsearch.h'
- fi
- echo shar: End of archive 2 \(of 4\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 4 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 4 archives.
- echo "Now do 'sh ./configure' or 'sh ./configure -prefix=PATH' (Default = /usr/local)"
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
- exit 0 # Just in case...
-