4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
26 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
29 #pragma ident "%Z%%M% %I% %E% SMI"
32 * acctmerg [-a] [-i] [-p] [-t] [-u] [-v] [file...]
33 * -a output in tacct.h/ascii (instead of tacct.h)
34 * -i input is in tacct.h/ascii (instead of tacct.h)
35 * -p print input files with no processing
36 * -t output single record that totals all input
37 * -u summarize by uid, rather than uid/name
38 * -v output in verbose tacct.h/ascii
39 * reads std input and 0-NFILE files, all in tacct.h format,
41 * merge/adds all records with same uid/name (or same uid if -u,
42 * or all records if -t], writes to std. output
43 * (still in tacct.h format)
44 * note that this can be used to summarize the std input
48 #include <sys/types.h>
49 #include <sys/param.h>
53 int nfile
; /* index of last used in fl */
56 struct tacct tb
[NFILE
]; /* current record from each file */
70 void prtacct(struct tacct
*);
71 struct tacct
*getleast(void);
72 void output(struct tacct
*);
73 void tacctadd(struct tacct
*, struct tacct
*);
74 void sumcurr(struct tacct
*);
77 main(int argc
, char **argv
)
108 if (++nfile
>= NFILE
) {
109 fprintf(stderr
, "acctmerg: >%d files\n", NFILE
);
112 if ((fl
[nfile
] = fopen(*argv
, "r")) == NULL
) {
113 fprintf(stderr
, "acctmerg: can't open %s\n", *argv
);
121 for (i
= 0; i
<= nfile
; i
++)
127 for (i
= 0; i
<= nfile
; i
++)
128 if(getnext(i
) == 0) {
129 fprintf(stderr
,"acctmerg: read error file %d. File may be empty.\n", i
);
134 while ((tp
= getleast()) != NULL
) /* get least uid of all files, */
135 sumcurr(tp
); /* sum all entries for that uid, */
136 if (totalonly
) /* and write the 'summed' record */
143 * getleast returns ptr to least (lowest uid) element of current
144 * avail, NULL if none left; always returns 1st of equals
149 struct tacct
*tp
, *least
;
152 for (tp
= tb
; tp
<= &tb
[nfile
]; tp
++) {
153 if (tp
->ta_name
[0] == '\0')
156 tp
->ta_uid
< least
->ta_uid
||
157 ((tp
->ta_uid
== least
->ta_uid
) &&
159 (strncmp(tp
->ta_name
, least
->ta_name
, NSZ
) < 0)))
166 * sumcurr sums all entries with same uid/name (into tp->tacct record)
167 * writes it out, gets new entry
170 sumcurr(struct tacct
*tp
)
175 memcpy(&tc
, tp
, sizeof(struct tacct
));
176 tacctadd(&tt
, tp
); /* gets total of all uids */
177 getnext(tp
-&tb
[0]); /* get next one in same file */
178 while (tp
<= &tb
[nfile
])
179 if (tp
->ta_name
[0] != '\0' &&
180 tp
->ta_uid
== tc
.ta_uid
&&
181 (uidsum
|| EQN(tp
->ta_name
, tc
.ta_name
))) {
186 tp
++; /* look at next file */
192 tacctadd(struct tacct
*t1
, struct tacct
*t2
)
194 t1
->ta_cpu
[0] = t1
->ta_cpu
[0] + t2
->ta_cpu
[0];
195 t1
->ta_cpu
[1] = t1
->ta_cpu
[1] + t2
->ta_cpu
[1];
196 t1
->ta_kcore
[0] = t1
->ta_kcore
[0] + t2
->ta_kcore
[0];
197 t1
->ta_kcore
[1] = t1
->ta_kcore
[1] + t2
->ta_kcore
[1];
198 t1
->ta_con
[0] = t1
->ta_con
[0] + t2
->ta_con
[0];
199 t1
->ta_con
[1] = t1
->ta_con
[1] + t2
->ta_con
[1];
200 t1
->ta_du
= t1
->ta_du
+ t2
->ta_du
;
201 t1
->ta_pc
+= t2
->ta_pc
;
202 t1
->ta_sc
+= t2
->ta_sc
;
203 t1
->ta_dc
+= t2
->ta_dc
;
204 t1
->ta_fee
+= t2
->ta_fee
;
208 output(struct tacct
*tp
)
213 fwrite(tp
, sizeof(*tp
), 1, stdout
);
217 * getnext reads next record from stream i, returns 1 if one existed
225 tp
->ta_name
[0] = '\0';
230 "%ld\t%s\t%e %e %e %e %e %e %e %lu\t%hu\t%hu\t%hu",
233 &tp
->ta_cpu
[0], &tp
->ta_cpu
[1],
234 &tp
->ta_kcore
[0], &tp
->ta_kcore
[1],
235 &tp
->ta_con
[0], &tp
->ta_con
[1],
243 if (fread(tp
, sizeof(*tp
), 1, fl
[i
]) == 1)
251 char fmt
[] = "%ld\t%.*s\t%.0f\t%.0f\t%.0f\t%.0f\t%.0f\t%.0f\t%.0f\t%lu\t%hu\t%hu\t%hu\n";
252 char fmtv
[] = "%ld\t%.*s\t%e %e %e %e %e %e %e %lu %hu\t%hu\t%hu\n";
255 prtacct(struct tacct
*tp
)
257 printf(verbose
? fmtv
: fmt
,
261 tp
->ta_cpu
[0], tp
->ta_cpu
[1],
262 tp
->ta_kcore
[0], tp
->ta_kcore
[1],
263 tp
->ta_con
[0], tp
->ta_con
[1],