Article 13472 of alt.sources: Submitted-by: ljp@tiac.net Archive-name: orion-1.0/part07 ---- Cut Here and feed the following to sh ---- #!/bin/sh # This is `orion.07' (part 7 of orion-1.0). # Do not concatenate these parts, unpack them in order with `/bin/sh'. # File `orion-1.0/sargent/sarg_p.h' is being continued... # save_IFS="${IFS}" IFS="${IFS}:" gettext_dir=FAILED locale_dir=FAILED first_param="$1" for dir in $PATH do if test "$gettext_dir" = FAILED && test -f $dir/gettext \ && ($dir/gettext --version >/dev/null 2>&1) then set `$dir/gettext --version 2>&1` if test "$3" = GNU then gettext_dir=$dir fi fi if test "$locale_dir" = FAILED && test -f $dir/shar \ && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) then locale_dir=`$dir/shar --print-text-domain-dir` fi done IFS="$save_IFS" if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED then echo=echo else TEXTDOMAINDIR=$locale_dir export TEXTDOMAINDIR TEXTDOMAIN=sharutils export TEXTDOMAIN echo="$gettext_dir/gettext -s" fi if test ! -r _sh05649/seq; then $echo 'Please unpack part 1 first!' exit 1 fi shar_sequence=`cat _sh05649/seq` if test "$shar_sequence" != 7; then $echo 'Please unpack part' "$shar_sequence" 'next!' exit 1 fi if test ! -f _sh05649/new; then $echo 'x -' 'STILL SKIPPING' 'orion-1.0/sargent/sarg_p.h' else $echo 'x -' 'continuing file' 'orion-1.0/sargent/sarg_p.h' sed 's/^X//' << 'SHAR_EOF' >> orion-1.0/sargent/sarg_p.h && X#include X#include X#include X#include X#include X#include X#include X#include X#endif X X#if defined(SCO5) X#define _INKERNEL X#include X/* SCSI and harddrive related. */ X#include X#include X#include X#include X#include X#include X#include X#include X/* */ X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#undef _INKERNEL X#include X#define _INKERNEL X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#endif X X#include X#include X X/* X** Arguments to usage(). X*/ X#define SARG_USAGE_FULL 0 X#define SARG_USAGE_GOSEE 1 X X/* X** Globals. X*/ Xextern int flagSar; /* 0=sargent data, 1=sar data. */ Xextern struct nlist *recNlist; /* Current nlist array. */ Xextern size_t sizeNlist; /* Size of current nlist array. */ Xextern struct profile globalProfile; X X/* X** Each define represents a different kernel variable. X** Using these constants, memAddr() can be called to X** to determine the kernel address of a given X** variable. X*/ X#define SARG_VAR_NULL 0 X#define SARG_VAR_SYSINFO 1 X#define SARG_VAR_MINFO 2 X#define SARG_VAR_INODE 3 X#define SARG_VAR_FILE 4 X#define SARG_VAR_PROC 6 X#define SARG_VAR_FLOCK 7 X#define SARG_VAR_V 8 X#define SARG_VAR_SYSERR 9 X#define SARG_VAR_FREEMEM 10 X#define SARG_VAR_QUEUE 11 X#define SARG_VAR_MBLOCK 12 X#define SARG_VAR_NMBLOCK 13 X#define SARG_VAR_DBLOCK 14 X#define SARG_VAR_MSGINFO 15 X#define SARG_VAR_MSGQUE 16 X#define SARG_VAR_SEMINFO 17 X#define SARG_VAR_MOUNT 18 X#define SARG_VAR_NFSTYP 19 X#define SARG_VAR_FSINFO 20 X#define SARG_VAR_METS 21 X#define SARG_VAR_LOCALPTR 22 X#define SARG_VAR_LOCALOFF 23 X#define SARG_VAR_MODHEAD 24 X#define SARG_VAR_DISKCNT 25 X#define SARG_VAR_SD01DP 26 X#define SARG_VAR_SDSKSTATS 27 X#define SARG_VAR_DSKPROBE 28 X#define SARG_VAR_NDISKS 29 X#define SARG_VAR_DSKSTUFF 30 X#define SARG_VAR_STRSTAT 31 X#define SARG_VAR_ROOTVFS 32 X/* X** Local metrics ids. X*/ X#define SARG_VAR_STR 33 X#define SARG_VAR_CPU 34 X#define SARG_VAR_VMMETER 35 X#define SARG_VAR_BUF 36 X#define SARG_VAR_TTY 37 X#define SARG_VAR_SYSCALL 38 X#define SARG_VAR_VM 39 X#define SARG_VAR_KMEM 40 X X/* X** Record used in offset table. Maps variable constants X** with offsets into the sar and sargent nlist arrays. X*/ Xstruct recOffsets X{ X unsigned var; /* SARG_VAR_* constants. */ X off_t sar; /* Offset in sar nlist array. */ X off_t sargent; /* Offset in sargent nlist array. */ X}; X X/* X** Structure of global information. X*/ Xstruct profile X{ X void *p_scratch; X int p_fdDisk; X int p_fdMem; X time_t p_ts; X int p_cntEngines; X unsigned int X p_sar : 1, X p_debug : 1, X p_noround : 1, X p_findings : 1; X X struct var kern_var; X#if defined(ORION_FEAT_METRICS) X struct mets kern_mets; X#endif X}; X Xstruct sampEntry X{ X int (*s_sample)(int); X int (*s_init)(int); X const char *s_name; X}; X X/* X** String table. X*/ Xextern const char * const S_Empty; Xextern const char * const S_PathMem; Xextern const char * const S_PathSa; Xextern const char * const S_PathLsa; Xextern const char * const S_PathAddr; Xextern const char * const S_PathLaddr; Xextern const char * const S_PathKern; Xextern const char * const S_PrefixSa; Xextern const char * const S_PrefixLsa; Xextern const char * const S_Command; X#if defined(SVR4) || defined(UW2) || defined(SUN5) Xextern const char * const S_PathProc; X#endif X#ifdef WOLLONG32 Xextern const char * S_SymEstrms; X#endif Xextern const char * S_SymDummy; X Xextern const unsigned C_IntervalTime; Xextern const unsigned C_IntervalCount; X Xextern const int C_MaxNlist; Xextern const int C_MaxLnlist; X Xextern pid_t pids[]; X Xextern int diskInit( int ); Xextern int mountInit( int ); Xextern int netstatInit( int ); Xextern int procInit( int, int ); Xextern int streamsInit( int ); X#ifdef WOLLONG32 Xextern int wollongInit( int ); X#endif X#ifdef VENIX32 Xextern int venixInit( int ); X#endif X#if defined(VENIX32) Xextern int sampleSar( struct sa*, int, caddr_t ); X#endif Xextern int basic1Sample( int ); Xextern int procSample( int, int ); Xextern int basic1Sample( int ); Xextern int diskSample( int ); Xextern int ipcsSample( int ); Xextern int psSample( int ); Xextern int mountSample( int ); Xextern int tcpipSample( int ); Xextern int netstatSample( int ); Xextern int streamsSample( int ); Xextern int ttySample( int ); Xextern int memsysSample( int ); Xextern int moduleSample( int ); X#ifdef VENIX32 Xextern int venixSample( int ); X#endif X#ifdef WOLLONG32 Xextern int wollongSample( int ); X#endif X/* X** Kernel access subsystem. X*/ Xextern int memInit( void ); Xextern int memFetch( unsigned, void*, unsigned ); Xextern int memRead( int, caddr_t, void*, unsigned ); Xextern caddr_t memAddr( unsigned ); X#if defined(ORION_FEAT_METRICS) Xextern int metInit( void ); Xextern void *metFetch( unsigned ); X#endif X#if defined(ORION_FEAT_SYSINFO) Xextern void siReset( void ); Xextern void *siFetch( unsigned ); X#endif X Xextern int procAdd( pid_t ); Xextern int diskWrite( void*, unsigned, unsigned ); X X#endif SHAR_EOF $echo 'File' 'orion-1.0/sargent/sarg_p.h' 'is complete' && chmod 0664 'orion-1.0/sargent/sarg_p.h' || $echo 'restore of' 'orion-1.0/sargent/sarg_p.h' 'failed' if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then md5sum -c << SHAR_EOF >/dev/null 2>&1 \ || $echo 'orion-1.0/sargent/sarg_p.h:' 'MD5 check failed' ff77cebed5e3e1fc3c2a2cd9daeaa255 orion-1.0/sargent/sarg_p.h SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'orion-1.0/sargent/sarg_p.h'`" test 6784 -eq "$shar_count" || $echo 'orion-1.0/sargent/sarg_p.h:' 'original size' '6784,' 'current size' "$shar_count!" fi fi # ============= orion-1.0/sargent/sarg.c ============== if test -f 'orion-1.0/sargent/sarg.c' && test "$first_param" != -c; then $echo 'x -' SKIPPING 'orion-1.0/sargent/sarg.c' '(file already exists)' rm -f _sh05649/new else > _sh05649/new $echo 'x -' extracting 'orion-1.0/sargent/sarg.c' '(text)' sed 's/^X//' << 'SHAR_EOF' > 'orion-1.0/sargent/sarg.c' && X X/* X** ---------------------------------------------------------------- X** X** Copyright (c) 1994,1995,1996 by Larry Plona X** X** This file is part of the Orion software package. The Orion X** software package is copyright by its author, Larry Plona. This X** software, both source code and prepared binaries, may be X** freely distributed as long as all copyright notices remain X** intact and this software is not sold or packaged with other X** commercial software. X** X** No warranty of any kind attached with this software. It is X** supplied as is. X** X** ---------------------------------------------------------------- X*/ X X#include"sarg_p.h" X Xstatic caddr_t allocScratch( void ); Xstatic void usage( unsigned ); X X/* X** Ordered by type. So this table should always have X** SARG_MAX_RTYP entries. X*/ Xstruct sampEntry sampTable[] = X{ X { NULL, NULL, NULL }, X { basic1Sample, NULL, "Basic1" }, X { NULL, NULL, "Reboot" }, X { procSample, procInit, "Proc" }, X#ifdef WOLLONG32 X { wollongSample, wollongInit, "Wollong" }, X#else X { NULL, NULL, NULL }, X#endif X { netstatSample, netstatInit, "Netstat" }, X { mountSample, mountInit, "Mount" }, X { psSample, NULL, "Ps" }, X { ipcsSample, NULL, "Ipcs" }, X#ifdef VENIX32 X { venixSample, venixInit, "VENIX" }, X#else X { NULL, NULL, NULL }, X#endif X { streamsSample, streamsInit, "STREAMS" }, X { ttySample, NULL, "TTY" }, X { memsysSample, NULL, "Memsys" }, X#if defined(SVR4) || defined(UW2) X { moduleSample, NULL, "Module" }, X#else X { NULL, NULL, NULL }, X#endif X { diskSample, diskInit, "Disk" } X}; X X/* X** Globals. X*/ X X/* X** String table. X*/ Xconst char * const S_Empty = ""; Xconst char * const S_PathMem = "/dev/kmem"; Xconst char * const S_PathSa = "/usr/adm/sa"; Xconst char * const S_PathLsa = "/usr/adm/sa"; Xconst char * const S_PathAddr = "/tmp/sa.adrfl"; Xconst char * const S_PathLaddr = "/tmp/ssa.adrfl"; X#if defined(SVR4) || defined(UW2) || defined(SCO5) Xconst char * const S_PathKern = "/stand/unix"; X#endif X#if defined(VENIX32) || defined(SVR3) Xconst char * const S_PathKern = "/unix"; X#endif X#if defined(SUN5) Xconst char * const S_PathKern = "/kernel/unix"; X#endif X#if defined(ORION_FEAT_PROCFS) Xconst char * const S_PathProc = "/proc"; X#endif Xconst char * const S_PrefixSa = "sa"; Xconst char * const S_PrefixLsa = "ssa"; Xconst char * const S_Command = "sargent"; Xconst char * const S_VerDbg = SARG_STR_VER; Xconst char * const S_RcsHeader = "$Header: /home2/ljp/src/src-ljp/product/orion/sargent/sarg.c,v 1.5 1996/06/24 06:15:08 ljp Exp $"; X Xconst unsigned C_IntervalTime = 10; Xconst unsigned C_IntervalCount = 1; X Xstruct profile globalProfile; Xchar globalEnable[SARG_MAX_RTYP+1]; X Xmain( int argc, const char *argv[] ) X{ X char pathData[1023+1]; X const char *strTimeBegin, *strTimeEnd; X int fdMem, fdData; X int i; X int flagReboot, flagAllday, flagLock, flagPriority; X unsigned countInterval, timeInterval; X unsigned priority; X time_t timeWait, timeEnd; X void *scratch; X X /* X ** Global flag, determining whether sar or Sargent data X ** is being used. Can be adjusted through command line. X */ X globalProfile.p_sar = 0; X X /* X ** Global flag determinig whether or not debug output X ** is written to standard out. Can be adjusted through X ** the command line. X */ X globalProfile.p_debug = 0; X X /* X ** By default, when a starting time is not given, sampling begins X ** at the "top" of the next interval. A command line option can X ** be used to disable this. For example, if the interval is one X ** hour, it may not be desirable to wait for the next hour to X ** begin before sampling. X */ X globalProfile.p_noround = 0; X X /* X ** Indicate that the kernel mets structure has not yet X ** been read in. X */ X#if defined(ORION_FEAT_METRICS) X globalProfile.kern_mets.mets_native_units.mnu_hz = 0; X#endif X X /* X ** VENIX version can lock itself in core and change X ** real time priorities. X */ X#ifdef VENIX32 X flagLock = 0; X flagPriority = 0; X priority = RT_PRI_LOW; X#endif X X /* X ** Start and end times for sample collection. X */ X strTimeBegin = strTimeEnd = NULL; X X /* X ** Number of samples and seconds between samples. X */ X countInterval = timeInterval = 0; X X /* X ** File where sample data is placed. X */ X pathData[0] = '\0'; X X /* X ** Number of seconds to wait before sampling starts. X */ X timeWait = 0; X X /* X ** List of process ids. X */ X for( i=0; i= argc ) X { X fputs( "Need argument to \"-f\".\n", stdout ); X usage( SARG_USAGE_GOSEE ); X exit( 1 ); X } X strcpy( pathData, argv[i] ); X continue; X } X if( !strcmp("-s",argv[i]) ) X { X ++i; X if( i >= argc ) X { X fputs( "Need argument to \"-s\".\n", stdout ); X usage( SARG_USAGE_GOSEE ); X exit( 1 ); X } X strTimeBegin = argv[i]; X continue; X } X if( !strcmp("-e",argv[i]) ) X { X ++i; X if( i >= argc ) X { X fputs( "Need argument to \"-e\".\n", stdout ); X usage( SARG_USAGE_GOSEE ); X exit( 1 ); X } X strTimeEnd = argv[i]; X continue; X } X if( !strcmp("-c",argv[i]) ) X { X ++i; X if( i >= argc ) X { X fputs( "Need argument to \"-c\".\n", stdout ); X usage( SARG_USAGE_GOSEE ); X exit( 1 ); X } X countInterval = atoi( argv[i] ); X continue; X } X if( !strcmp("-t",argv[i]) ) X { X ++i; X if( i >= argc ) X { X fputs( "Need argument to \"-t\".\n", stdout ); X usage( SARG_USAGE_GOSEE ); X exit( 1 ); X } X timeInterval = atoi( argv[i] ); X continue; X } X if( !strcmp("-p",argv[i]) ) X { X ++i; X if( i >= argc ) X { X fputs( "Need argument to \"-p\".\n", stdout ); X usage( SARG_USAGE_GOSEE ); X exit( 1 ); X } X procAdd( (pid_t)atoi(argv[i]) ); X continue; X } X if( !strcmp("-prio",argv[i]) ) X { X ++i; X if( i >= argc ) X { X fputs( "Need argument to \"-prio\".\n", stdout ); X usage( SARG_USAGE_GOSEE ); X exit( 1 ); X } X ++flagPriority; X priority = atoi( argv[i] ); X continue; X } X if( !strcmp("-sar",argv[i]) ) X { X#if defined(VENIX32) || defined(SVR3) || defined(SVR4) X globalProfile.p_sar = 1; X continue; X#endif X#if defined(UW2) X fputs( "UnixWare 2 version does not support sar data.\n", X stdout ); X exit( 1 ); X#endif X } X if( !strcmp("-v",argv[i]) ) X { X fputs( "Debugging on.\n", stdout ); X globalProfile.p_debug = 1; X continue; X } X if( !strcmp("-V",argv[i]) ) X { X globalProfile.p_findings = 1; X continue; X } X if( !strcmp("-reboot",argv[i]) ) X { X ++flagReboot; X continue; X } X if( !strcmp("-lock",argv[i]) ) X { X#ifndef VENIX32 X fputs( "Only VENIX 3.2 version can lock itself.\n", stdout ); X continue; X#else X ++flagLock; X continue; X#endif X } X if( !strcmp("-noround",argv[i]) ) X { X globalProfile.p_noround = 1; X continue; X } X if( !strcmp("-allday",argv[i]) ) X { X ++flagAllday; X continue; X } X if( !strcmp("-wollong",argv[i]) ) X { X#ifndef WOLLONG32 X fputs( "Wollongong SVR3 driver support was not built.\n", X stdout ); X continue; X#else X globalEnable[SARG_RTYP_WOLLONG] = 1; X continue; X#endif X } X if( !strcmp("-venix",argv[i]) ) X { X#ifndef VENIX32 X fputs( "VENIX 3.2 support was not built.\n", X stdout ); X continue; X#else X globalEnable[SARG_RTYP_VENIX] = 1; X continue; X#endif X } X if( !strcmp("-memsys",argv[i]) ) X { X globalEnable[SARG_RTYP_MEMSYS] = 1; X continue; X } X if( !strcmp("-disk",argv[i]) ) X { X globalEnable[SARG_RTYP_DISK] = 1; X continue; X } X if( !strcmp("-module",argv[i]) ) X { X#if defined(SVR4) || defined(UW2) X globalEnable[SARG_RTYP_MODULE] = 1; X#else X fputs( "Module record type not supported on this platform.\n", X stdout ); X#endif X continue; X } X if( !strcmp("-mount",argv[i]) ) X { X globalEnable[SARG_RTYP_MOUNT] = 1; X continue; X } X if( !strcmp("-ps",argv[i]) ) X { X globalEnable[SARG_RTYP_PS] = 1; X continue; X } X if( !strcmp("-netstat",argv[i]) ) X { X globalEnable[SARG_RTYP_NETSTAT] = 1; X continue; X } X if( !strcmp("-ipcs",argv[i]) ) X { X globalEnable[SARG_RTYP_IPCS] = 1; X continue; X } X if( !strcmp("-streams",argv[i]) ) X { X globalEnable[SARG_RTYP_STREAMS] = 1; X continue; X } X if( !strcmp("-tty",argv[i]) ) X { X globalEnable[SARG_RTYP_TTY] = 1; X continue; X } X if( !strcmp("-help",argv[i]) || !strcmp("-?",argv[i]) ) X { X usage( SARG_USAGE_FULL ); X continue; X } X if( !strcmp("-ver",argv[i]) || !strcmp("-?",argv[i]) ) X { X fprintf( stdout, "Version of Orion is %s.\n", S_VerDbg ); X exit( 0 ); X } X if( argv[i][0] == '-' ) X { X fprintf( stdout, "Unrecognized option, \"%s\".\n", argv[i] ); X usage( SARG_USAGE_GOSEE ); X exit( 1 ); X } X fprintf( stdout, "Unrecognized argument, \"%s\".\n", argv[i] ); X usage( SARG_USAGE_GOSEE ); X exit( 1 ); X } X X /* X ** Rationalize the command line settings. X */ X X /* X ** When sampling until the end of the day, both a count and a X ** time interval cannot be used. X */ X if( flagAllday && countInterval && timeInterval ) X { X fputs( X "When using \"-allday\", can not specify both count and" X " interval.\n", X stdout ); X usage( SARG_USAGE_GOSEE ); X exit( 1 ); X } X X /* X ** When writing a marker, can not perform sampling. X */ X if( flagReboot && (flagAllday||countInterval||timeInterval) ) X { X fputs( "Can not use any options with \"-reboot\".\n", stdout ); X usage( SARG_USAGE_GOSEE ); X exit( 1 ); X } X X /* X ** If sampling until the end of the day and neither a count of X ** samples nor a time between samples was given, use the default X ** time between samples (the other will be calculated). X */ X if( flagAllday && !countInterval && !timeInterval ) X timeInterval = C_IntervalTime; X X /* X ** If not sampling until the end of the day, make sure that both X ** the count of samples and the time between samples have values. X */ X if( !flagAllday && !flagReboot && !countInterval ) X countInterval = C_IntervalCount; X if( !flagAllday && !flagReboot && !timeInterval ) X timeInterval = C_IntervalTime; X X /* X ** According to the sar(1M) man page, intervals under five X ** seconds affect the data. This probably ought to be a X ** little higher. X */ X if( !flagReboot && timeInterval<5 ) X { X fputs( "Interval time cannot be less than 5 seconds.\n", stdout ); Xfprintf( stdout, "Interval is %d.\n", timeInterval ); X usage( SARG_USAGE_GOSEE ); X exit( 1 ); X } X X /* X ** If no filename was given to receive the sample data, create X ** one using the default naming scheme. X */ X if( pathData[0] == '\0' ) X { X time_t timeCurr; X struct tm *recTimeCurr; X X timeCurr = time( NULL ); X recTimeCurr = localtime( &timeCurr ); X X sprintf( pathData, "%s/%s%.2d", X globalProfile.p_sar?S_PathSa:S_PathLsa, X globalProfile.p_sar?S_PrefixSa:S_PrefixLsa, X recTimeCurr->tm_mday ); X } X X if( globalProfile.p_findings ) X { X fprintf( stdout, "size of struct nlist is %d.\n", X sizeof(struct nlist) ); X fprintf( stdout, "size of struct proc is %d.\n", X sizeof(struct proc) ); X#if defined(VENIX32) || defined(SVR3) || defined(SVR4) X fprintf( stdout, "size of struct sa is %d.\n", X sizeof(struct sa) ); X#endif X if( !(globalProfile.p_sar) ) X { X fprintf( stdout, "size of struct sargBasic1 is %d.\n", X sizeof(struct sargBasic1) ); X fprintf( stdout, "size of struct sargProc is %d.\n", X sizeof(struct sargProc) ); X } X } X X /* X ** Initialize kernel structure address lookup and caching X ** routines. X */ X if( !memInit() ) X exit( 1 ); X fdMem = globalProfile.p_fdMem; X X /* X ** Append to the data file. X */ X if( (fdData=open(pathData,O_WRONLY|O_APPEND|O_CREAT|O_SYNC,0644)) == -1 ) X { X close( fdMem ); X fprintf( stdout, "Bad open(2) of \"%s\" (sample data). %s.\n", X pathData, sys_errlist[errno] ); X exit( 1 ); X } X globalProfile.p_fdDisk = fdData; X X /* X ** Allocate scratch pad memory. X ** X ** Populate the global copy of the kernel var structure. X */ X if( (scratch=allocScratch()) == NULL ) X { X close( fdData ); X close( fdMem ); X exit( 1 ); X } X globalProfile.p_scratch = scratch; X X /* X ** Call the initialization routines for each X ** enabled sample type. X */ X for( i=0; itm_hour*3600) + (recTimeCurr->tm_min*60) + X recTimeCurr->tm_sec; X X /* X ** If a start time was given, determine the number of seconds to X ** wait before it comes around. Note that rounding of start time X ** will not take place. X */ X if( strTimeBegin != NULL ) X { X hour = min = sec = 0; X sscanf( strTimeBegin, "%d:%d:%d", &hour, &min, &sec ); X timeBegin = (time_t)(sec+(min*60)+(hour*3600)); X if( timeNow < timeBegin ) X timeWait = timeBegin - timeNow; X } X X /* X ** If an end time was given, determine the number of samples X ** need to cover this time. Note that "-allday" can not have X ** been given (checked for above). X */ X if( strTimeEnd != NULL ) X { X hour = min = sec = 0; X sscanf( strTimeEnd, "%d:%d:%d", &hour, &min, &sec ); X timeEnd = (time_t)(sec+(min*60)+(hour*3600)); X if( timeEnd= (22*3600)+(30*60) ) X { X fputs( "Too close to midnight for \"-allday\".\n", stdout ); X free( scratch ); X close( fdData ); X close( fdMem ); X exit( 0 ); X } X#endif X X sec = timeEnd - timeNow; X X if( timeInterval ) X countInterval = sec / timeInterval; X else X { X timeInterval = sec / countInterval; X if( timeInterval < 5 ) X { X fputs( "Interval time cannot be less than 5 seconds.\n", X stdout ); X free( scratch ); X close( fdData ); X close( fdMem ); X exit( 0 ); X } X } X } X X /* X ** Wait for the "top" of the next interval. For example, if X ** the interval is 5 seconds and the current time is X ** 13:08:08, wait for 13:08:05. X ** X ** Do not do this if "-noround" or "-s" are specified. X */ X if( strTimeBegin==NULL && !(globalProfile.p_noround) ) X { X timeWait = timeInterval - X (timeNow-((timeNow/timeInterval)*timeInterval)); X if( timeWait >= timeInterval ) X timeWait = 0; X } X X if( globalProfile.p_debug ) X { X fprintf( stdout, "%d samples. %d seconds before starting.\n", X countInterval, timeWait ); X } X } X X /* X ** Finally. Perform the given number of samples at the X ** given interval. X */ X { X int i; X void *proc; X unsigned interval; X#if defined(VENIX32) || defined(SVR3) || defined(SVR4) X struct sa recSar; X#endif X X if( timeWait ) X sleep( timeWait ); X X if( globalProfile.p_debug ) X { X fprintf( stdout, "Making %d samples, %d seconds apart.\n", X countInterval, timeInterval ); X } X for( interval=0; interval= countInterval ) X break; X X /* Wait for next sampling time. */ X sleep( timeInterval ); X } X } X X free( scratch ); X close( fdData ); X close( fdMem ); X exit( 0 ); X} X X/* X** allocScratch() X** X** Currently this function works for both sar and Sargent data. X*/ Xstatic caddr_t allocScratch( void ) X{ X caddr_t ptr; X size_t max; X X max = 0; X X if( !memFetch(SARG_VAR_V,(void*)&globalProfile.kern_var, X sizeof(globalProfile.kern_var)) ) X { X fputs( "Could not fetch \"var\".\n", stdout ); X return NULL; X } X X#if !defined(UW2) X { X int nmblock; X struct msginfo msginfo; X X if( !memFetch(SARG_VAR_NMBLOCK,(void*)&nmblock,sizeof(nmblock)) ) X { X fputs( "Could not fetch \"nmblock\".\n", stdout ); X return NULL; X } X max = maximum( max, nmblock, sizeof(mblk_t) ); X X if( !memFetch(SARG_VAR_MSGINFO,(void*)&msginfo, X sizeof(struct msginfo)) ) X { X fputs( "Could not fetch \"msginfo\".\n", stdout ); X return NULL; X } X max = maximum( max, msginfo.msgmni, sizeof(struct msqid_ds) ); X X max = maximum( max, globalProfile.kern_var.v_proc, X sizeof(struct proc) ); X max = maximum( max, globalProfile.kern_var.v_inode, X sizeof(struct inode) ); X max = maximum( max, globalProfile.kern_var.v_file, X sizeof(struct file) ); X max = maximum( max, globalProfile.kern_var.v_nqueue, X sizeof(struct queue) ); X max = maximum( max, globalProfile.kern_var.v_mount, X sizeof(struct mount) ); X } X#endif X X#if defined(UW2) X max = maximum( max, 1, sizeof(struct pstatus) ); X#endif X X#if defined(SVR4) || defined(UW2) || defined(SUN5) X { X struct sargModule sargModule; X X max = maximum( max, 64, sizeof(sargModule.loaded[0]) ); X } X#endif X X if( globalProfile.p_debug ) X fprintf( stdout, "Allocating %d bytes for scratch.\n", max ); X X if( (ptr=(caddr_t)malloc(max)) == NULL ) X { X fputs( "Bad malloc(3).\n", stdout ); X return NULL; X } X X return ptr; X} X Xint diskWrite( void *buf, unsigned len, unsigned type ) X{ X int rc; X struct sargHdr recHdr; X X recHdr.h_type = type; X recHdr.h_ts = globalProfile.p_ts; X recHdr.h_len = len; X if( (rc=write(globalProfile.p_fdDisk,&recHdr,sizeof(recHdr))) == -1 ) X { X fprintf( stdout, "Bad write(). %s.\n", sys_errlist[errno] ); X return 0; X } X if( rc != sizeof(recHdr) ) X { X fprintf( stdout, "Bad write(). Only wrote %d of %d.\n", rc, len ); X return 0; X } X X if( (rc=write(globalProfile.p_fdDisk,buf,len)) == -1 ) X { X fprintf( stdout, "Bad write(). %s.\n", sys_errlist[errno] ); X return 0; X } X if( rc != len ) X { X fprintf( stdout, "Bad write(). Only wrote %d of %d.\n", rc, len ); X return 0; X } X X return 1; X} X Xstatic void usage( unsigned type ) X{ X if( type == SARG_USAGE_GOSEE ) X { X fprintf( stdout, X "Use \"%s -help\" or \"%s -?\" for details.\n", X S_Command, S_Command ); X return; X } X X fprintf( stdout, X "usage: %s [-s