|
|
1.1 root 1: #include <stdio.h>
2: #include <sys/types.h>
3: #include <sys/acct.h>
4: #include <signal.h>
5:
6: /* interpret command time accounting */
7:
8: #define size 2500
9: #define NC sizeof(acctbuf.ac_comm)
10: struct acct acctbuf;
11: int lflg;
12: int cflg;
13: int iflg;
14: int jflg;
15: int nflg;
16: int aflg;
17: int rflg;
18: int oflg;
19: int tflg;
20: int vflg;
21: int uflg;
22: int thres = 1;
23: int sflg;
24: int bflg;
25: int mflg;
26:
27: struct user {
28: int ncomm;
29: int fill;
30: float fctime;
31: } user[1000];
32:
33: struct tab {
34: char name[NC];
35: int count;
36: float realt;
37: float cput;
38: float syst;
39: } tab[size];
40:
41: float treal;
42: float tcpu;
43: float tsys;
44: int junkp = -1;
45: char *sname;
46: float ncom;
47: time_t expand();
48:
49: main(argc, argv)
50: char **argv;
51: {
52: FILE *ff;
53: int i, j, k;
54: extern tcmp(), ncmp(), bcmp();
55: extern float sum();
56: float ft;
57:
58: if (argc>1)
59: if (argv[1][0]=='-') {
60: argv++;
61: argc--;
62: for(i=1; argv[0][i]; i++)
63: switch(argv[0][i]) {
64:
65: case 'o':
66: oflg++;
67: break;
68:
69: case 'i':
70: iflg++;
71: break;
72:
73: case 'b':
74: bflg++;
75: break;
76:
77: case 'l':
78: lflg++;
79: break;
80:
81: case 'c':
82: cflg++;
83: break;
84:
85: case 'j':
86: jflg++;
87: break;
88:
89: case 'n':
90: nflg++;
91: break;
92:
93: case 'a':
94: aflg++;
95: break;
96:
97: case 'r':
98: rflg++;
99: break;
100:
101: case 't':
102: tflg++;
103: break;
104:
105: case 's':
106: sflg++;
107: aflg++;
108: break;
109:
110: case '0':
111: case '1':
112: case '2':
113: case '3':
114: case '4':
115: case '5':
116: case '6':
117: case '7':
118: case '8':
119: case '9':
120: thres = argv[0][i]-'0';
121: break;
122:
123: case 'v':
124: vflg++;
125: break;
126:
127: case 'u':
128: uflg++;
129: break;
130:
131: case 'm':
132: mflg++;
133: break;
134: }
135: }
136: if (iflg==0)
137: init();
138: if (argc<2)
139: doacct("/usr/adm/acct");
140: else while (--argc)
141: doacct(*++argv);
142: if (uflg) {
143: return;
144: }
145:
146: /*
147: * cleanup pass
148: * put junk together
149: */
150:
151: if (vflg)
152: strip();
153: if(!aflg)
154: for (i=0; i<size; i++)
155: if (tab[i].name[0]) {
156: for(j=0; j<NC; j++)
157: if(tab[i].name[j] == '?')
158: goto yes;
159: if(tab[i].count != 1)
160: continue;
161: yes:
162: if(junkp == -1)
163: junkp = enter("***other");
164: tab[junkp].count += tab[i].count;
165: tab[junkp].realt += tab[i].realt;
166: tab[junkp].cput += tab[i].cput;
167: tab[junkp].syst += tab[i].syst;
168: tab[i].name[0] = 0;
169: }
170: for(i=k=0; i<size; i++)
171: if(tab[i].name[0]) {
172: for(j=0; j<NC; j++)
173: tab[k].name[j] = tab[i].name[j];
174: tab[k].count = tab[i].count;
175: tab[k].realt = tab[i].realt;
176: tab[k].cput = tab[i].cput;
177: tab[k].syst = tab[i].syst;
178: k++;
179: }
180: if (sflg) {
181: signal(SIGINT, SIG_IGN);
182: if ((ff = fopen("/usr/adm/usracct", "w")) != NULL) {
183: fwrite((char *)user, sizeof(user), 1, ff);
184: fclose(ff);
185: }
186: if ((ff = fopen("/usr/adm/savacct", "w")) == NULL) {
187: printf("Can't save\n");
188: exit(0);
189: }
190: fwrite((char *)tab, sizeof(tab[0]), k, ff);
191: fclose(ff);
192: creat("/usr/adm/acct", 0644);
193: signal(SIGINT, SIG_DFL);
194: }
195: /*
196: * sort and print
197: */
198:
199: if (mflg) {
200: printmoney();
201: exit(0);
202: }
203: qsort(tab, k, sizeof(tab[0]), nflg? ncmp: (bflg?bcmp:tcmp));
204: column(ncom, treal, tcpu, tsys);
205: printf("\n");
206: for (i=0; i<k; i++)
207: if (tab[i].name[0]) {
208: ft = tab[i].count;
209: column(ft, tab[i].realt, tab[i].cput, tab[i].syst);
210: printf(" %.14s\n", tab[i].name);
211: }
212: }
213:
214: printmoney()
215: {
216: register i;
217: char buf[128];
218: register char *cp;
219:
220: for (i=0; i<256; i++) {
221: if (user[i].ncomm) {
222: if (getpw(i, buf)!=0)
223: printf("%-8d", i);
224: else {
225: cp = buf;
226: while (*cp!=':' &&*cp!='\n' && *cp)
227: cp++;
228: *cp = 0;
229: printf("%-8s", buf);
230: }
231: printf("%7u %9.2f\n",
232: user[i].ncomm, user[i].fctime/60);
233: }
234: }
235: }
236:
237: column(n, a, b, c)
238: double n, a, b, c;
239: {
240:
241: printf("%8.0f", n);
242: if(cflg) {
243: if(n == ncom)
244: printf("%9s", ""); else
245: printf("%8.2f%%", 100.*n/ncom);
246: }
247: col(n, a, treal);
248: if (oflg)
249: col(n, 3600*(b/(b+c)), tcpu+tsys);
250: else if(lflg) {
251: col(n, b, tcpu);
252: col(n, c, tsys);
253: } else
254: col(n, b+c, tcpu+tsys);
255: if(tflg)
256: printf("%8.1f", a/(b+c));
257: }
258:
259: col(n, a, m)
260: double n, a, m;
261: {
262:
263: if(jflg)
264: printf("%11.2f", a/(n*60.)); else
265: printf("%11.2f", a/3600.);
266: if(cflg) {
267: if(a == m)
268: printf("%9s", ""); else
269: printf("%8.2f%%", 100.*a/m);
270: }
271: }
272:
273: doacct(f)
274: char *f;
275: {
276: int i;
277: FILE *ff;
278: long x;
279: struct acct fbuf;
280: register char *cp;
281: register int c;
282:
283: if (sflg && sname) {
284: printf("Only 1 file with -s\n");
285: exit(0);
286: }
287: if (sflg)
288: sname = f;
289: if ((ff = fopen(f, "r"))==NULL) {
290: printf("Can't open %s\n", f);
291: return;
292: }
293: while (fread((char *)&fbuf, sizeof(fbuf), 1, ff) == 1) {
294: if (fbuf.ac_comm[0]==0) {
295: fbuf.ac_comm[0] = '?';
296: }
297: for (cp = fbuf.ac_comm; cp < &fbuf.ac_comm[NC]; cp++) {
298: c = *cp & 0377;
299: if (c && (c < ' ' || c >= 0200)) {
300: *cp = '?';
301: }
302: }
303: if (fbuf.ac_flag&AFORK) {
304: for (cp=fbuf.ac_comm; cp < &fbuf.ac_comm[NC]; cp++)
305: if (*cp==0) {
306: *cp = '*';
307: break;
308: }
309: }
310: x = expand(fbuf.ac_utime) + expand(fbuf.ac_stime);
311: if (uflg) {
312: printf("%3d%6.1f %.14s\n", fbuf.ac_uid&0377, x/60.0,
313: fbuf.ac_comm);
314: continue;
315: }
316: c = fbuf.ac_uid&0377;
317: user[c].ncomm++;
318: user[c].fctime += x/60.;
319: ncom += 1.0;
320: i = enter(fbuf.ac_comm);
321: tab[i].count++;
322: x = expand(fbuf.ac_etime)*60;
323: tab[i].realt += x;
324: treal += x;
325: x = expand(fbuf.ac_utime);
326: tab[i].cput += x;
327: tcpu += x;
328: x = expand(fbuf.ac_stime);
329: tab[i].syst += x;
330: tsys += x;
331: }
332: fclose(ff);
333: }
334:
335: ncmp(p1, p2)
336: struct tab *p1, *p2;
337: {
338:
339: if(p1->count == p2->count)
340: return(tcmp(p1, p2));
341: if(rflg)
342: return(p1->count - p2->count);
343: return(p2->count - p1->count);
344: }
345:
346: bcmp(p1, p2)
347: struct tab *p1, *p2;
348: {
349: float f1, f2;
350: float sum();
351:
352: f1 = sum(p1)/p1->count;
353: f2 = sum(p2)/p2->count;
354: if(f1 < f2) {
355: if(rflg)
356: return(-1);
357: return(1);
358: }
359: if(f1 > f2) {
360: if(rflg)
361: return(1);
362: return(-1);
363: }
364: return(0);
365: }
366: tcmp(p1, p2)
367: struct tab *p1, *p2;
368: {
369: extern float sum();
370: float f1, f2;
371:
372: f1 = sum(p1);
373: f2 = sum(p2);
374: if(f1 < f2) {
375: if(rflg)
376: return(-1);
377: return(1);
378: }
379: if(f1 > f2) {
380: if(rflg)
381: return(1);
382: return(-1);
383: }
384: return(0);
385: }
386:
387: float sum(p)
388: struct tab *p;
389: {
390:
391: if(p->name[0] == 0)
392: return(0.0);
393: return(
394: p->cput+
395: p->syst);
396: }
397:
398: init()
399: {
400: struct tab tbuf;
401: int i;
402: FILE *f;
403:
404: if ((f = fopen("/usr/adm/savacct", "r")) == NULL)
405: goto gshm;
406: while (fread((char *)&tbuf, sizeof(tbuf), 1, f) == 1) {
407: i = enter(tbuf.name);
408: ncom += tbuf.count;
409: tab[i].count = tbuf.count;
410: treal += tbuf.realt;
411: tab[i].realt = tbuf.realt;
412: tcpu += tbuf.cput;
413: tab[i].cput = tbuf.cput;
414: tsys += tbuf.syst;
415: tab[i].syst = tbuf.syst;
416: }
417: fclose(f);
418: gshm:
419: if ((f = fopen("/usr/adm/usracct", "r")) == NULL)
420: return;
421: fread((char *)user, sizeof(user), 1, f);
422: fclose(f);
423: }
424:
425: enter(np)
426: char *np;
427: {
428: int i, j;
429:
430: for (i=j=0; i<NC; i++) {
431: if (np[i]==0)
432: j = i;
433: if (j)
434: np[i] = 0;
435: }
436: for (i=j=0; j<NC; j++) {
437: i = i*7 + np[j];
438: }
439: if (i < 0)
440: i = -i;
441: for (i%=size; tab[i].name[0]; i = (i+1)%size) {
442: for (j=0; j<NC; j++)
443: if (tab[i].name[j]!=np[j])
444: goto no;
445: goto yes;
446: no:;
447: }
448: for (j=0; j<NC; j++)
449: tab[i].name[j] = np[j];
450: yes:
451: return(i);
452: }
453:
454: strip()
455: {
456: int i, j, c;
457:
458: j = enter("**junk**");
459: for (i = 0; i<size; i++) {
460: if (tab[i].name[0] && tab[i].count<=thres) {
461: printf("%.14s--", tab[i].name);
462: if ((c=getchar())=='y') {
463: tab[i].name[0] = '\0';
464: tab[j].count += tab[i].count;
465: tab[j].realt += tab[i].realt;
466: tab[j].cput += tab[i].cput;
467: tab[j].syst += tab[i].syst;
468: }
469: while (c && c!='\n')
470: c = getchar();
471: }
472: }
473: }
474:
475: time_t
476: expand(t)
477: unsigned t;
478: {
479: register time_t nt;
480:
481: nt = t&017777;
482: t >>= 13;
483: while (t!=0) {
484: t--;
485: nt <<= 3;
486: }
487: return(nt);
488: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.