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