dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / acct / acctmerg.c
blobe9c5715949658c3861a119e86fefde22507b7819
1 /*
2 * CDDL HEADER START
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
7 * with the License.
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]
20 * CDDL HEADER END
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,
40 * sorted by uid/name.
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
47 #include <stdio.h>
48 #include <sys/types.h>
49 #include <sys/param.h>
50 #include "acctdef.h"
51 #include <stdlib.h>
53 int nfile; /* index of last used in fl */
54 FILE *fl[NFILE];
56 struct tacct tb[NFILE]; /* current record from each file */
57 struct tacct tt = {
59 "TOTAL"
61 int asciiout;
62 int asciiinp;
63 int printonly;
64 int totalonly;
65 int uidsum;
66 int verbose;
68 int exitcode = 0;
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 *);
76 int
77 main(int argc, char **argv)
79 int i;
80 struct tacct *tp;
82 fl[0] = stdin;
84 while (--argc > 0) {
85 if (**++argv == '-')
86 switch (*++*argv) {
87 case 'a':
88 asciiout++;
89 continue;
90 case 'i':
91 asciiinp++;
92 continue;
93 case 'p':
94 printonly++;
95 continue;
96 case 't':
97 totalonly++;
98 continue;
99 case 'u':
100 uidsum++;
101 continue;
102 case 'v':
103 verbose++;
104 asciiout++;
105 continue;
107 else {
108 if (++nfile >= NFILE) {
109 fprintf(stderr, "acctmerg: >%d files\n", NFILE);
110 exit(1);
112 if ((fl[nfile] = fopen(*argv, "r")) == NULL) {
113 fprintf(stderr, "acctmerg: can't open %s\n", *argv);
114 exitcode = 1;
115 /* exit(1); */
120 if (printonly) {
121 for (i = 0; i <= nfile; i++)
122 while (getnext(i))
123 prtacct(&tb[i]);
124 exit(exitcode);
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);
130 exitcode = 2;
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 */
137 output(&tt);
139 exit(exitcode);
143 * getleast returns ptr to least (lowest uid) element of current
144 * avail, NULL if none left; always returns 1st of equals
146 struct tacct *
147 getleast(void)
149 struct tacct *tp, *least;
151 least = NULL;
152 for (tp = tb; tp <= &tb[nfile]; tp++) {
153 if (tp->ta_name[0] == '\0')
154 continue;
155 if (least == NULL ||
156 tp->ta_uid < least->ta_uid ||
157 ((tp->ta_uid == least->ta_uid) &&
158 !uidsum &&
159 (strncmp(tp->ta_name, least->ta_name, NSZ) < 0)))
160 least = tp;
162 return(least);
166 * sumcurr sums all entries with same uid/name (into tp->tacct record)
167 * writes it out, gets new entry
169 void
170 sumcurr(struct tacct *tp)
172 struct tacct tc;
173 char *memcpy();
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))) {
182 tacctadd(&tc, tp);
183 tacctadd(&tt, tp);
184 getnext(tp-&tb[0]);
185 } else
186 tp++; /* look at next file */
187 if (!totalonly)
188 output(&tc);
191 void
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;
207 void
208 output(struct tacct *tp)
210 if (asciiout)
211 prtacct(tp);
212 else
213 fwrite(tp, sizeof(*tp), 1, stdout);
217 * getnext reads next record from stream i, returns 1 if one existed
220 getnext(int i)
222 struct tacct *tp;
224 tp = &tb[i];
225 tp->ta_name[0] = '\0';
226 if (fl[i] == NULL)
227 return(0);
228 if (asciiinp) {
229 if (fscanf(fl[i],
230 "%ld\t%s\t%e %e %e %e %e %e %e %lu\t%hu\t%hu\t%hu",
231 &tp->ta_uid,
232 tp->ta_name,
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],
236 &tp->ta_du,
237 &tp->ta_pc,
238 &tp->ta_sc,
239 &tp->ta_dc,
240 &tp->ta_fee) != EOF)
241 return(1);
242 } else {
243 if (fread(tp, sizeof(*tp), 1, fl[i]) == 1)
244 return(1);
246 fclose(fl[i]);
247 fl[i] = NULL;
248 return(0);
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";
254 void
255 prtacct(struct tacct *tp)
257 printf(verbose ? fmtv : fmt,
258 tp->ta_uid,
259 OUTPUT_NSZ,
260 tp->ta_name,
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],
264 tp->ta_du,
265 tp->ta_pc,
266 tp->ta_sc,
267 tp->ta_dc,
268 tp->ta_fee);