xref: /onnv-gate/usr/src/cmd/acct/acctcms.c (revision 428:a261479c3dbd)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
230Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
280Sstevel@tonic-gate /*	  All Rights Reserved  	*/
290Sstevel@tonic-gate 
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
320Sstevel@tonic-gate 
330Sstevel@tonic-gate /*
340Sstevel@tonic-gate  *	acctcms [-a] [-c] [-j] [-n] [-s] [-p] [-o] [-t] [file...]
350Sstevel@tonic-gate  *	summarize per-process accounting
360Sstevel@tonic-gate  *	-a	output in ascii, rather than [pt]cms.h format
370Sstevel@tonic-gate  *	-c	sort by total cpu, rather than total kcore-minutes
380Sstevel@tonic-gate  *	-j	anything used only once -> ***other
390Sstevel@tonic-gate  *	-n	sort by number of processes
400Sstevel@tonic-gate  *	-s	any following files already in pcms.h format
410Sstevel@tonic-gate  *      -p      output prime time command summary (only with -a)
420Sstevel@tonic-gate  *      -o      output non-prime time (offshift) command summary (only
430Sstevel@tonic-gate  *		with -a option)
440Sstevel@tonic-gate  *	-t	process records in total (old) style (tcms.h) format
450Sstevel@tonic-gate  *	file	file in [pt]cms.h (if -s seen already) or acct.h (if not)
460Sstevel@tonic-gate  *	expected use:
470Sstevel@tonic-gate  *	acctcms /var/adm/pacct? > today; acctcms -s old today >new
480Sstevel@tonic-gate  *	cp new old; rm new
490Sstevel@tonic-gate  *	acctcms -a today; acctcms -a old
500Sstevel@tonic-gate  */
510Sstevel@tonic-gate #include <stdio.h>
520Sstevel@tonic-gate #include <sys/types.h>
530Sstevel@tonic-gate #include <sys/param.h>
540Sstevel@tonic-gate #include "acctdef.h"
550Sstevel@tonic-gate #include <ctype.h>
56*428Ssl108498 #include <string.h>
570Sstevel@tonic-gate #include <sys/acct.h>
58*428Ssl108498 #include <stdlib.h>
590Sstevel@tonic-gate 
600Sstevel@tonic-gate int	csize = CSIZE;
610Sstevel@tonic-gate 
620Sstevel@tonic-gate /*
630Sstevel@tonic-gate  *  Total cms records format
640Sstevel@tonic-gate  */
650Sstevel@tonic-gate struct tcms {
660Sstevel@tonic-gate 	char	tcm_comm[8];	/* command name */
670Sstevel@tonic-gate 	long	tcm_pc;		/* number of processes */
680Sstevel@tonic-gate 	float	tcm_cpu;	/* cpu time(min) */
690Sstevel@tonic-gate 	float	tcm_real;	/* real time(min) */
700Sstevel@tonic-gate 	float	tcm_kcore;	/* kcore-minutes */
710Sstevel@tonic-gate 	ulong_t	tcm_io;		/* chars transferred */
720Sstevel@tonic-gate 	ulong_t	tcm_rw;		/* blocks read */
730Sstevel@tonic-gate } ;
740Sstevel@tonic-gate struct tcms	*tcm;
750Sstevel@tonic-gate /*
760Sstevel@tonic-gate  * prime/nonprime CMS record format
770Sstevel@tonic-gate  */
780Sstevel@tonic-gate struct pcms {
790Sstevel@tonic-gate 	char	pcm_comm[8];	/* command name */
800Sstevel@tonic-gate 	long	pcm_pc[2];	/* number of processes */
810Sstevel@tonic-gate 	float	pcm_cpu[2];	/* cpu time(min) */
820Sstevel@tonic-gate 	float	pcm_real[2];	/* real time(min) */
830Sstevel@tonic-gate 	float	pcm_kcore[2];	/* kcore-minutes */
840Sstevel@tonic-gate 	float	pcm_io[2];	/* chars transferred */
850Sstevel@tonic-gate 	float	pcm_rw[2];	/* blocks read */
860Sstevel@tonic-gate } ;
870Sstevel@tonic-gate struct pcms	*pcm;
880Sstevel@tonic-gate struct  tcms    tcmtmp  = {{'*','*','*','o','t','h','e','r'}};
890Sstevel@tonic-gate struct  pcms    pcmtmp  = {{'*','*','*','o','t','h','e','r'}};
900Sstevel@tonic-gate int	aflg;
910Sstevel@tonic-gate int	cflg;
920Sstevel@tonic-gate int	jflg;
930Sstevel@tonic-gate int	nflg;
940Sstevel@tonic-gate int	sflg;
950Sstevel@tonic-gate int	pflg;
960Sstevel@tonic-gate int	oflg;
970Sstevel@tonic-gate int	tflg;
980Sstevel@tonic-gate int	errflg;
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate #ifdef uts
1010Sstevel@tonic-gate float   expand();
1020Sstevel@tonic-gate #else
1030Sstevel@tonic-gate ulong_t	expand();
1040Sstevel@tonic-gate #endif
1050Sstevel@tonic-gate 
106*428Ssl108498 void outputc(void);
107*428Ssl108498 void totprnt(struct pcms *);
108*428Ssl108498 void pprint(struct pcms *);
109*428Ssl108498 void prnt(struct pcms *, int);
110*428Ssl108498 void print(struct pcms *);
111*428Ssl108498 void outputa(void);
112*428Ssl108498 void toutptc(void);
113*428Ssl108498 void tprint(struct tcms *);
114*428Ssl108498 void toutpta(void);
115*428Ssl108498 int ncmp(struct pcms *, struct pcms *);
116*428Ssl108498 int tncmp(struct tcms *, struct tcms *);
117*428Ssl108498 int tccmp(struct tcms *, struct tcms *);
118*428Ssl108498 int tkcmp(struct tcms *, struct tcms *);
119*428Ssl108498 int ccmp(struct pcms *, struct pcms *);
120*428Ssl108498 int kcmp(struct pcms *, struct pcms *);
121*428Ssl108498 void tdofile(char *);
122*428Ssl108498 void dofile(char *);
123*428Ssl108498 void tfixjunk(void);
124*428Ssl108498 void fixjunk(void);
125*428Ssl108498 void tcmadd(struct tcms *, struct tcms *);
126*428Ssl108498 void pcmadd(struct pcms *, struct pcms *);
127*428Ssl108498 void tsqueeze(void);
128*428Ssl108498 void squeeze(void);
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate /*  Format specification for ASCII printing */
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate char	*fmtcmd =	"%-8.8s",
1330Sstevel@tonic-gate 	*fmtcnt =	"%8ld",
1340Sstevel@tonic-gate 	*fmtkcore =	" %11.2f",
1350Sstevel@tonic-gate 	*fmtcpu =	" %9.2f",
1360Sstevel@tonic-gate 	*fmtreal =	" %12.2f",
1370Sstevel@tonic-gate 	*fmtmsz =	" %7.2f",
1380Sstevel@tonic-gate 	*fmtmcpu =	" %6.2f",
1390Sstevel@tonic-gate 	*fmthog =	" %5.2f",
1400Sstevel@tonic-gate 	*fmtcharx =	" %12.0f",
1410Sstevel@tonic-gate 	*fmtblkx =	" %10.0f" ;
1420Sstevel@tonic-gate 
143*428Ssl108498 int
main(int argc,char ** argv)144*428Ssl108498 main(int argc, char **argv)
1450Sstevel@tonic-gate {
1460Sstevel@tonic-gate 	int	c;
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate 	while((c = getopt(argc, argv, "acjnspot")) != EOF)
1490Sstevel@tonic-gate 	switch(c) {
1500Sstevel@tonic-gate 		case 'a':
1510Sstevel@tonic-gate 			aflg++;
1520Sstevel@tonic-gate 			continue;
1530Sstevel@tonic-gate 		case 'c':
1540Sstevel@tonic-gate 			cflg++;
1550Sstevel@tonic-gate 			continue;
1560Sstevel@tonic-gate 		case 'j':
1570Sstevel@tonic-gate 			jflg++;
1580Sstevel@tonic-gate 			continue;
1590Sstevel@tonic-gate 		case 'n':
1600Sstevel@tonic-gate 			nflg++;
1610Sstevel@tonic-gate 			continue;
1620Sstevel@tonic-gate 		case 's':
1630Sstevel@tonic-gate 			sflg++;
1640Sstevel@tonic-gate 			continue;
1650Sstevel@tonic-gate 		case 'p':
1660Sstevel@tonic-gate 			pflg++;
1670Sstevel@tonic-gate 			continue;
1680Sstevel@tonic-gate 		case 'o':
1690Sstevel@tonic-gate 			oflg++;
1700Sstevel@tonic-gate 			continue;
1710Sstevel@tonic-gate 		case 't':
1720Sstevel@tonic-gate 			tflg++;
1730Sstevel@tonic-gate 			continue;
1740Sstevel@tonic-gate 		default:
1750Sstevel@tonic-gate 			errflg++;
1760Sstevel@tonic-gate 			continue;
1770Sstevel@tonic-gate 	}
1780Sstevel@tonic-gate 	if(errflg){
1790Sstevel@tonic-gate 		fprintf(stderr, "Usage: %s [-acjnspot] [file ...]\n", argv[0]);
1800Sstevel@tonic-gate 		exit(1);
1810Sstevel@tonic-gate 	}
1820Sstevel@tonic-gate 	if(tflg) {
1830Sstevel@tonic-gate 		if( (tcm = (struct tcms *)calloc(CSIZE, sizeof(struct tcms))) == NULL) {
1840Sstevel@tonic-gate 			fprintf(stderr, "%s: Cannot allocate memory\n", argv[0]);
1850Sstevel@tonic-gate 			exit(5);
1860Sstevel@tonic-gate 		}
1870Sstevel@tonic-gate 		for(; optind < argc; optind++)
1880Sstevel@tonic-gate 			tdofile(argv[optind]);
1890Sstevel@tonic-gate 		if (jflg)
1900Sstevel@tonic-gate 			tfixjunk();
1910Sstevel@tonic-gate 		tsqueeze();
192*428Ssl108498 		qsort(tcm, csize, sizeof(tcm[0]),
193*428Ssl108498 		    (int (*)(const void *, const void *))
194*428Ssl108498 		     ( nflg ? tncmp: (cflg? tccmp: tkcmp)));
1950Sstevel@tonic-gate 		if (aflg)
1960Sstevel@tonic-gate 			toutpta();
1970Sstevel@tonic-gate 		else
1980Sstevel@tonic-gate 			toutptc();
1990Sstevel@tonic-gate 	} else {
2000Sstevel@tonic-gate 		if( (pcm = (struct pcms *)calloc(CSIZE, sizeof(struct pcms))) == NULL) {
2010Sstevel@tonic-gate 			fprintf(stderr, "%s: Cannot allocate memory\n", argv[0]);
2020Sstevel@tonic-gate 			exit(6);
2030Sstevel@tonic-gate 		}
2040Sstevel@tonic-gate 		for(; optind < argc; optind++)
2050Sstevel@tonic-gate 			dofile(argv[optind]);
2060Sstevel@tonic-gate 		if (jflg)
2070Sstevel@tonic-gate 			fixjunk();
2080Sstevel@tonic-gate 		squeeze();
209*428Ssl108498 		qsort(pcm, csize, sizeof(pcm[0]),
210*428Ssl108498 		    (int (*)(const void *, const void *))
211*428Ssl108498 		    (nflg? ncmp: (cflg? ccmp: kcmp)));
2120Sstevel@tonic-gate 		if (aflg)
2130Sstevel@tonic-gate 			outputa();
2140Sstevel@tonic-gate 		else
2150Sstevel@tonic-gate 			outputc();
2160Sstevel@tonic-gate 	}
2170Sstevel@tonic-gate 	exit(0);
2180Sstevel@tonic-gate 
2190Sstevel@tonic-gate }
2200Sstevel@tonic-gate 
221*428Ssl108498 void
tdofile(char * fname)222*428Ssl108498 tdofile(char *fname)
2230Sstevel@tonic-gate {
2240Sstevel@tonic-gate 	struct tcms cmt;
2250Sstevel@tonic-gate 	union {
2260Sstevel@tonic-gate 		struct acct ab;		/* SVR4 acct structure */
2270Sstevel@tonic-gate 		struct o_acct oab;	/* SVR3 acct structure */
2280Sstevel@tonic-gate 	} acct;
2290Sstevel@tonic-gate 	int ver = 0;
2300Sstevel@tonic-gate 	ulong_t	mem;
2310Sstevel@tonic-gate 	ulong_t	cpu;
2320Sstevel@tonic-gate 	ulong_t	real;
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate 	if (freopen(fname, "r", stdin) == NULL) {
2350Sstevel@tonic-gate 		fprintf(stderr,  "acctcms: cannot open %s\n", fname);
2360Sstevel@tonic-gate 		return;
2370Sstevel@tonic-gate 	}
2380Sstevel@tonic-gate 
2390Sstevel@tonic-gate 	if (sflg)
2400Sstevel@tonic-gate 		while (fread(&cmt, sizeof(cmt), 1, stdin) == 1)
2410Sstevel@tonic-gate 			tenter(&cmt);
2420Sstevel@tonic-gate 	else {
2430Sstevel@tonic-gate 		if (fread(&acct.ab, sizeof(acct.ab), 1, stdin) == 1)
2440Sstevel@tonic-gate 			/* check for expanded account structure flag */
2450Sstevel@tonic-gate 			if (acct.ab.ac_flag & AEXPND)
2460Sstevel@tonic-gate 				ver = 2;		/* 4.0 acct file */
2470Sstevel@tonic-gate 			else
2480Sstevel@tonic-gate 				ver = 1;		/* SVR3.x acct file */
2490Sstevel@tonic-gate 
2500Sstevel@tonic-gate 		rewind(stdin);	/* reset file pointer */
2510Sstevel@tonic-gate 
2520Sstevel@tonic-gate  		switch(ver) {
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate 		default:
2550Sstevel@tonic-gate 				/* this can't happen */
2560Sstevel@tonic-gate 			fprintf(stderr, "acctcms: encountered bad version number\n");
2570Sstevel@tonic-gate 			return;
2580Sstevel@tonic-gate 		case 1 :
2590Sstevel@tonic-gate 			while (fread(&acct.oab, sizeof(acct.oab), 1, stdin) == 1) {
2600Sstevel@tonic-gate 				CPYN(cmt.tcm_comm, acct.oab.ac_comm);
2610Sstevel@tonic-gate 				cmt.tcm_pc = 1;
2620Sstevel@tonic-gate 				cpu = expand(acct.oab.ac_stime)+
2630Sstevel@tonic-gate 					expand(acct.oab.ac_utime);
2640Sstevel@tonic-gate 				cmt.tcm_cpu = MINT(cpu);
2650Sstevel@tonic-gate 				real = expand(acct.oab.ac_etime);
2660Sstevel@tonic-gate 				cmt.tcm_real = MINT(real);
2670Sstevel@tonic-gate 				mem = expand(acct.oab.ac_mem);
2680Sstevel@tonic-gate 				cmt.tcm_kcore = MINT(KCORE(mem));
2690Sstevel@tonic-gate 				cmt.tcm_io = expand(acct.oab.ac_io);
2700Sstevel@tonic-gate 				cmt.tcm_rw = expand(acct.oab.ac_rw);
2710Sstevel@tonic-gate 				tenter(&cmt);
2720Sstevel@tonic-gate 			}
2730Sstevel@tonic-gate 			break;
2740Sstevel@tonic-gate 		case 2 :
2750Sstevel@tonic-gate 
2760Sstevel@tonic-gate 			while (fread(&acct.ab, sizeof(acct.ab), 1, stdin) == 1) {
2770Sstevel@tonic-gate 				CPYN(cmt.tcm_comm, acct.ab.ac_comm);
2780Sstevel@tonic-gate 				cmt.tcm_pc = 1;
2790Sstevel@tonic-gate 				cpu = expand(acct.oab.ac_stime)+
2800Sstevel@tonic-gate 					expand(acct.oab.ac_utime);
2810Sstevel@tonic-gate 				cmt.tcm_cpu = MINT(cpu);
2820Sstevel@tonic-gate 				real = expand(acct.ab.ac_etime);
2830Sstevel@tonic-gate 				cmt.tcm_real = MINT(real);
2840Sstevel@tonic-gate 				mem = expand(acct.ab.ac_mem);
2850Sstevel@tonic-gate 				cmt.tcm_kcore = MINT(KCORE(mem));
2860Sstevel@tonic-gate 				cmt.tcm_io = expand(acct.ab.ac_io);
2870Sstevel@tonic-gate 				cmt.tcm_rw = expand(acct.ab.ac_rw);
2880Sstevel@tonic-gate 				tenter(&cmt);
2890Sstevel@tonic-gate 			}
2900Sstevel@tonic-gate 			break;
2910Sstevel@tonic-gate 		}
2920Sstevel@tonic-gate 	}
2930Sstevel@tonic-gate }
2940Sstevel@tonic-gate 
295*428Ssl108498 void
dofile(char * fname)296*428Ssl108498 dofile(char *fname)
2970Sstevel@tonic-gate {
2980Sstevel@tonic-gate 	union {
2990Sstevel@tonic-gate 		struct acct ab;
3000Sstevel@tonic-gate 		struct o_acct oab;
3010Sstevel@tonic-gate 	} acct;
3020Sstevel@tonic-gate 	struct pcms 	pcmt;
3030Sstevel@tonic-gate 	double		ratio;
3040Sstevel@tonic-gate 	long		elaps[2];
3050Sstevel@tonic-gate 	ulong_t		etime;
3060Sstevel@tonic-gate 	double	dtmp;
3070Sstevel@tonic-gate 	unsigned long	ltmp;
3080Sstevel@tonic-gate 	ulong_t	mem;
3090Sstevel@tonic-gate 	ulong_t	cpu;
3100Sstevel@tonic-gate 	ulong_t	real;
3110Sstevel@tonic-gate 
3120Sstevel@tonic-gate 	if (freopen(fname, "r", stdin) == NULL) {
3130Sstevel@tonic-gate 		fprintf(stderr,  "acctcms: cannot open %s\n", fname);
3140Sstevel@tonic-gate 		return;
3150Sstevel@tonic-gate 	}
3160Sstevel@tonic-gate 
3170Sstevel@tonic-gate 	if (sflg)
3180Sstevel@tonic-gate 		while (fread(&pcmt, sizeof(pcmt), 1, stdin) == 1)
3190Sstevel@tonic-gate 			enter(&pcmt);
3200Sstevel@tonic-gate 	else {
3210Sstevel@tonic-gate 		int ver = 0;
3220Sstevel@tonic-gate 
3230Sstevel@tonic-gate 		if (fread(&acct.ab, sizeof(acct.ab), 1, stdin) == 1)
3240Sstevel@tonic-gate 			/* check for expanded account structure flag */
3250Sstevel@tonic-gate 			if (acct.ab.ac_flag & AEXPND)
3260Sstevel@tonic-gate 				ver = 2;		/* 4.0 acct file */
3270Sstevel@tonic-gate 			else
3280Sstevel@tonic-gate 				ver = 1;		/* SVR3.x acct file */
3290Sstevel@tonic-gate 
3300Sstevel@tonic-gate 		rewind(stdin);	/* reset file pointer */
3310Sstevel@tonic-gate 
3320Sstevel@tonic-gate 		switch(ver) {
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate 		default :
3350Sstevel@tonic-gate  				/* this can't happen */
3360Sstevel@tonic-gate 			fprintf(stderr, "acctcms: encountered bad version number\n");
3370Sstevel@tonic-gate 			return;
3380Sstevel@tonic-gate 		case 1 :
3390Sstevel@tonic-gate 
3400Sstevel@tonic-gate 			while (fread(&acct.oab, sizeof(acct.oab), 1, stdin) == 1) {
3410Sstevel@tonic-gate 				CPYN(pcmt.pcm_comm, acct.oab.ac_comm);
3420Sstevel@tonic-gate 			/*
3430Sstevel@tonic-gate 			** Approximate P/NP split as same as elapsed time
3440Sstevel@tonic-gate 		 	*/
3450Sstevel@tonic-gate 				if((etime = SECS(expand(acct.oab.ac_etime))) == 0)
3460Sstevel@tonic-gate 					etime = 1;
3470Sstevel@tonic-gate 				if (pnpsplit(acct.oab.ac_btime, etime, elaps)
3480Sstevel@tonic-gate 				    == 0) {
3490Sstevel@tonic-gate 					(void) fprintf(stderr, "acctcms: could "
3500Sstevel@tonic-gate 					    "not calculate prime/non-prime "
3510Sstevel@tonic-gate 					    "hours\n");
3520Sstevel@tonic-gate 					exit(1);
3530Sstevel@tonic-gate 				}
3540Sstevel@tonic-gate 				ratio = (double)elaps[PRIME]/(double)etime;
3550Sstevel@tonic-gate 				if(elaps[PRIME] > elaps[NONPRIME]) {
3560Sstevel@tonic-gate 					pcmt.pcm_pc[PRIME] = 1;
3570Sstevel@tonic-gate 					pcmt.pcm_pc[NONPRIME] = 0;
3580Sstevel@tonic-gate 				} else {
3590Sstevel@tonic-gate 					pcmt.pcm_pc[PRIME] = 0;
3600Sstevel@tonic-gate 					pcmt.pcm_pc[NONPRIME] = 1;
3610Sstevel@tonic-gate 				}
3620Sstevel@tonic-gate 				cpu = expand(acct.oab.ac_stime)+
3630Sstevel@tonic-gate 					expand(acct.oab.ac_utime);
3640Sstevel@tonic-gate 				dtmp = MINT(cpu);
3650Sstevel@tonic-gate 				pcmt.pcm_cpu[PRIME] = dtmp * ratio;
3660Sstevel@tonic-gate 				pcmt.pcm_cpu[NONPRIME] = (ratio == 1.0) ? 0.0 :
3670Sstevel@tonic-gate 					(dtmp - pcmt.pcm_cpu[PRIME]);
3680Sstevel@tonic-gate 				real = expand(acct.oab.ac_etime);
3690Sstevel@tonic-gate 				dtmp = MINT(real);
3700Sstevel@tonic-gate 				pcmt.pcm_real[PRIME] = dtmp * ratio;
3710Sstevel@tonic-gate 				pcmt.pcm_real[NONPRIME] = (ratio == 1.0) ? 0.0 :
3720Sstevel@tonic-gate 					(dtmp - pcmt.pcm_real[PRIME]);
3730Sstevel@tonic-gate 				mem = expand(acct.oab.ac_mem);
3740Sstevel@tonic-gate 				dtmp = MINT(KCORE(mem));
3750Sstevel@tonic-gate 				pcmt.pcm_kcore[PRIME] = dtmp * ratio;
3760Sstevel@tonic-gate 				pcmt.pcm_kcore[NONPRIME] = (ratio == 1.0) ? 0.0 :
3770Sstevel@tonic-gate 					(dtmp - pcmt.pcm_kcore[PRIME]);
3780Sstevel@tonic-gate 				ltmp = expand(acct.oab.ac_io);
3790Sstevel@tonic-gate 				pcmt.pcm_io[PRIME] = (double)ltmp * ratio;
3800Sstevel@tonic-gate 				pcmt.pcm_io[NONPRIME] = (ratio == 1.0) ? 0.0 :
3810Sstevel@tonic-gate 					((double)ltmp - pcmt.pcm_io[PRIME]);
3820Sstevel@tonic-gate 				ltmp = expand(acct.oab.ac_rw);
3830Sstevel@tonic-gate 				pcmt.pcm_rw[PRIME] = (double)ltmp * ratio;
3840Sstevel@tonic-gate 				pcmt.pcm_rw[NONPRIME] = (ratio == 1.0) ? 0.0 :
3850Sstevel@tonic-gate 					((double)ltmp - pcmt.pcm_rw[PRIME]);
3860Sstevel@tonic-gate 				enter(&pcmt);
3870Sstevel@tonic-gate 			}
3880Sstevel@tonic-gate 
3890Sstevel@tonic-gate 			break;
3900Sstevel@tonic-gate 		case 2 :
3910Sstevel@tonic-gate 			while (fread(&acct.ab, sizeof(acct.ab), 1, stdin) == 1) {
3920Sstevel@tonic-gate 				CPYN(pcmt.pcm_comm, acct.ab.ac_comm);
3930Sstevel@tonic-gate 				/*
3940Sstevel@tonic-gate 				** Approximate P/NP split as same as elapsed time
3950Sstevel@tonic-gate 		 		*/
3960Sstevel@tonic-gate 				if((etime = SECS(expand(acct.ab.ac_etime))) == 0)
3970Sstevel@tonic-gate 					etime = 1;
3980Sstevel@tonic-gate 				if(pnpsplit(acct.ab.ac_btime, etime, elaps) == 0) {
3990Sstevel@tonic-gate 					fprintf(stderr, "acctcms: could not calculate prime/non-prime hours\n");
4000Sstevel@tonic-gate 					exit(1);
4010Sstevel@tonic-gate 				}
4020Sstevel@tonic-gate 				ratio = (double)elaps[PRIME]/(double)etime;
4030Sstevel@tonic-gate 				if(elaps[PRIME] > elaps[NONPRIME]) {
4040Sstevel@tonic-gate 					pcmt.pcm_pc[PRIME] = 1;
4050Sstevel@tonic-gate 					pcmt.pcm_pc[NONPRIME] = 0;
4060Sstevel@tonic-gate 				} else {
4070Sstevel@tonic-gate 					pcmt.pcm_pc[PRIME] = 0;
4080Sstevel@tonic-gate 					pcmt.pcm_pc[NONPRIME] = 1;
4090Sstevel@tonic-gate 				}
4100Sstevel@tonic-gate 				cpu = expand(acct.ab.ac_stime)+
4110Sstevel@tonic-gate 					expand(acct.ab.ac_utime);
4120Sstevel@tonic-gate 				dtmp = MINT(cpu);
4130Sstevel@tonic-gate 				pcmt.pcm_cpu[PRIME] = dtmp * ratio;
4140Sstevel@tonic-gate 				pcmt.pcm_cpu[NONPRIME] = (ratio == 1.0) ? 0.0 :
4150Sstevel@tonic-gate 					(dtmp - pcmt.pcm_cpu[PRIME]);
4160Sstevel@tonic-gate 				real = expand(acct.ab.ac_etime);
4170Sstevel@tonic-gate 				dtmp = MINT(real);
4180Sstevel@tonic-gate 				pcmt.pcm_real[PRIME] = dtmp * ratio;
4190Sstevel@tonic-gate 				pcmt.pcm_real[NONPRIME] = (ratio == 1.0) ? 0.0 :
4200Sstevel@tonic-gate 					(dtmp - pcmt.pcm_real[PRIME]);
4210Sstevel@tonic-gate 				mem = expand(acct.ab.ac_mem);
4220Sstevel@tonic-gate 				dtmp = MINT(KCORE(mem));
4230Sstevel@tonic-gate 				pcmt.pcm_kcore[PRIME] = dtmp * ratio;
4240Sstevel@tonic-gate 				pcmt.pcm_kcore[NONPRIME] = (ratio == 1.0) ? 0.0 :
4250Sstevel@tonic-gate 					(dtmp - pcmt.pcm_kcore[PRIME]);
4260Sstevel@tonic-gate 				ltmp = expand(acct.ab.ac_io);
4270Sstevel@tonic-gate 				pcmt.pcm_io[PRIME] = (double)ltmp * ratio;
4280Sstevel@tonic-gate 				pcmt.pcm_io[NONPRIME] = (ratio == 1.0) ? 0.0 :
4290Sstevel@tonic-gate 					((double)ltmp - pcmt.pcm_io[PRIME]);
4300Sstevel@tonic-gate 				ltmp = expand(acct.ab.ac_rw);
4310Sstevel@tonic-gate 				pcmt.pcm_rw[PRIME] = (double)ltmp * ratio;
4320Sstevel@tonic-gate 				pcmt.pcm_rw[NONPRIME] = (ratio == 1.0) ? 0.0 :
4330Sstevel@tonic-gate 					((double)ltmp - pcmt.pcm_rw[PRIME]);
4340Sstevel@tonic-gate 				enter(&pcmt);
4350Sstevel@tonic-gate 			}
4360Sstevel@tonic-gate 
4370Sstevel@tonic-gate 			break;
4380Sstevel@tonic-gate 		}
4390Sstevel@tonic-gate 	}
4400Sstevel@tonic-gate }
4410Sstevel@tonic-gate 
442*428Ssl108498 int
tenter(struct tcms * p)443*428Ssl108498 tenter(struct tcms *p)
4440Sstevel@tonic-gate {
445*428Ssl108498 	int i;
446*428Ssl108498 	int j;
447*428Ssl108498 	struct tcms *ntcm;
4480Sstevel@tonic-gate 	for (i = j = 0; j < sizeof(p->tcm_comm); j++) {
4490Sstevel@tonic-gate 		if (p->tcm_comm[j] && p->tcm_comm[j] <= 037)
4500Sstevel@tonic-gate 			p->tcm_comm[j] = '?';
4510Sstevel@tonic-gate 		i = i*7 + p->tcm_comm[j];	/* hash function */
4520Sstevel@tonic-gate 	}
4530Sstevel@tonic-gate 	if (i < 0)
4540Sstevel@tonic-gate 		i = -i;
4550Sstevel@tonic-gate 	for (i %= csize, j = 0; tcm[i].tcm_comm[0] && j != csize; i = (i+1)%csize, j++)
4560Sstevel@tonic-gate 		if (EQN(p->tcm_comm, tcm[i].tcm_comm))
4570Sstevel@tonic-gate 			break;
4580Sstevel@tonic-gate 	if(j == csize) {
4590Sstevel@tonic-gate 		if ((ntcm = (struct tcms *) realloc(tcm,
4600Sstevel@tonic-gate 			(csize + CSIZE - 1) * sizeof (struct tcms))) == NULL) {
4610Sstevel@tonic-gate 			fprintf(stderr,
4620Sstevel@tonic-gate 				"acctcms: Cannot reallocate memory (tcm)\n");
4630Sstevel@tonic-gate 			return(-1);
4640Sstevel@tonic-gate 		} else {
4650Sstevel@tonic-gate 			memset(&ntcm[csize], 0, CSIZE - 1);
4660Sstevel@tonic-gate 			tcm = ntcm;
4670Sstevel@tonic-gate 			if (!EQN(p->tcm_comm, tcm[i].tcm_comm))
4680Sstevel@tonic-gate 				i = csize;
4690Sstevel@tonic-gate 			csize = csize + CSIZE - 1;
4700Sstevel@tonic-gate 		}
4710Sstevel@tonic-gate 	}
4720Sstevel@tonic-gate 	if (tcm[i].tcm_comm[0] == 0)
4730Sstevel@tonic-gate 		CPYN(tcm[i].tcm_comm, p->tcm_comm);
4740Sstevel@tonic-gate 	tcmadd(&tcm[i], p);
4750Sstevel@tonic-gate 	return(i);
4760Sstevel@tonic-gate }
477*428Ssl108498 
478*428Ssl108498 int
enter(struct pcms * p)479*428Ssl108498 enter(struct pcms *p)
4800Sstevel@tonic-gate {
481*428Ssl108498 	int i;
482*428Ssl108498 	int j;
483*428Ssl108498 	struct pcms *npcm;
4840Sstevel@tonic-gate 	for (i = j = 0; j < sizeof(p->pcm_comm); j++) {
4850Sstevel@tonic-gate 		if (p->pcm_comm[j] && p->pcm_comm[j] <= 037)
4860Sstevel@tonic-gate 			p->pcm_comm[j] = '?';
4870Sstevel@tonic-gate 		i = i*7 + p->pcm_comm[j];	/* hash function */
4880Sstevel@tonic-gate 	}
4890Sstevel@tonic-gate 	if (i < 0)
4900Sstevel@tonic-gate 		i = -i;
4910Sstevel@tonic-gate 	for (i %= csize, j = 0; pcm[i].pcm_comm[0] && j != csize; i = (i+1)%csize, j++)
4920Sstevel@tonic-gate 		if (EQN(p->pcm_comm, pcm[i].pcm_comm))
4930Sstevel@tonic-gate 			break;
4940Sstevel@tonic-gate 	if(j == csize) {
4950Sstevel@tonic-gate 		if ((npcm = (struct pcms *) realloc(pcm,
4960Sstevel@tonic-gate 			(csize + CSIZE - 1) * sizeof (struct pcms))) == NULL) {
4970Sstevel@tonic-gate 			fprintf(stderr,
4980Sstevel@tonic-gate 				"acctcms: Cannot reallocate memory (pcm)\n");
4990Sstevel@tonic-gate 			return(-1);
5000Sstevel@tonic-gate 		} else {
5010Sstevel@tonic-gate 			memset(&npcm[csize], 0, CSIZE - 1);
5020Sstevel@tonic-gate 			pcm = npcm;
5030Sstevel@tonic-gate 			if (!EQN(p->pcm_comm, pcm[i].pcm_comm))
5040Sstevel@tonic-gate 				i = csize;
5050Sstevel@tonic-gate 			csize = csize + CSIZE - 1;
5060Sstevel@tonic-gate 		}
5070Sstevel@tonic-gate 	}
5080Sstevel@tonic-gate 	if (pcm[i].pcm_comm[0] == 0)
5090Sstevel@tonic-gate 		CPYN(pcm[i].pcm_comm, p->pcm_comm);
5100Sstevel@tonic-gate 	pcmadd(&pcm[i], p);
5110Sstevel@tonic-gate 	return(i);
5120Sstevel@tonic-gate }
513*428Ssl108498 
514*428Ssl108498 void
tfixjunk(void)515*428Ssl108498 tfixjunk(void)	/* combine commands used only once */
5160Sstevel@tonic-gate {
517*428Ssl108498 	int i, j;
518*428Ssl108498 	j = tenter(&tcmtmp);
5190Sstevel@tonic-gate 	for (i = 0; i < csize; i++)
5200Sstevel@tonic-gate 		if (i != j && tcm[i].tcm_comm[0] && tcm[i].tcm_pc <= 1) {
5210Sstevel@tonic-gate 			tcmadd(&tcm[j], &tcm[i]);
5220Sstevel@tonic-gate 			tcm[i].tcm_comm[0] = 0;
5230Sstevel@tonic-gate 		}
5240Sstevel@tonic-gate }
525*428Ssl108498 
526*428Ssl108498 void
fixjunk(void)527*428Ssl108498 fixjunk(void)	/* combine commands used only once */
5280Sstevel@tonic-gate {
529*428Ssl108498 	int i, j;
5300Sstevel@tonic-gate 	j = enter(&pcmtmp);
5310Sstevel@tonic-gate 	for (i = 0; i < csize; i++)
5320Sstevel@tonic-gate 		if (i != j && pcm[i].pcm_comm[0] && (pcm[i].pcm_pc[PRIME] + pcm[i].pcm_pc[NONPRIME]) <= 1) {
5330Sstevel@tonic-gate 			pcmadd(&pcm[j], &pcm[i]);
5340Sstevel@tonic-gate 			pcm[i].pcm_comm[0] = 0;
5350Sstevel@tonic-gate 		}
5360Sstevel@tonic-gate }
5370Sstevel@tonic-gate 
538*428Ssl108498 void
tcmadd(struct tcms * p1,struct tcms * p2)539*428Ssl108498 tcmadd(struct tcms *p1, struct tcms *p2)
5400Sstevel@tonic-gate {
5410Sstevel@tonic-gate 	p1->tcm_pc += p2->tcm_pc;
5420Sstevel@tonic-gate 	p1->tcm_cpu = p1->tcm_cpu + p2->tcm_cpu;
5430Sstevel@tonic-gate 	p1->tcm_real = p1->tcm_real + p2->tcm_real;
5440Sstevel@tonic-gate 	p1->tcm_kcore = p1->tcm_kcore + p2->tcm_kcore;
5450Sstevel@tonic-gate 	p1->tcm_io += p2->tcm_io;
5460Sstevel@tonic-gate 	p1->tcm_rw += p2->tcm_rw;
5470Sstevel@tonic-gate }
548*428Ssl108498 
549*428Ssl108498 void
pcmadd(struct pcms * p1,struct pcms * p2)550*428Ssl108498 pcmadd(struct pcms *p1, struct pcms *p2)
5510Sstevel@tonic-gate {
5520Sstevel@tonic-gate 	p1->pcm_pc[PRIME] += p2->pcm_pc[PRIME];
5530Sstevel@tonic-gate 	p1->pcm_pc[NONPRIME] += p2->pcm_pc[NONPRIME];
5540Sstevel@tonic-gate 	p1->pcm_cpu[PRIME] += p2->pcm_cpu[PRIME];
5550Sstevel@tonic-gate 	p1->pcm_cpu[NONPRIME] += p2->pcm_cpu[NONPRIME];
5560Sstevel@tonic-gate 	p1->pcm_real[PRIME] += p2->pcm_real[PRIME];
5570Sstevel@tonic-gate 	p1->pcm_real[NONPRIME] += p2->pcm_real[NONPRIME];
5580Sstevel@tonic-gate 	p1->pcm_kcore[PRIME] += p2->pcm_kcore[PRIME];
5590Sstevel@tonic-gate 	p1->pcm_kcore[NONPRIME] += p2->pcm_kcore[NONPRIME];
5600Sstevel@tonic-gate 	p1->pcm_io[PRIME] += p2->pcm_io[PRIME];
5610Sstevel@tonic-gate 	p1->pcm_io[NONPRIME] += p2->pcm_io[NONPRIME];
5620Sstevel@tonic-gate 	p1->pcm_rw[PRIME] += p2->pcm_rw[PRIME];
5630Sstevel@tonic-gate 	p1->pcm_rw[NONPRIME] += p2->pcm_rw[NONPRIME];
5640Sstevel@tonic-gate }
5650Sstevel@tonic-gate 
566*428Ssl108498 void
tsqueeze(void)567*428Ssl108498 tsqueeze(void)	/* get rid of holes in hash table */
5680Sstevel@tonic-gate {
569*428Ssl108498 	int i, k;
5700Sstevel@tonic-gate 
5710Sstevel@tonic-gate 	for (i = k = 0; i < csize; i++)
5720Sstevel@tonic-gate 		if (tcm[i].tcm_comm[0]) {
5730Sstevel@tonic-gate 			CPYN(tcm[k].tcm_comm, tcm[i].tcm_comm);
5740Sstevel@tonic-gate 			tcm[k].tcm_pc = tcm[i].tcm_pc;
5750Sstevel@tonic-gate 			tcm[k].tcm_cpu = tcm[i].tcm_cpu;
5760Sstevel@tonic-gate 			tcm[k].tcm_real = tcm[i].tcm_real;
5770Sstevel@tonic-gate 			tcm[k].tcm_kcore = tcm[i].tcm_kcore;
5780Sstevel@tonic-gate 			tcm[k].tcm_io = tcm[i].tcm_io;
5790Sstevel@tonic-gate 			tcm[k].tcm_rw = tcm[i].tcm_rw;
5800Sstevel@tonic-gate 			k++;
5810Sstevel@tonic-gate 		}
5820Sstevel@tonic-gate 	csize = k;
5830Sstevel@tonic-gate }
584*428Ssl108498 
585*428Ssl108498 void
squeeze(void)586*428Ssl108498 squeeze(void)	/* get rid of holes in hash table */
5870Sstevel@tonic-gate {
588*428Ssl108498 	int i, k;
5890Sstevel@tonic-gate 
5900Sstevel@tonic-gate 	for (i = k = 0; i < csize; i++)
5910Sstevel@tonic-gate 		if (pcm[i].pcm_comm[0]) {
5920Sstevel@tonic-gate 			CPYN(pcm[k].pcm_comm, pcm[i].pcm_comm);
5930Sstevel@tonic-gate 			pcm[k].pcm_pc[PRIME] = pcm[i].pcm_pc[PRIME];
5940Sstevel@tonic-gate 			pcm[k].pcm_pc[NONPRIME] = pcm[i].pcm_pc[NONPRIME];
5950Sstevel@tonic-gate 			pcm[k].pcm_cpu[PRIME] = pcm[i].pcm_cpu[PRIME];
5960Sstevel@tonic-gate 			pcm[k].pcm_cpu[NONPRIME] = pcm[i].pcm_cpu[NONPRIME];
5970Sstevel@tonic-gate 			pcm[k].pcm_real[PRIME] = pcm[i].pcm_real[PRIME];
5980Sstevel@tonic-gate 			pcm[k].pcm_real[NONPRIME] = pcm[i].pcm_real[NONPRIME];
5990Sstevel@tonic-gate 			pcm[k].pcm_kcore[PRIME] = pcm[i].pcm_kcore[PRIME];
6000Sstevel@tonic-gate 			pcm[k].pcm_kcore[NONPRIME] = pcm[i].pcm_kcore[NONPRIME];
6010Sstevel@tonic-gate 			pcm[k].pcm_io[PRIME] = pcm[i].pcm_io[PRIME];
6020Sstevel@tonic-gate 			pcm[k].pcm_io[NONPRIME] = pcm[i].pcm_io[NONPRIME];
6030Sstevel@tonic-gate 			pcm[k].pcm_rw[PRIME] = pcm[i].pcm_rw[PRIME];
6040Sstevel@tonic-gate 			pcm[k].pcm_rw[NONPRIME] = pcm[i].pcm_rw[NONPRIME];
6050Sstevel@tonic-gate 			k++;
6060Sstevel@tonic-gate 		}
6070Sstevel@tonic-gate 	csize = k;
6080Sstevel@tonic-gate }
6090Sstevel@tonic-gate 
610*428Ssl108498 int
tccmp(struct tcms * p1,struct tcms * p2)611*428Ssl108498 tccmp(struct tcms *p1, struct tcms *p2)
6120Sstevel@tonic-gate {
6130Sstevel@tonic-gate 	if (p1->tcm_cpu == p2->tcm_cpu)
6140Sstevel@tonic-gate 		return(0);
6150Sstevel@tonic-gate 	return ((p2->tcm_cpu > p1->tcm_cpu)? 1 : -1);
6160Sstevel@tonic-gate }
6170Sstevel@tonic-gate 
618*428Ssl108498 int
ccmp(struct pcms * p1,struct pcms * p2)619*428Ssl108498 ccmp(struct pcms *p1, struct pcms *p2)
6200Sstevel@tonic-gate {
621*428Ssl108498 	int	index;
6220Sstevel@tonic-gate 
6230Sstevel@tonic-gate 	if( (pflg && oflg) || (!pflg && !oflg) ) {
6240Sstevel@tonic-gate 		if (p1->pcm_cpu[PRIME] + p1->pcm_cpu[NONPRIME] == p2->pcm_cpu[PRIME] + p2->pcm_cpu[NONPRIME])
6250Sstevel@tonic-gate 			return(0);
6260Sstevel@tonic-gate 		return ((p2->pcm_cpu[PRIME] + p2->pcm_cpu[NONPRIME] > p1->pcm_cpu[PRIME] + p1->pcm_cpu[NONPRIME])? 1 : -1);
6270Sstevel@tonic-gate 	}
6280Sstevel@tonic-gate 	index = pflg ? PRIME : NONPRIME;
6290Sstevel@tonic-gate 	if (p1->pcm_cpu[index] == p2->pcm_cpu[index])
6300Sstevel@tonic-gate 		return(0);
6310Sstevel@tonic-gate 	return ((p2->pcm_cpu[index] > p1->pcm_cpu[index])? 1 : -1);
6320Sstevel@tonic-gate }
6330Sstevel@tonic-gate 
634*428Ssl108498 int
tkcmp(struct tcms * p1,struct tcms * p2)635*428Ssl108498 tkcmp(struct tcms *p1, struct tcms *p2)
6360Sstevel@tonic-gate {
6370Sstevel@tonic-gate 	if (p1->tcm_kcore == p2->tcm_kcore)
6380Sstevel@tonic-gate 		return(0);
6390Sstevel@tonic-gate 	return ((p2->tcm_kcore > p1->tcm_kcore)? 1 : -1);
6400Sstevel@tonic-gate }
6410Sstevel@tonic-gate 
642*428Ssl108498 int
kcmp(struct pcms * p1,struct pcms * p2)643*428Ssl108498 kcmp(struct pcms *p1, struct pcms *p2)
6440Sstevel@tonic-gate {
645*428Ssl108498 	int	index;
6460Sstevel@tonic-gate 
6470Sstevel@tonic-gate 	if( (pflg && oflg) || (!pflg && !pflg) ){
6480Sstevel@tonic-gate 		if (p1->pcm_kcore[PRIME] + p1->pcm_kcore[NONPRIME] == p2->pcm_kcore[PRIME] + p2->pcm_kcore[NONPRIME])
6490Sstevel@tonic-gate 			return(0);
6500Sstevel@tonic-gate 		return ((p2->pcm_kcore[PRIME] + p2->pcm_kcore[NONPRIME] > p1->pcm_kcore[PRIME] + p1->pcm_kcore[NONPRIME])? 1 : -1);
6510Sstevel@tonic-gate 	}
6520Sstevel@tonic-gate 	index = pflg ? PRIME : NONPRIME;
6530Sstevel@tonic-gate 	if (p1->pcm_kcore[index] == p2->pcm_kcore[index])
6540Sstevel@tonic-gate 		return(0);
6550Sstevel@tonic-gate 	return ((p2->pcm_kcore[index] > p1->pcm_kcore[index])? 1 : -1);
6560Sstevel@tonic-gate }
6570Sstevel@tonic-gate 
658*428Ssl108498 int
tncmp(struct tcms * p1,struct tcms * p2)659*428Ssl108498 tncmp(struct tcms *p1, struct tcms *p2)
6600Sstevel@tonic-gate {
6610Sstevel@tonic-gate 	if (p1->tcm_pc == p2->tcm_pc)
6620Sstevel@tonic-gate 		return(0);
6630Sstevel@tonic-gate 	return ((p2->tcm_pc > p1->tcm_pc)? 1 : -1);
6640Sstevel@tonic-gate }
6650Sstevel@tonic-gate 
666*428Ssl108498 int
ncmp(struct pcms * p1,struct pcms * p2)667*428Ssl108498 ncmp(struct pcms *p1, struct pcms *p2)
6680Sstevel@tonic-gate {
669*428Ssl108498 	int	index;
6700Sstevel@tonic-gate 
6710Sstevel@tonic-gate 	if( (pflg && oflg) || (!pflg && !oflg) ) {
6720Sstevel@tonic-gate 		if (p1->pcm_pc[PRIME] + p1->pcm_pc[NONPRIME] == p2->pcm_pc[PRIME] + p2->pcm_pc[NONPRIME])
6730Sstevel@tonic-gate 			return(0);
6740Sstevel@tonic-gate 		return ((p2->pcm_pc[PRIME] + p2->pcm_pc[NONPRIME] > p1->pcm_pc[PRIME] + p1->pcm_pc[NONPRIME])? 1 : -1);
6750Sstevel@tonic-gate 	}
6760Sstevel@tonic-gate 	index =  pflg ? PRIME : NONPRIME;
6770Sstevel@tonic-gate 	if (p1->pcm_pc[index] == p2->pcm_pc[index])
6780Sstevel@tonic-gate 		return(0);
6790Sstevel@tonic-gate 	return ((p2->pcm_pc[index] > p1->pcm_pc[index])? 1 : -1);
6800Sstevel@tonic-gate }
6810Sstevel@tonic-gate 
6820Sstevel@tonic-gate char	thd1[] =
6830Sstevel@tonic-gate "COMMAND   NUMBER      TOTAL       TOTAL       TOTAL   MEAN     MEAN     HOG      CHARS        BLOCKS\n";
6840Sstevel@tonic-gate char	thd2[] =
6850Sstevel@tonic-gate "NAME        CMDS    KCOREMIN     CPU-MIN     REAL-MIN SIZE-K  CPU-MIN  FACTOR   TRNSFD         READ\n";
686*428Ssl108498 
687*428Ssl108498 void
toutpta(void)688*428Ssl108498 toutpta(void)
6890Sstevel@tonic-gate {
690*428Ssl108498 	int i;
6910Sstevel@tonic-gate 
6920Sstevel@tonic-gate 	printf(thd1);
6930Sstevel@tonic-gate 	printf(thd2);
6940Sstevel@tonic-gate 	printf("\n");
6950Sstevel@tonic-gate 	for (i = 0; i < csize; i++)
6960Sstevel@tonic-gate 		tcmadd(&tcmtmp, &tcm[i]);
6970Sstevel@tonic-gate 	CPYN(tcmtmp.tcm_comm, "TOTALS");
6980Sstevel@tonic-gate 	tprint(&tcmtmp);
6990Sstevel@tonic-gate 	printf("\n");
7000Sstevel@tonic-gate 	for (i = 0; i < csize; i++)
7010Sstevel@tonic-gate 		tprint(&tcm[i]);
7020Sstevel@tonic-gate }
7030Sstevel@tonic-gate 
704*428Ssl108498 void
tprint(struct tcms * p)705*428Ssl108498 tprint(struct tcms *p)
7060Sstevel@tonic-gate {
7070Sstevel@tonic-gate 	printf("%-8.8s", p->tcm_comm);
7080Sstevel@tonic-gate 	printf(" %7ld", p->tcm_pc);
7090Sstevel@tonic-gate 	printf(" %11.2f", p->tcm_kcore);
7100Sstevel@tonic-gate 	printf(" %10.2f", p->tcm_cpu);
7110Sstevel@tonic-gate 	printf(" %12.2f", p->tcm_real);
7120Sstevel@tonic-gate 	if(p->tcm_cpu == 0)  p->tcm_cpu = 1;
7130Sstevel@tonic-gate 	printf(" %6.2f", p->tcm_kcore/p->tcm_cpu);
7140Sstevel@tonic-gate 	if(p->tcm_pc == 0)  p->tcm_pc = 1;
7150Sstevel@tonic-gate 	printf(" %7.2f", p->tcm_cpu/p->tcm_pc);
7160Sstevel@tonic-gate 	if (p->tcm_real == 0)
7170Sstevel@tonic-gate 		p->tcm_real = 1;
7180Sstevel@tonic-gate 	printf(" %8.2f", p->tcm_cpu/p->tcm_real);
7190Sstevel@tonic-gate 	printf(" %11lu", p->tcm_io);
7200Sstevel@tonic-gate 	printf(" %11lu\n", p->tcm_rw);
7210Sstevel@tonic-gate }
7220Sstevel@tonic-gate 
723*428Ssl108498 void
toutptc(void)724*428Ssl108498 toutptc(void)
7250Sstevel@tonic-gate {
726*428Ssl108498 	int i;
7270Sstevel@tonic-gate 
7280Sstevel@tonic-gate 	for (i = 0; i < csize; i++)
7290Sstevel@tonic-gate 		fwrite(&tcm[i], sizeof(tcm[i]), 1, stdout);
7300Sstevel@tonic-gate }
7310Sstevel@tonic-gate 
7320Sstevel@tonic-gate char	hd1[] =
7330Sstevel@tonic-gate "COMMAND   NUMBER      TOTAL       TOTAL       TOTAL   MEAN    MEAN     HOG         CHARS     BLOCKS\n";
7340Sstevel@tonic-gate char	hd2[] =
7350Sstevel@tonic-gate "NAME        CMDS    KCOREMIN     CPU-MIN   REAL-MIN  SIZE-K  CPU-MIN  FACTOR      TRNSFD      READ\n";
7360Sstevel@tonic-gate char	hd3[] =
7370Sstevel@tonic-gate "COMMAND        NUMBER         TOTAL          CPU-MIN                 REAL-MIN        MEAN    MEAN      HOG       CHARS       BLOCKS\n";
7380Sstevel@tonic-gate char	hd4[] =
7390Sstevel@tonic-gate "NAME         (P)    (NP)   KCOREMIN       (P)      (NP)          (P)         (NP)  SIZE-K  CPU-MIN   FACTOR     TRNSFD        READ\n";
7400Sstevel@tonic-gate char	hdprime[] =
7410Sstevel@tonic-gate "                                   PRIME TIME COMMAND SUMMARY\n";
7420Sstevel@tonic-gate char	hdnonprime[] =
7430Sstevel@tonic-gate "                                  NON-PRIME TIME COMMAND SUMMARY\n";
7440Sstevel@tonic-gate char	hdtot[] =
7450Sstevel@tonic-gate "                                     TOTAL COMMAND SUMMARY\n";
7460Sstevel@tonic-gate char	hdp[] =
7470Sstevel@tonic-gate "                                PRIME/NON-PRIME TIME COMMAND SUMMARY\n";
7480Sstevel@tonic-gate 
749*428Ssl108498 void
outputa(void)750*428Ssl108498 outputa(void)
7510Sstevel@tonic-gate {
752*428Ssl108498 	int i;
7530Sstevel@tonic-gate 
7540Sstevel@tonic-gate 	if( pflg && oflg ) printf(hdp);
7550Sstevel@tonic-gate 	else if(pflg) printf(hdprime);
7560Sstevel@tonic-gate 	else if(oflg) printf(hdnonprime);
7570Sstevel@tonic-gate 	else printf(hdtot);
7580Sstevel@tonic-gate 	if( (!pflg && !oflg) || (pflg ^ oflg)) {
7590Sstevel@tonic-gate 		printf(hd1);
7600Sstevel@tonic-gate 		printf(hd2);
7610Sstevel@tonic-gate 	}
7620Sstevel@tonic-gate 	else {
7630Sstevel@tonic-gate 		printf(hd3);
7640Sstevel@tonic-gate 		printf(hd4);
7650Sstevel@tonic-gate 	}
7660Sstevel@tonic-gate 	printf("\n");
7670Sstevel@tonic-gate 	for (i = 0; i < csize; i++)
7680Sstevel@tonic-gate 		pcmadd(&pcmtmp, &pcm[i]);
7690Sstevel@tonic-gate 	CPYN(pcmtmp.pcm_comm, "TOTALS");
7700Sstevel@tonic-gate 	print(&pcmtmp);
7710Sstevel@tonic-gate 	printf("\n");
7720Sstevel@tonic-gate 	for (i = 0; i < csize; i++)
7730Sstevel@tonic-gate 		print(&pcm[i]);
7740Sstevel@tonic-gate }
7750Sstevel@tonic-gate 
776*428Ssl108498 void
print(struct pcms * p)777*428Ssl108498 print(struct pcms *p)
7780Sstevel@tonic-gate {
7790Sstevel@tonic-gate 	if(pflg && oflg) pprint(p);
7800Sstevel@tonic-gate 	else if(pflg || oflg) prnt(p, pflg ? PRIME : NONPRIME);
7810Sstevel@tonic-gate 	else totprnt(p);
7820Sstevel@tonic-gate }
7830Sstevel@tonic-gate 
784*428Ssl108498 void
prnt(struct pcms * p,int hr)785*428Ssl108498 prnt(struct pcms *p, int hr)
7860Sstevel@tonic-gate {
7870Sstevel@tonic-gate 	if(p->pcm_pc[hr] == 0) return;
7880Sstevel@tonic-gate 	printf(fmtcmd, p->pcm_comm);
7890Sstevel@tonic-gate 	printf(fmtcnt, p->pcm_pc[hr]);
7900Sstevel@tonic-gate 	printf(fmtkcore, p->pcm_kcore[hr]);
7910Sstevel@tonic-gate 	printf(fmtcpu, p->pcm_cpu[hr]);
7920Sstevel@tonic-gate 	printf(fmtreal, p->pcm_real[hr]);
7930Sstevel@tonic-gate 	if(p->pcm_cpu[hr] == 0)  p->pcm_cpu[hr] = 1;
7940Sstevel@tonic-gate 	printf(fmtmsz, p->pcm_kcore[hr]/p->pcm_cpu[hr]);
7950Sstevel@tonic-gate 	if(p->pcm_pc[hr] == 0)  p->pcm_pc[hr] = 1;
7960Sstevel@tonic-gate 	printf(fmtmcpu, p->pcm_cpu[hr]/p->pcm_pc[hr]);
7970Sstevel@tonic-gate 	if (p->pcm_real[hr] == 0)
7980Sstevel@tonic-gate 		p->pcm_real[hr] = 1;
7990Sstevel@tonic-gate 	printf(fmthog, p->pcm_cpu[hr]/p->pcm_real[hr]);
8000Sstevel@tonic-gate 	printf(fmtcharx,p->pcm_io[hr]);
8010Sstevel@tonic-gate 	printf(fmtblkx,p->pcm_rw[hr]);
8020Sstevel@tonic-gate 	printf("\n");
8030Sstevel@tonic-gate }
8040Sstevel@tonic-gate 
805*428Ssl108498 void
pprint(struct pcms * p)806*428Ssl108498 pprint(struct pcms *p)
8070Sstevel@tonic-gate {
8080Sstevel@tonic-gate 	printf(fmtcmd, p->pcm_comm);
8090Sstevel@tonic-gate 	printf(fmtcnt, p->pcm_pc[PRIME]);
8100Sstevel@tonic-gate 	printf(fmtcnt, p->pcm_pc[NONPRIME]);
8110Sstevel@tonic-gate 	printf(fmtkcore, TOTAL(p->pcm_kcore));
8120Sstevel@tonic-gate 	printf(fmtcpu, p->pcm_cpu[PRIME]);
8130Sstevel@tonic-gate 	printf(fmtcpu, p->pcm_cpu[NONPRIME]);
8140Sstevel@tonic-gate 	printf(fmtreal, p->pcm_real[PRIME]);
8150Sstevel@tonic-gate 	printf(fmtreal, p->pcm_real[NONPRIME]);
8160Sstevel@tonic-gate 	if(TOTAL(p->pcm_cpu) == 0)  p->pcm_cpu[PRIME] = 1;
8170Sstevel@tonic-gate 	printf(fmtmsz, TOTAL(p->pcm_kcore)/TOTAL(p->pcm_cpu));
8180Sstevel@tonic-gate 	if(TOTAL(p->pcm_pc) == 0)  p->pcm_pc[PRIME] = 1;
8190Sstevel@tonic-gate 	printf(fmtmcpu, TOTAL(p->pcm_cpu)/TOTAL(p->pcm_pc));
8200Sstevel@tonic-gate 	if ( TOTAL(p->pcm_real) == 0)
8210Sstevel@tonic-gate 		p->pcm_real[PRIME] = 1;
8220Sstevel@tonic-gate 	printf(fmthog, TOTAL(p->pcm_cpu)/TOTAL(p->pcm_real));
8230Sstevel@tonic-gate 	printf(fmtcharx,TOTAL(p->pcm_io));
8240Sstevel@tonic-gate 	printf(fmtblkx, TOTAL(p->pcm_rw));
8250Sstevel@tonic-gate 	printf("\n");
8260Sstevel@tonic-gate }
8270Sstevel@tonic-gate 
828*428Ssl108498 void
totprnt(struct pcms * p)829*428Ssl108498 totprnt(struct pcms *p)
8300Sstevel@tonic-gate {
8310Sstevel@tonic-gate 	printf(fmtcmd, p->pcm_comm);
8320Sstevel@tonic-gate 	printf(fmtcnt, TOTAL(p->pcm_pc));
8330Sstevel@tonic-gate 	printf(fmtkcore, TOTAL(p->pcm_kcore));
8340Sstevel@tonic-gate 	printf(fmtcpu, TOTAL(p->pcm_cpu));
8350Sstevel@tonic-gate 	printf(fmtreal, TOTAL(p->pcm_real));
8360Sstevel@tonic-gate 	if(TOTAL(p->pcm_cpu) == 0)  p->pcm_cpu[PRIME] = 1;
8370Sstevel@tonic-gate 	printf(fmtmsz, TOTAL(p->pcm_kcore)/TOTAL(p->pcm_cpu));
8380Sstevel@tonic-gate 	if(TOTAL(p->pcm_pc) == 0)  p->pcm_pc[PRIME] = 1;
8390Sstevel@tonic-gate 	printf(fmtmcpu, TOTAL(p->pcm_cpu)/TOTAL(p->pcm_pc));
8400Sstevel@tonic-gate 	if (TOTAL(p->pcm_real) == 0)
8410Sstevel@tonic-gate 		p->pcm_real[PRIME] = 1;
8420Sstevel@tonic-gate 	printf(fmthog, TOTAL(p->pcm_cpu)/TOTAL(p->pcm_real));
8430Sstevel@tonic-gate 	printf(fmtcharx,TOTAL(p->pcm_io));
8440Sstevel@tonic-gate 	printf(fmtblkx,TOTAL(p->pcm_rw));
8450Sstevel@tonic-gate 	printf("\n");
8460Sstevel@tonic-gate }
847*428Ssl108498 
848*428Ssl108498 void
outputc(void)849*428Ssl108498 outputc(void)
8500Sstevel@tonic-gate {
851*428Ssl108498 	int i;
8520Sstevel@tonic-gate 
8530Sstevel@tonic-gate 	for (i = 0; i < csize; i++)
8540Sstevel@tonic-gate 		fwrite(&pcm[i], sizeof(pcm[i]), 1, stdout);
8550Sstevel@tonic-gate }
856