/*
 * $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
 *
 */

/* 	Copyright (c) 1984 AT&T	*/
/*	  All Rights Reserved  	*/

/*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*/
/*	The copyright notice above does not evidence any   	*/
/*	actual or intended publication of such source code.	*/

#ident	"$Header: sar.c 1.5 90/08/31 $"

/*
	sar.c - It generates a report either
		from an input data file or
		by invoking sadc to read system activity counters 
		at the specified intervals.
	usage: sar [-ubdycwaqvmpr] [-o file] t [n]    or
	       sar [-ubdycwaqvmpr][-s hh:mm][-e hh:mm][-i ss][-f file]
*/

/* $Log:	sar.c,v $
 */

#include <stdio.h>
#include <sys/param.h>
#include <ctype.h>
#include <time.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/fcntl.h>
#include <sys/flock.h>
#include <sys/wait.h>
#include <string.h>
#include "sysinfo.h"
#include "sa.h"

struct sa nx,ox,ax,bx;
struct tm *localtime(), *curt,args,arge;
struct utsname name;
int	sflg, eflg, iflg, oflg, fflg;
#ifdef	RFS_SUPPORT
int	dflg=0;
float	Isyscall, Isysread, Isyswrite, Isysexec, Ireadch, Iwritech;
float	Osyscall, Osysread, Osyswrite, Osysexec, Oreadch, Owritech;
float 	Lsyscall, Lsysread, Lsyswrite, Lsysexec, Lreadch, Lwritech;
#endif	/* RFS_SUPPORT */
int	realtime;
int	passno;
int	t=0;
int	n=0;
int	rcnt=0;

double 	magic = 4.294967296e9;

int	recsz, ndevs;
int	tabflg;
char	options[16],fopt[16];
float	tdiff;
float	st_time, etime, isec;
int	fin, fout, childid;
int	pipedes[2];
char	arg1[10], arg2[10];

extern  int optind;
extern  char *optarg;
extern void exit(), perror();
extern off_t lseek();
extern time_t time();

main (argc,argv)
char	**argv;
int	argc;
{
	char    flnm[MAXPATHLEN];	/* pathname may be formed dynamically */
	char	*ofile;			/* pathname assigned from optarg */
	int	c;
	char	cc;
	long    temp;
	int	jj=0;

/*      process options with arguments and pack options 
	without arguments  */
#ifdef	RFS_SUPPORT
	while ((c = getopt(argc,argv,"uybdvcwaqmprACDSo:s:e:i:f:")) != EOF) {
#else
	while ((c = getopt(argc,argv,"uybdvcwaqmprAo:s:e:i:f:")) != EOF) {
#endif	/* RFS_SUPPORT */
		switch (cc = c) {
#ifdef	RFS_SUPPORT
		case 'D':
			dflg++;
			break;
#endif	/* RFS_SUPPORT */
		case 'o':
			oflg++;
			ofile = optarg;
			break;
		case 's':
			if (sscanf(optarg,"%d:%d:%d",
			&args.tm_hour, &args.tm_min, &args.tm_sec) < 1)
				pillarg(cc);
			else {
				sflg++,
				st_time = args.tm_hour*3600.0 +
					args.tm_min*60.0 +
					args.tm_sec;
			}
			break;
		case 'e':
			if(sscanf(optarg,"%d:%d:%d",
			&arge.tm_hour, &arge.tm_min, &arge.tm_sec) < 1)
				pillarg(cc);
			else {
				eflg++;
				etime = arge.tm_hour*3600.0 +
					arge.tm_min*60.0 +
					arge.tm_sec;
			}
			break;
		case 'i':
			if (sscanf(optarg,"%f",&isec) < 1)
				pillarg(cc);
			else{
			if (isec > 0.0)
				iflg++;
			}
			break;
		case 'f':
			fflg++;
			(void) strcpy(flnm, optarg);
			break;
		case '?':
#ifdef	RFS_SUPPORT
			(void) fprintf(stderr,"usage: sar [-ubdycwaqvmprACDS][-o file] t [n]\n");
			(void) fprintf(stderr,"       sar [-ubdycwaqvmprACDS][-s hh:mm][-e hh:mm][-i ss][-f file]\n");
#else
			(void) fprintf(stderr,"usage: sar [-ubdycwaqvmprA][-o file] t [n]\n");
			(void) fprintf(stderr,"       sar [-ubdycwaqvmprA][-s hh:mm][-e hh:mm][-i ss][-f file]\n");
#endif	/* RFS_SUPPORT */
			exit(2);
			break;
		case 'u':
			(void) strncat(options,&cc,1);
			break;
		default:
			(void) strncat(options,&cc,1);
			break;
		}
	}

	/*   Are starting and ending times consistent?  */
	if ((sflg) && (eflg) && (etime <= st_time))
		pmsgexit("etime <= st_time");

	/*
	 * Determine if t and n arguments are given,
	 * and whether to run in real time or from a file
	 */
	switch (argc - optind) {
	case 0:		/*   Get input data from file   */
		if(fflg == 0) {
			temp = time((long *) 0);
			curt = localtime(&temp);
			(void) sprintf(flnm,"/usr/adm/sa/sa%.2d", curt->tm_mday);
		}
		if((fin = open(flnm, 0)) == -1) {
			(void) fprintf(stderr, "sar:Can't open %s\n", flnm);
			exit(1);
		}
		break;
	case 1:		/*   Real time data; one cycle   */
		realtime++;
		t = atoi(argv[optind]);
		n = 2;
		break;
	case 2:		/*   Real time data; specified cycles   */
	default:
		realtime++;
		t = atoi(argv[optind]);
		n = 1 + atoi(argv[optind+1]);
		break;
	}

	/*	"u" is default option to display cpu utilization   */

	if (strlen(options) == 0)
		(void) strcpy(options, "u");

	/*    'A' means all data options   */

	if (strchr(options, 'A') != NULL) {
#ifdef	RFS_SUPPORT
		(void) strcpy(options, "udqbwcayvmprCS");
		dflg++;
#else
		(void) strcpy(options, "udqbwcayvmpr");
#endif	/* RFS_SUPPORT */
	}
#ifdef	RFS_SUPPORT
	else if ( (dflg)
	     && (strchr(options,'u') == NULL)
	     && (strchr(options,'b') == NULL)
	     && (strchr(options,'c') == NULL) ) strcat(options,"u");
#endif	/* RFS_SUPPORT */

	if(realtime) {
	/*	Get input data from sadc via pipe   */
		if((t <= 0) || (n < 2))
			pmsgexit("args t & n <= 0");
		(void) sprintf(arg1,"%d", t);
		(void) sprintf(arg2,"%d", n);
		if (pipe(pipedes) == -1)
			perrexit();
		if ((childid = fork()) == 0){	/*  child:   */
			(void) close(1); /* shift pipedes[write] to stdout */
			if (dup(pipedes[1]) == -1)
				perrexit();
			if (execlp ("/usr/lib/sa/sadc","/usr/lib/sa/sadc",arg1,arg2,0) == -1)
				perrexit();
		}		/*   parent:   */
		fin = pipedes[0];
		(void) close(pipedes[1]);	/*   Close unused output   */
	}

	if(oflg) {
		if(strcmp(ofile, flnm) == 0)
			pmsgexit("ofile same as ffile");
		fout = creat(ofile, 00644);
	}

/*      read the header record and compute record size */
	if (read(fin, (char *) &ndevs, sizeof(ndevs)) < 0)
		perrexit();
	recsz = sizeof(struct sa) - sizeof(nx.devio) +
		ndevs * sizeof(nx.devio[0]);

	if(oflg)
		if (write(fout, (char *)&ndevs, sizeof(ndevs)) != sizeof(ndevs))
			perrexit();

	if(realtime) {
		/*   Make single pass, processing all options   */
		(void) strcpy(fopt, options);
		passno++;
		prpass();
		(void) kill(childid, 2);
		if (wait((int *) 0) == -1)
			perrexit();
	} else {
		/*   Make multiple passes, one for each option   */
		while(strlen(strncpy(fopt,&options[jj++],1)) > 0) {
			if (lseek(fin, (long)(sizeof ndevs), 0) == -1)
				perrexit();
			passno++;
			prpass();
		}
	}
	return(0);
}

/*****************************************************/

/*	Read records from input, classify, and decide on printing   */
prpass(){
	int	lines=0;
	int recno=0;
	float tnext=0;
	float trec;

	if(sflg)	tnext = st_time;
	while(read(fin, &nx, (unsigned)recsz) > 0) {
		curt = localtime(&nx.ts);
		trec =    curt->tm_hour * 3600.0
			+ curt->tm_min * 60.0
			+ curt->tm_sec;
		if((recno == 0) && (trec < st_time))
			continue;
		if ((eflg) && (trec > etime))
			break;
		if ((oflg) && (passno == 1))
			if (write(fout, &nx, (unsigned)recsz) != recsz)
				perrexit();
		if (recno == 0) {
			if(passno == 1) {
				if (uname(&name) == -1)
					perrexit();
				(void) printf("\n%s %s %s %s %s    %.2d/%.2d/%.2d\n",
					name.sysname,
					name.nodename,
					name.release,
					name.version,
					name.machine,
					curt->tm_mon + 1,
					curt->tm_mday,
					curt->tm_year);
			}
			prthdg();
			recno = 1;
			if((iflg) && (tnext == 0))
				tnext = trec;
		}
		/*
		 * Don't need to remove '+ nx.si.cpu[3]' term below as
		 * sadc still sets it negative for the dummy record
		 */
		if ((nx.si.cpu[0] + nx.si.cpu[1] + nx.si.cpu[2] + nx.si.cpu[3]) < 0) {
		/*  This dummy record signifies system restart
		    New initial values of counters follow in next record  */
			prttim();
			(void) printf("\tunix restarts\n");
			recno = 1;
			continue;
		}
		if((iflg) && (trec < tnext))
			continue;
		if(recno++ > 1) {
			tdiff =   nx.si.cpu[0] - ox.si.cpu[0]
				+ nx.si.cpu[1] - ox.si.cpu[1]
				+ nx.si.cpu[2] - ox.si.cpu[2];
				/*
				 * Remove the term below as wait time (cpu[3])
				 * is accumulated separately and is included
				 * in idle.
				 * + nx.si.cpu[3] - ox.si.cpu[3];
				 */
			if(tdiff <= 0) 
				continue;
			
			prtopt();	/*  Print a line of data  */
			lines++;
		}
		ox = nx;		/*  Age the data	*/
		if(isec > 0)
			while(tnext <= trec)
				tnext += isec;
	}
	rcnt=recno;
	if(lines > 1)
		prtavg();
	ax = bx;		/*  Zero out the accumulators   */
}

/************************************************************/

/*      print time label routine	*/
prttim()
{
	curt = localtime(&nx.ts);
	(void) printf("%.2d:%.2d:%.2d",
		curt->tm_hour,
		curt->tm_min,
		curt->tm_sec);
	tabflg = 1;
}

/***********************************************************/

/*      test if 8-spaces to be added routine    */
tsttab()
{
	if (tabflg == 0) 
		(void) printf("        ");
	else
		tabflg = 0;
}

/************************************************************/

/*      print report heading routine    */
prthdg()
{
	int	jj=0;
	char	ccc;

	(void) printf("\n");
	prttim();
	while((ccc = fopt[jj++]) != NULL)
	switch(ccc){
	case 'u':
		tsttab();
#ifdef	RFS_SUPPORT
		if (dflg) {
			(void) printf(" %7s %7s %7s %7s %7s\n",
				"%usr",
				"%sys",
				"%sys",
				"%wio",
				"%idle");
			tsttab();
			(void) printf(" %7s %7s %7s\n",
				"",
				"local",
				"remote");
			break;
		}
#endif	/* RFS_SUPPORT */
		(void) printf(" %7s %7s %7s %7s\n",
			"%usr",
			"%sys",
			"%wio",
			"%idle");
		break;
	case 'y':
		tsttab();
		(void) printf(" %7s %7s %7s %7s %7s %7s\n",
			"rawch/s",
			"canch/s",
			"outch/s",
			"rcvin/s",
			"xmtin/s",
			"mdmin/s");
		break;
	case 'b':
		tsttab();
		(void) printf(" %7s %7s %7s %7s %7s %7s %7s %7s\n",
			"bread/s",
			"lread/s",
			"%rcache",
			"bwrit/s",
			"lwrit/s",
			"%wcache",
			"pread/s",
			"pwrit/s");
		break;
	case 'd':
		tsttab();
		(void) printf(" %7s %7s %7s %7s %7s %7s %7s\n",
			"device",
			"%busy",
			"avque",
			"r+w/s",
			"blks/s",
			"avwait",
			"avserv");
		break;
	case 'v':
		tsttab();
		(void) printf("  %s  %s  %s  %s\n",
			"proc-sz ov",
			"inod-sz ov",
			"file-sz ov",
			"lock-sz   ");
		break;
	case 'c':
		tsttab();
		(void) printf(" %7s %7s %7s %7s %7s %8.8s %8.8s\n",
			"scall/s",
			"sread/s",
			"swrit/s",
			"fork/s",
			"exec/s",
			"rchar/s",
			"wchar/s");
		break;
	case 'w':
		tsttab();
		(void) printf(" %7s %7s %7s %7s %7s\n",
			"swpin/s",
			"bswin/s",
			"swpot/s",
			"bswot/s",
			"pswch/s");
		break;
	case 'a':
		tsttab();
		(void) printf(" %7s %7s %7s\n",
			"iget/s",
			"namei/s",
			"dirbk/s");
		break;
	case 'q':
		tsttab();
		(void) printf(" %7s %7s %7s %7s\n",
			"runq-sz",
			"%runocc",
			"swpq-sz",
			"%swpocc");
		break;
	case 'm':
		tsttab();
		(void) printf(" %7s %7s\n",
			"msg/s",
			"sema/s");
		break;
	case 'r':
		tsttab();
		(void) printf(" %7s %7s\n",
			"freemem",
			"freeswp");
		break;
#ifdef	RFS_SUPPORT
	case 'S':
		tsttab();
		(void) printf("%11s %9s %9s %9s %9s\n",
			"serv/lo-hi",
			"request",
			"request",
			"server",
			"server");
		tsttab();
		(void) printf("%6s %d %1s %d %9s %9s %9s %9s\n",
			"",
			nx.minserve,
			"-",
			nx.maxserve,
			"%busy",
			"avg lgth",
			"%avail",
			"avg avail");
		break;
	case 'C':
		tsttab();
		(void) printf(" %11s %11s %11s %11s %11s %11s\n",
			"snd-inv/s",
			"snd-msg/s",
			"rcv-inv/s",
			"rcv-msg/s",
			"dis-bread/s",
			"blk-inv/s");
		break;
#endif	/* RFS_SUPPORT */
	case 'p':
		tsttab();
		(void) printf(" %7s %7s %7s %7s\n",
			"vflt/s",
			"pflt/s",
			"pgfil/s",
			"rclm/s");
		break;
	}
	if(jj > 2)	(void) printf("\n");
}

/**********************************************************/

/*      print options routine   */
prtopt()
{
	register int ii, j;
	int jj=0;
	char	ccc;
	time_t cpu[5];

	if(strcmp(fopt, "d") == 0)   (void) printf("\n");
	prttim();
	/*
	 * Calculate cpu time in the interval happened and account for
	 * wait time being a subset of idle time
	 */
	for (ii = 0; ii < 4; ii++)
		cpu[ii] = nx.si.cpu[ii] - ox.si.cpu[ii];

	/*
	 * Wait time is a subset of idle time.  However, the way wait time
	 * is calculated in DYNIX/ptx, it may actually be larger than the
	 * idle time.  We know that the sum of user, sys, and idle is
	 * correct so force wait to be <= idle as kept by the OS and adjust
	 * idle appropriately.
	 */
	if (cpu[CPU_IDLE] < cpu[CPU_WAIT]) {
		cpu[CPU_WAIT] = cpu[CPU_IDLE];
		cpu[CPU_IDLE] = 0;
	} else {
		cpu[CPU_IDLE] -= cpu[CPU_WAIT];
	}

	for(ii=0;ii<4;ii++)
		ax.si.cpu[ii] += cpu[ii];

#ifdef	RFS_SUPPORT
	if (dflg) ax.di.serve += nx.di.serve   - ox.di.serve;
#endif	/* RFS_SUPPORT */

	while((ccc = fopt[jj++]) != NULL)
	switch(ccc){
	case 'u':
		tsttab();
#ifdef	RFS_SUPPORT
	if (dflg) {
			(void) printf(" %7.0f %7.0f %7.0f %7.0f %7.0f\n",
			(float)cpu[1]/tdiff * 100.0,

			(float)(cpu[2] -
			       (nx.di.serve - ox.di.serve) )/tdiff * 100.0,
			(float)(nx.di.serve - ox.di.serve)/tdiff * 100.0,

			(float)cpu[3]/tdiff * 100.0,
			(float)cpu[0]/tdiff * 100.0);
		break;
	}
#endif	/* RFS_SUPPORT */
		(void) printf(" %7.0f %7.0f %7.0f %7.0f\n",
		(float)cpu[1]/tdiff * 100.0,
		(float)cpu[2]/tdiff * 100.0,
		(float)cpu[3]/tdiff * 100.0,
		(float)cpu[0]/tdiff * 100.0);
		break;
	case 'y':
		tsttab();
		(void) printf(" %7.0f %7.0f %7.0f %7.0f %7.0f %7.0f\n",
		(float)(nx.si.rawch - ox.si.rawch)/tdiff * HZ,
		(float)(nx.si.canch - ox.si.canch)/tdiff * HZ,
		(float)(nx.si.outch - ox.si.outch)/tdiff * HZ,
		(float)(nx.si.rcvint - ox.si.rcvint)/tdiff * HZ,
		(float)(nx.si.xmtint - ox.si.xmtint)/tdiff * HZ,
		(float)(nx.si.mdmint - ox.si.mdmint)/tdiff * HZ);

		ax.si.rawch += nx.si.rawch - ox.si.rawch;
		ax.si.canch += nx.si.canch - ox.si.canch;
		ax.si.outch += nx.si.outch - ox.si.outch;
		ax.si.rcvint += nx.si.rcvint - ox.si.rcvint;
		ax.si.xmtint += nx.si.xmtint - ox.si.xmtint;
		ax.si.mdmint += nx.si.mdmint - ox.si.mdmint;
		break;
	case 'b':
		tsttab();
#ifdef	RFS_SUPPORT
		if (dflg) {
			(void) printf("\n   local  %4.0f %7.0f %7.0f %7.0f %7.0f %7.0f %7.0f %7.0f\n",
				(float)(nx.si.bread - ox.si.bread)/tdiff * HZ,
				(float)(nx.si.lread - ox.si.lread)/tdiff * HZ,
				((nx.si.lread - ox.si.lread) <= 0) ? 100 :
				(((float)(nx.si.lread - ox.si.lread) -
				  (float)(nx.si.bread - ox.si.bread))/
				  (float)(nx.si.lread - ox.si.lread) * 100.0),
				(float)(nx.si.bwrite - ox.si.bwrite)/tdiff * HZ,
				(float)(nx.si.lwrite - ox.si.lwrite)/tdiff * HZ,
				((nx.si.lwrite - ox.si.lwrite) <= 0) ? 100 :
				(((float)(nx.si.lwrite - ox.si.lwrite) -
				  (float)(nx.si.bwrite - ox.si.bwrite))/
				  (float)(nx.si.lwrite - ox.si.lwrite) * 100.0),
				(float)(nx.si.phread - ox.si.phread)/tdiff * HZ,
				(float)(nx.si.phwrite - ox.si.phwrite)/tdiff * HZ);

			ax.si.bread += nx.si.bread - ox.si.bread;
			ax.si.bwrite += nx.si.bwrite - ox.si.bwrite;
			ax.si.lread += nx.si.lread - ox.si.lread;
			ax.si.lwrite += nx.si.lwrite - ox.si.lwrite;
			ax.si.phread += nx.si.phread - ox.si.phread;
			ax.si.phwrite += nx.si.phwrite - ox.si.phwrite;
			(void) printf("   remote %4.0f %7.0f %7.0f %7.0f %7.0f %7.0f \n",
				(float)(nx.rc.cbread - ox.rc.cbread)/tdiff * HZ,
				(float)(nx.rc.clread - ox.rc.clread)/tdiff * HZ,
				(((float)(nx.rc.clread - ox.rc.clread) -
	         		(float)(nx.rc.cbread - ox.rc.cbread))/
				(float)((nx.rc.clread - ox.rc.clread)?
				(nx.rc.clread - ox.rc.clread):1) * 100.0),
				(float)(nx.rc.cbwrite - ox.rc.cbwrite)/tdiff * HZ,
				(float)(nx.rc.clwrite - ox.rc.clwrite)/tdiff * HZ,
				(((float)(nx.rc.clwrite - ox.rc.clwrite) -
				(float)(nx.rc.cbwrite - ox.rc.cbwrite))/
				(float)((nx.rc.clwrite - ox.rc.clwrite)?
				(nx.rc.clwrite - ox.rc.clwrite):1) * 100.0));

			ax.rc.cbread += nx.rc.cbread - ox.rc.cbread;
			ax.rc.cbwrite += nx.rc.cbwrite - ox.rc.cbwrite;
			ax.rc.clread += nx.rc.clread - ox.rc.clread;
			ax.rc.clwrite += nx.rc.clwrite - ox.rc.clwrite;
			break;
		}
#endif	/* RFS_SUPPORT */
		(void) printf(" %7.0f %7.0f %7.0f %7.0f %7.0f %7.0f %7.0f %7.0f\n",
			(float)(nx.si.bread - ox.si.bread)/tdiff * HZ,
			(float)(nx.si.lread - ox.si.lread)/tdiff * HZ,
			((nx.si.lread - ox.si.lread) <= 0) ? 100.0 :
			(((float)(nx.si.lread - ox.si.lread) -
			  (float)(nx.si.bread - ox.si.bread))/
			  (float)(nx.si.lread - ox.si.lread) * 100.0),
			(float)(nx.si.bwrite - ox.si.bwrite)/tdiff * HZ,
			(float)(nx.si.lwrite - ox.si.lwrite)/tdiff * HZ,
			((nx.si.lwrite - ox.si.lwrite) <= 0) ? 100.0 :
			(((float)(nx.si.lwrite - ox.si.lwrite) -
			  (float)(nx.si.bwrite - ox.si.bwrite))/
			  (float)(nx.si.lwrite - ox.si.lwrite) * 100.0),
			(float)(nx.si.phread - ox.si.phread)/tdiff * HZ,
			(float)(nx.si.phwrite - ox.si.phwrite)/tdiff * HZ);

		ax.si.bread += nx.si.bread - ox.si.bread;
		ax.si.bwrite += nx.si.bwrite - ox.si.bwrite;
		ax.si.lread += nx.si.lread - ox.si.lread;
		ax.si.lwrite += nx.si.lwrite - ox.si.lwrite;
		ax.si.phread += nx.si.phread - ox.si.phread;
		ax.si.phwrite += nx.si.phwrite - ox.si.phwrite;
		break;
	case 'd':
		for (j = 0; j < ndevs; j++) {
			ulong ops, blks, active, resp;

			/*
			 * If there weren't any operations or the drive wasn't
			 * active, skip it
			 */
			ops = nx.devio[j].d_ops - ox.devio[j].d_ops;
			active = nx.devio[j].d_active - ox.devio[j].d_active;

			if (ops <= 0 || active <= 0)
				continue;

			blks = nx.devio[j].d_blks - ox.devio[j].d_blks;
			resp = nx.devio[j].d_resp - ox.devio[j].d_resp;
			/*
			 * DYNIX keeps the active and resp times in
			 * microseconds internally and sadc converts them
			 * to milliseconds.  This creates a situation where
			 * the resp time for and interval can appear 1 ms
			 * less than the active time when in fact it should
			 * be the same.  This is caused by the loss in
			 * in precision in converting to milliseconds.
			 * The following code corrects the case when active
			 * is 1 greater then the response time and complains
			 * otherwise.
			 */
			if (resp < active) {
				if (++resp < active) {
					(void) fprintf(stderr,
			    "sar: corrupted disk response and active times\n");
				}
			}

			tsttab();
			(void) printf("%9s", nx.devio[j].d_name);
			(void) printf(" %7.0f %7.1f %7.0f %7.0f %7.1f %7.1f\n",
				(float) active / (tdiff*1000./HZ) * 100.0,
				(float) resp / (float) active,
				(float) ops / tdiff * HZ,
				(float) blks / tdiff * HZ,
				((float) resp - (float) active) / (float) ops,
				(float) active / (float) ops);

			/* Add to average */
			(void) strcpy(ax.devio[j].d_name, nx.devio[j].d_name);
			ax.devio[j].d_ops += ops;
			ax.devio[j].d_blks += blks;
			ax.devio[j].d_active += active;
			ax.devio[j].d_resp += resp;
		}
		break;
	case 'v':
		tsttab();
		(void) printf(" %3d/%3d%3ld %3d/%3d%3ld %3d/%3d%3ld %3d/%3d\n",
			nx.szproc, nx.mszproc, (nx.procovf - ox.procovf),
			nx.szinode, nx.mszinode, (nx.inodeovf - ox.inodeovf),
			nx.szfile, nx.mszfile, (nx.fileovf - ox.fileovf),
			nx.szlckr, nx.mszlckr);
		break;
	case 'c':
		tsttab();
#ifdef	RFS_SUPPORT
	if (dflg) {
		Isyscall = (float)(nx.di.isyscall - ox.di.isyscall )/tdiff * HZ;
		Osyscall = (float)(nx.di.osyscall - ox.di.osyscall )/tdiff * HZ;
		Lsyscall = (float)(nx.si.syscall - ox.si.syscall )/tdiff * HZ -
				(Isyscall + Osyscall);

		Isysread = (float)(nx.di.isysread - ox.di.isysread )/tdiff * HZ;
		Osysread = (float)(nx.di.osysread - ox.di.osysread )/tdiff * HZ;
		Lsysread = (float)(nx.si.sysread - ox.si.sysread )/tdiff * HZ -
				(Isysread + Osysread);

		Isyswrite = (float)(nx.di.isyswrite - ox.di.isyswrite )/tdiff * HZ;
		Osyswrite = (float)(nx.di.osyswrite - ox.di.osyswrite )/tdiff * HZ;
		Lsyswrite = (float)(nx.si.syswrite - ox.si.syswrite )/tdiff * HZ -
				(Isyswrite + Osyswrite);

		Isysexec = (float)(nx.di.isysexec - ox.di.isysexec )/tdiff * HZ;
		Osysexec = (float)(nx.di.osysexec - ox.di.osysexec )/tdiff * HZ;
		Lsysexec = (float)(nx.si.sysexec - ox.si.sysexec )/tdiff * HZ -
				  (Isysexec + Osysexec);

		Ireadch = (float)(nx.di.ireadch - ox.di.ireadch )/tdiff * HZ;
		Oreadch = (float)(nx.di.oreadch - ox.di.oreadch )/tdiff * HZ;
		Lreadch = (float)(nx.si.readch - ox.si.readch )/tdiff * HZ -
				(Ireadch + Oreadch);

		Iwritech = (float)(nx.di.iwritech - ox.di.iwritech )/tdiff * HZ;
		Owritech = (float)(nx.di.owritech - ox.di.owritech )/tdiff * HZ;
		Lwritech = (float)(nx.si.writech - ox.si.writech )/tdiff * HZ -
				(Iwritech + Owritech);

		(void) printf("\n%-8s %7.0f %7.0f %7.0f %7s %7.2f %7.0f %7.0f\n",
			"   in", Isyscall,Isysread,Isyswrite,"",Isysexec,
			Ireadch,Iwritech);
		(void) printf("%-8s %7.0f %7.0f %7.0f %7s %7.2f %7.0f %7.0f\n",
			"   out",Osyscall,Osysread,Osyswrite,"",Osysexec,
			Oreadch,Owritech);
		(void) printf("%-8s %7.0f %7.0f %7.0f %7.2f %7.2f %7.0f %7.0f\n",
			"   local", Lsyscall, Lsysread, Lsyswrite,
			(float)(nx.si.sysfork - ox.si.sysfork)/tdiff * HZ,
			Lsysexec, Lreadch, Lwritech);
 
		ax.di.isyscall += nx.di.isyscall - ox.di.isyscall;
		ax.di.osyscall += nx.di.osyscall - ox.di.osyscall;
		ax.si.syscall += nx.si.syscall - ox.si.syscall;
 
		ax.di.isysread += nx.di.isysread - ox.di.isysread;
		ax.di.osysread += nx.di.osysread - ox.di.osysread;
		ax.si.sysread += nx.si.sysread - ox.si.sysread;
 
		ax.di.isyswrite += nx.di.isyswrite - ox.di.isyswrite;
		ax.di.osyswrite += nx.di.osyswrite - ox.di.osyswrite;
		ax.si.syswrite += nx.si.syswrite - ox.si.syswrite;
 
		ax.di.isysexec += nx.di.isysexec - ox.di.isysexec;
		ax.di.osysexec += nx.di.osysexec - ox.di.osysexec;
		ax.si.sysexec += nx.si.sysexec - ox.si.sysexec;
 
		ax.di.ireadch += nx.di.ireadch - ox.di.ireadch;
		ax.di.oreadch += nx.di.oreadch - ox.di.oreadch;
		ax.si.readch += nx.si.readch - ox.si.readch;
	 
		ax.di.iwritech += nx.di.iwritech - ox.di.iwritech;
		ax.di.owritech += nx.di.owritech - ox.di.owritech;
		ax.si.writech += nx.si.writech - ox.si.writech;

		ax.si.sysfork += nx.si.sysfork - ox.si.sysfork;

		break;
	}
#endif	/* RFS_SUPPORT */
		(void) printf(" %7.0f %7.0f %7.0f %7.2f %7.2f %8.0f %8.0f\n",
			(float)(nx.si.syscall - ox.si.syscall)/tdiff *HZ,
			(float)(nx.si.sysread - ox.si.sysread)/tdiff *HZ,
			(float)(nx.si.syswrite - ox.si.syswrite)/tdiff *HZ,
			(float)(nx.si.sysfork - ox.si.sysfork)/tdiff *HZ,
			(float)(nx.si.sysexec - ox.si.sysexec)/tdiff *HZ,
			(float)(nx.si.readch - ox.si.readch)/tdiff * HZ,
			(float)(nx.si.writech - ox.si.writech)/tdiff * HZ);

		ax.si.syscall += nx.si.syscall - ox.si.syscall;
		ax.si.sysread += nx.si.sysread - ox.si.sysread;
		ax.si.syswrite += nx.si.syswrite - ox.si.syswrite;
		ax.si.sysfork += nx.si.sysfork - ox.si.sysfork;
		ax.si.sysexec += nx.si.sysexec - ox.si.sysexec;
		ax.si.readch += nx.si.readch - ox.si.readch;
		ax.si.writech += nx.si.writech - ox.si.writech;
		break;
	case 'w':
		tsttab();
		(void) printf(" %7.2f %7.1f %7.2f %7.1f %7.0f\n",
			(float)(nx.si.swapin - ox.si.swapin)/tdiff * HZ,
			(float)(nx.si.bswapin -ox.si.bswapin)/tdiff * HZ,
			(float)(nx.si.swapout - ox.si.swapout)/tdiff * HZ,
			(float)(nx.si.bswapout - ox.si.bswapout)/tdiff * HZ,
			(float)(nx.si.pswitch - ox.si.pswitch)/tdiff * HZ);

		ax.si.swapin += nx.si.swapin - ox.si.swapin;
		ax.si.swapout += nx.si.swapout - ox.si.swapout;
		ax.si.bswapin += nx.si.bswapin - ox.si.bswapin;
		ax.si.bswapout += nx.si.bswapout - ox.si.bswapout;
		ax.si.pswitch += nx.si.pswitch - ox.si.pswitch;
		break;
	case 'a':
		tsttab();
		(void) printf(" %7.0f %7.0f %7.0f\n",
			(float)(nx.si.iget - ox.si.iget)/tdiff * HZ,
			(float)(nx.si.namei - ox.si.namei)/tdiff * HZ,
			(float)(nx.si.dirblk - ox.si.dirblk)/tdiff * HZ);

		ax.si.iget += nx.si.iget - ox.si.iget;
		ax.si.namei += nx.si.namei - ox.si.namei;
		ax.si.dirblk += nx.si.dirblk - ox.si.dirblk;
		break;
#ifdef	RFS_SUPPORT
	case 'S':
		tsttab();
		(void) printf("%11.0f %9.1f %9.0f %9.1f %9.0f\n",
			(float)(nx.di.nservers - ox.di.nservers)/tdiff * HZ,
			(((nx.di.rcv_occ - ox.di.rcv_occ)/tdiff * HZ * 100.0) > 100) ? 100.0 :
				(float)(nx.di.rcv_occ - ox.di.rcv_occ)/tdiff * HZ * 100.0,
			(nx.di.rcv_occ - ox.di.rcv_occ <= 0) ? 0.0 :
				((nx.di.rcv_que - ox.di.rcv_que <= 0) ? 0.0 :
				(float)(nx.di.rcv_que - ox.di.rcv_que)/
					(float)(nx.di.rcv_occ - ox.di.rcv_occ)),
			(((nx.di.srv_occ - ox.di.srv_occ)/tdiff * HZ * 100.0) > 100) ? 100.0 :
				(float)(nx.di.srv_occ - ox.di.srv_occ)/tdiff * HZ * 100.0,
			(nx.di.srv_occ - ox.di.srv_occ == 0) ? 0.0 :
				(float)(nx.di.srv_que - ox.di.srv_que)/
					(float)(nx.di.srv_occ - ox.di.srv_occ));
 


		ax.di.nservers += nx.di.nservers - ox.di.nservers;
		ax.di.rcv_occ += nx.di.rcv_occ - ox.di.rcv_occ;
		ax.di.rcv_que += nx.di.rcv_que - ox.di.rcv_que;
		ax.di.srv_occ += nx.di.srv_occ - ox.di.srv_occ;
		ax.di.srv_que += nx.di.srv_que - ox.di.srv_que;
		break;
	case 'C':
		tsttab();
		(void) printf("%11.1f %11.1f %11.1f %11.1f %11.1f %11.1f\n",
			(float)(nx.rc.snd_dis - ox.rc.snd_dis)/tdiff * HZ,
			(float)(nx.rc.snd_msg - ox.rc.snd_msg)/tdiff * HZ,
			(float)(nx.rc.rcv_dis - ox.rc.rcv_dis)/tdiff * HZ,
			(float)(nx.rc.rcv_msg - ox.rc.rcv_msg)/tdiff * HZ,
			(float)(nx.rc.dis_bread - ox.rc.dis_bread)/tdiff * HZ,
			(float)(nx.rc.blk_inval - ox.rc.blk_inval)/tdiff * HZ);

		ax.rc.snd_dis += nx.rc.snd_dis - ox.rc.snd_dis;
		ax.rc.snd_msg += nx.rc.snd_msg - ox.rc.snd_msg;
		ax.rc.rcv_dis += nx.rc.rcv_dis - ox.rc.rcv_dis;
		ax.rc.rcv_msg += nx.rc.rcv_msg - ox.rc.rcv_msg;
		ax.rc.dis_bread += nx.rc.dis_bread - ox.rc.dis_bread;
		ax.rc.blk_inval += nx.rc.blk_inval - ox.rc.blk_inval;
		break;
#endif	/* RFS_SUPPORT */
	
	case 'q':
		tsttab();
		if ((nx.si.runocc - ox.si.runocc) == 0)
			(void) printf(" %7s %7s", "  ", "  ");
		else {
			(void) printf(" %7.1f %7.0f",
			(float)(nx.si.runque -ox.si.runque)/
				(float)(nx.si.runocc - ox.si.runocc),
			(float)(nx.si.runocc -ox.si.runocc)/tdiff *HZ *100.0);
			ax.si.runque += nx.si.runque - ox.si.runque;
			ax.si.runocc += nx.si.runocc - ox.si.runocc;
		}
		if ((nx.si.swpocc - ox.si.swpocc) == 0)
			(void) printf(" %7s %7s\n","  ","  ");
		else {
			(void) printf(" %7.1f %7.0f\n",
			(float)(nx.si.swpque -ox.si.swpque)/
				(float)(nx.si.swpocc - ox.si.swpocc),
			(float)(nx.si.swpocc -ox.si.swpocc)/tdiff *HZ *100.0);
			ax.si.swpque += nx.si.swpque - ox.si.swpque;
			ax.si.swpocc += nx.si.swpocc - ox.si.swpocc;

		}
		break;
	case 'm':
		tsttab();
		(void) printf(" %7.2f %7.2f\n",
			(float)(nx.si.msg - ox.si.msg)/tdiff * HZ,
			(float)(nx.si.sema - ox.si.sema)/tdiff * HZ);

		ax.si.msg += nx.si.msg - ox.si.msg;
		ax.si.sema += nx.si.sema - ox.si.sema;
		break;

 	{
	unsigned long k0, k1, x;
	case 'r':
		tsttab();
		k1 = (nx.mi.freemem[1] - ox.mi.freemem[1]);
		if (nx.mi.freemem[0] >= ox.mi.freemem[0]) {
			k0 = nx.mi.freemem[0] - ox.mi.freemem[0]; 
		}
		else
		{ 	k0 = 1 + (~(ox.mi.freemem[0] - nx.mi.freemem[0]));
			k1--; 
		}
		(void) printf(" %7.0f %7.0f\n",
			(double)(k0 + magic * k1)/tdiff,
			(float)nx.mi.freeswap);

			x = ax.mi.freemem[0];
			ax.mi.freemem[0] += k0;
			ax.mi.freemem[1] += k1;
			if ( x > ax.mi.freemem[0])
				ax.mi.freemem[1]++;
			ax.mi.freeswap += nx.mi.freeswap;
		break;
 	}


	case 'p':
		tsttab();
		(void) printf(" %7.2f %7.2f %7.2f %7.2f\n",
			(float)(nx.mi.vfault - ox.mi.vfault) / tdiff * HZ,
			(float)(nx.mi.pfault - ox.mi.pfault) / tdiff * HZ,
			(float)(nx.mi.file - ox.mi.file) / tdiff * HZ,
			(float)(nx.mi.freedpgs - ox.mi.freedpgs) / tdiff * HZ);
		ax.mi.vfault += nx.mi.vfault - ox.mi.vfault;
		ax.mi.pfault += nx.mi.pfault - ox.mi.pfault;
		ax.mi.file += nx.mi.file - ox.mi.file;
		ax.mi.freedpgs += nx.mi.freedpgs - ox.mi.freedpgs;
	}
	if(jj > 2)	(void) printf("\n");
}

/**********************************************************/

/*      print average routine  */
prtavg()
{
	register int j;
	int	jj=0;
	char	ccc;

	tdiff = ax.si.cpu[0] + ax.si.cpu[1] + ax.si.cpu[2] + ax.si.cpu[3];
	if (tdiff <= 0.0)
		return;
	(void) printf("\n");

	while((ccc = fopt[jj++]) != NULL)
	switch(ccc){
	case 'u':
#ifdef	RFS_SUPPORT
		if (dflg) {
				(void) printf("Average  %7.0f %7.0f %7.0f %7.0f %7.0f\n",
				(float)ax.si.cpu[1]/tdiff * 100.0,
				(float)(ax.si.cpu[2] - ax.di.serve)/tdiff * 100.0,
				(float)(ax.di.serve)/tdiff * 100.0,
				(float)ax.si.cpu[3]/tdiff * 100.0,
				(float)ax.si.cpu[0]/tdiff * 100.0);

		break;
		}
#endif	/* RFS_SUPPORT */
			(void) printf("Average  %7.0f %7.0f %7.0f %7.0f\n",
			(float)ax.si.cpu[1]/tdiff * 100.0,
			(float)ax.si.cpu[2]/tdiff * 100.0,
			(float)ax.si.cpu[3]/tdiff * 100.0,
			(float)ax.si.cpu[0]/tdiff * 100.0);
		break;
	case 'y':
		(void) printf("Average  %7.0f %7.0f %7.0f %7.0f %7.0f %7.0f\n",
			(float)ax.si.rawch/tdiff *HZ,
			(float)ax.si.canch/tdiff *HZ,
			(float)ax.si.outch/tdiff *HZ,
			(float)ax.si.rcvint/tdiff *HZ,
			(float)ax.si.xmtint/tdiff *HZ,
			(float)ax.si.mdmint/tdiff *HZ);
		break;
	case 'b':
#ifdef	RFS_SUPPORT
		if (dflg) {
			(void) printf("Average\n   local  %4.0f %7.0f %7.0f %7.0f %7.0f %7.0f %7.0f %7.0f\n",
				(float)ax.si.bread/tdiff *HZ,
				(float)ax.si.lread/tdiff *HZ,
				(float)(ax.si.lread - ax.si.bread)/
					(float)(ax.si.lread) * 100.0,
				(float)ax.si.bwrite/tdiff *HZ,
				(float)ax.si.lwrite/tdiff *HZ,
				(float)(ax.si.lwrite - ax.si.bwrite)/
					(float)(ax.si.lwrite) * 100.0,
				(float)ax.si.phread/tdiff *HZ,
				(float)ax.si.phwrite/tdiff *HZ);
			(void) printf("   remote %4.0f %7.0f %7.0f %7.0f %7.0f %7.0f\n",
				(float)ax.rc.cbread/tdiff *HZ,
				(float)ax.rc.clread/tdiff *HZ,
				(float)(ax.rc.clread - ax.rc.cbread)/
				(float)(ax.rc.clread?(ax.rc.clread):1) * 100.0,
				(float)ax.rc.cbwrite/tdiff *HZ,
				(float)ax.rc.clwrite/tdiff *HZ,
				(float)(ax.rc.clwrite - ax.rc.cbwrite)/
					(float)(ax.rc.clwrite?(ax.rc.clwrite):
					1) * 100.0);
				break;
		}
#endif	/* RFS_SUPPORT */
		(void) printf("Average  %7.0f %7.0f %7.0f %7.0f %7.0f %7.0f %7.0f %7.0f\n",
			(float)ax.si.bread/tdiff *HZ,
			(float)ax.si.lread/tdiff *HZ,
			(ax.si.lread <= 0) ? 100.0 :
			(float)(ax.si.lread - ax.si.bread)/
				(float)(ax.si.lread) * 100.0,
			(float)ax.si.bwrite/tdiff *HZ,
			(float)ax.si.lwrite/tdiff *HZ,
			(ax.si.lwrite <= 0) ? 100.0 :
			(float)(ax.si.lwrite - ax.si.bwrite)/
				(float)(ax.si.lwrite) * 100.0,
			(float)ax.si.phread/tdiff *HZ,
			(float)ax.si.phwrite/tdiff *HZ);
		break;
	case 'd':
		(void) printf("Average ");
		tabflg = 1;
		for (j = 0; j < ndevs; j++) {
			if ((ax.devio[j].d_ops <= 0) ||
			   			(ax.devio[j].d_active <= 0))
				continue;

			tsttab();
			(void) printf("%9s%", ax.devio[j].d_name);
			(void) printf(" %7.0f %7.1f %7.0f %7.0f %7.1f %7.1f\n",
				ax.devio[j].d_active / (tdiff*1000./HZ) * 100.0,
				(float)ax.devio[j].d_resp/ax.devio[j].d_active,
				(float)ax.devio[j].d_ops/tdiff *HZ,
				(float)ax.devio[j].d_blks/tdiff *HZ,
				(ax.devio[j].d_resp - ax.devio[j].d_active) /
					(float)ax.devio[j].d_ops,
				(float)ax.devio[j].d_active/ax.devio[j].d_ops );
		}
		break;
	case 'v':
		break;
	case 'c':
#ifdef	RFS_SUPPORT
		if (dflg) {
			Isyscall = (float)(ax.di.isyscall/tdiff * HZ);
			Osyscall = (float)(ax.di.osyscall/tdiff * HZ);
			Lsyscall = (float)(ax.si.syscall/tdiff * HZ) -
					(Isyscall + Osyscall);

			Isysread = (float)(ax.di.isysread/tdiff * HZ);
			Osysread = (float)(ax.di.osysread/tdiff * HZ);
			Lsysread = (float)(ax.si.sysread/tdiff * HZ) -
					(Isysread + Osysread);

			Isyswrite = (float)(ax.di.isyswrite/tdiff * HZ);
			Osyswrite = (float)(ax.di.osyswrite/tdiff * HZ);
			Lsyswrite = (float)(ax.si.syswrite/tdiff * HZ) -
					(Isyswrite + Osyswrite);

			Isysexec = (float)(ax.di.isysexec/tdiff * HZ);
			Osysexec = (float)(ax.di.osysexec/tdiff * HZ);
			Lsysexec = (float)(ax.si.sysexec/tdiff * HZ) -
					(Isysexec + Osysexec);

			Ireadch = (float)(ax.di.ireadch/tdiff * HZ);
			Oreadch = (float)(ax.di.oreadch/tdiff * HZ);
			Lreadch = (float)(ax.si.readch/tdiff * HZ) -
					(Ireadch + Oreadch);

			Iwritech = (float)(ax.di.iwritech/tdiff * HZ);
			Owritech = (float)(ax.di.owritech/tdiff * HZ);
			Lwritech = (float)(ax.si.writech/tdiff * HZ) -
					(Iwritech + Owritech);

			(void) printf("Average\n%-8s %7.0f %7.0f %7.0f %7s %7.2f %7.0f %7.0f\n",
				"   in", Isyscall,Isysread,Isyswrite,"",Isysexec,
				Ireadch,Iwritech);
			(void) printf("%-8s %7.0f %7.0f %7.0f %7s %7.2f %7.0f %7.0f\n",
				"   out",Osyscall,Osysread,Osyswrite,"",Osysexec,
				Oreadch,Owritech);
			(void) printf("%-8s %7.0f %7.0f %7.0f %7.2f %7.2f %7.0f %7.0f\n",
				"   local", Lsyscall, Lsysread, Lsyswrite,
				(float)ax.si.sysfork/tdiff *HZ,
				Lsysexec, Lreadch, Lwritech);
			break;
		}
#endif	/* RFS_SUPPORT */

		(void) printf("Average  %7.0f %7.0f %7.0f %7.2f %7.2f %8.0f %8.0f\n",
			(float)ax.si.syscall/tdiff *HZ,
			(float)ax.si.sysread/tdiff *HZ,
			(float)ax.si.syswrite/tdiff *HZ,
			(float)ax.si.sysfork/tdiff *HZ,
			(float)ax.si.sysexec/tdiff *HZ,
			(float)ax.si.readch/tdiff * HZ,
			(float)ax.si.writech/tdiff * HZ);
		break;
	case 'w':
		(void) printf("Average  %7.2f %7.1f %7.2f %7.1f %7.0f\n",
			(float)ax.si.swapin/tdiff * HZ,
			(float)ax.si.bswapin /tdiff * HZ,
			(float)ax.si.swapout/tdiff * HZ,
			(float)ax.si.bswapout/tdiff * HZ,
			(float)ax.si.pswitch/tdiff * HZ);
		break;
	case 'a':
		(void) printf("Average  %7.0f %7.0f %7.0f\n",
			(float)ax.si.iget/tdiff * HZ,
			(float)ax.si.namei/tdiff * HZ,
			(float)ax.si.dirblk/tdiff * HZ);
		break;
#ifdef	RFS_SUPPORT
	case 'S':
		(void) printf("Average %11.0f %9.0f %9.0f %9.0f %9.0f\n",
			(float)ax.di.nservers / tdiff * HZ,
			((ax.di.rcv_occ / tdiff * HZ * 100.0) > 100) ? 100.0 :
				(float)ax.di.rcv_occ / tdiff * HZ * 100.0,
			(ax.di.rcv_occ == 0) ? 0.0 :
				(float)ax.di.rcv_que / (float)ax.di.rcv_occ,
			((ax.di.srv_occ / tdiff * HZ * 100.0) > 100) ? 100.0 :
				(float)ax.di.srv_occ / tdiff * HZ * 100.0,
			(ax.di.srv_occ == 0 ) ? 0.0 :
				(float)ax.di.srv_que / (float)ax.di.srv_occ );
		break;
	case 'C':
		(void) printf("Average %11.1f %11.1f %11.1f %11.1f %11.1f %11.1f\n",
			(float)(ax.rc.snd_dis)/tdiff * HZ,
			(float)(ax.rc.snd_msg)/tdiff * HZ,
			(float)(ax.rc.rcv_dis)/tdiff * HZ,
			(float)(ax.rc.rcv_msg)/tdiff * HZ,
			(float)(ax.rc.dis_bread)/tdiff * HZ,
			(float)(ax.rc.blk_inval)/tdiff * HZ);
		break;
#endif	/* RFS_SUPPORT */
	case 'q':
		if (ax.si.runocc == 0)
			(void) printf("Average  %7s %7s ","  ","  ");
		else {
			(void) printf("Average  %7.1f %7.0f ",
			(float)ax.si.runque /
				(float)ax.si.runocc,
			(float)ax.si.runocc /tdiff *HZ *100.0);
		}
		if (ax.si.swpocc == 0)
			(void) printf("%7s %7s\n","  ","  ");
		else {
			(void) printf("%7.1f %7.0f\n",
			(float)ax.si.swpque/
				(float)ax.si.swpocc,
			(float)ax.si.swpocc/tdiff *HZ *100.0);

		}
		break;
	case 'm':
		(void) printf("Average  %7.2f %7.2f\n",
			(float)ax.si.msg/tdiff * HZ,
			(float)ax.si.sema/tdiff * HZ);
		break;

	case 'r':
		(void) printf("Average  %7.0f",
			(double)(ax.mi.freemem[0] + magic * ax.mi.freemem[1])/tdiff);
		if(rcnt > 2)
		  (void) printf("%7.0f\n",(float)(ax.mi.freeswap) / (rcnt-2));
		else (void) printf("\n");
		break;

	case 'p':
		(void) printf("Average  %7.2f %7.2f %7.2f %7.2f\n",
			(float)(ax.mi.vfault / tdiff * HZ),
			(float)(ax.mi.pfault / tdiff * HZ),
			(float)(ax.mi.file / tdiff * HZ),
			(float)(ax.mi.freedpgs / tdiff * HZ));
	}
}

/**********************************************************/

/*      error exit routines  */
pillarg(cc)
	char cc;
{
	(void) fprintf(stderr,"%s -- illegal argument for option  %c\n",
		optarg, cc);
	exit(1);
}

perrexit()
{
	perror("sar");
	exit(1);
}

pmsgexit(s)
char	*s;
{
	(void) fprintf(stderr, "%s\n", s);
	exit(1);
}
