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 */
54 FILE *fl
[NFILE
] = {stdin
};
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
)
106 if (++nfile
>= NFILE
) {
107 fprintf(stderr
, "acctmerg: >%d files\n", NFILE
);
110 if ((fl
[nfile
] = fopen(*argv
, "r")) == NULL
) {
111 fprintf(stderr
, "acctmerg: can't open %s\n", *argv
);
119 for (i
= 0; i
<= nfile
; i
++)
125 for (i
= 0; i
<= nfile
; i
++)
126 if(getnext(i
) == 0) {
127 fprintf(stderr
,"acctmerg: read error file %d. File may be empty.\n", i
);
132 while ((tp
= getleast()) != NULL
) /* get least uid of all files, */
133 sumcurr(tp
); /* sum all entries for that uid, */
134 if (totalonly
) /* and write the 'summed' record */
141 * getleast returns ptr to least (lowest uid) element of current
142 * avail, NULL if none left; always returns 1st of equals
147 struct tacct
*tp
, *least
;
150 for (tp
= tb
; tp
<= &tb
[nfile
]; tp
++) {
151 if (tp
->ta_name
[0] == '\0')
154 tp
->ta_uid
< least
->ta_uid
||
155 ((tp
->ta_uid
== least
->ta_uid
) &&
157 (strncmp(tp
->ta_name
, least
->ta_name
, NSZ
) < 0)))
164 * sumcurr sums all entries with same uid/name (into tp->tacct record)
165 * writes it out, gets new entry
168 sumcurr(struct tacct
*tp
)
173 memcpy(&tc
, tp
, sizeof(struct tacct
));
174 tacctadd(&tt
, tp
); /* gets total of all uids */
175 getnext(tp
-&tb
[0]); /* get next one in same file */
176 while (tp
<= &tb
[nfile
])
177 if (tp
->ta_name
[0] != '\0' &&
178 tp
->ta_uid
== tc
.ta_uid
&&
179 (uidsum
|| EQN(tp
->ta_name
, tc
.ta_name
))) {
184 tp
++; /* look at next file */
190 tacctadd(struct tacct
*t1
, struct tacct
*t2
)
192 t1
->ta_cpu
[0] = t1
->ta_cpu
[0] + t2
->ta_cpu
[0];
193 t1
->ta_cpu
[1] = t1
->ta_cpu
[1] + t2
->ta_cpu
[1];
194 t1
->ta_kcore
[0] = t1
->ta_kcore
[0] + t2
->ta_kcore
[0];
195 t1
->ta_kcore
[1] = t1
->ta_kcore
[1] + t2
->ta_kcore
[1];
196 t1
->ta_con
[0] = t1
->ta_con
[0] + t2
->ta_con
[0];
197 t1
->ta_con
[1] = t1
->ta_con
[1] + t2
->ta_con
[1];
198 t1
->ta_du
= t1
->ta_du
+ t2
->ta_du
;
199 t1
->ta_pc
+= t2
->ta_pc
;
200 t1
->ta_sc
+= t2
->ta_sc
;
201 t1
->ta_dc
+= t2
->ta_dc
;
202 t1
->ta_fee
+= t2
->ta_fee
;
206 output(struct tacct
*tp
)
211 fwrite(tp
, sizeof(*tp
), 1, stdout
);
215 * getnext reads next record from stream i, returns 1 if one existed
223 tp
->ta_name
[0] = '\0';
228 "%ld\t%s\t%e %e %e %e %e %e %e %lu\t%hu\t%hu\t%hu",
231 &tp
->ta_cpu
[0], &tp
->ta_cpu
[1],
232 &tp
->ta_kcore
[0], &tp
->ta_kcore
[1],
233 &tp
->ta_con
[0], &tp
->ta_con
[1],
241 if (fread(tp
, sizeof(*tp
), 1, fl
[i
]) == 1)
249 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";
250 char fmtv
[] = "%ld\t%.*s\t%e %e %e %e %e %e %e %lu %hu\t%hu\t%hu\n";
253 prtacct(struct tacct
*tp
)
255 printf(verbose
? fmtv
: fmt
,
259 tp
->ta_cpu
[0], tp
->ta_cpu
[1],
260 tp
->ta_kcore
[0], tp
->ta_kcore
[1],
261 tp
->ta_con
[0], tp
->ta_con
[1],