#define size 1000 /***/ /* interpret command time accounting */ int lflg; int cflg; int jflg; int nflg; int aflg; int rflg; int tflg; int vflg; int uflg; int thres 1; int sflg; int bflg; int mflg; extern int fout; struct user { int ncomm; /*** int fill; ***/ float fctime; } user[256]; struct tab { char name[8]; int count; float realt; float cput; float syst; } *tab; struct tab *enter(); struct ftab { char fname[14]; char shf; char uid; int fdatet[2]; int frealt[2]; int fcput[2]; int fsyst[2]; }; float treal; float tcpu; float tsys; struct tab *junkp 0; char *sname; float ncom; main(argc, argv) char **argv; { register i, j, k; register struct tab *ip, *kp; extern tcmp(), ncmp(), bcmp(); extern float sum(); float ft; init(); if (argc>1) if (argv[1][0]=='-') { argv++; argc--; for(i=1; argv[0][i]; i++) switch(argv[0][i]) { case 'b': bflg++; break; case 'l': lflg++; break; case 'c': cflg++; break; case 'j': jflg++; break; case 'n': nflg++; break; case 'a': aflg++; break; case 'r': rflg++; break; case 't': tflg++; break; case 's': sflg++; aflg++; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': thres = argv[0][i]-'0'; break; case 'v': vflg++; break; case 'u': uflg++; break; case 'm': mflg++; break; } } fout = dup(1); if (argc<2) acct("/usr/adm/sha"); else while (--argc) acct(*++argv); if (uflg) { flush(); return; } /* * cleanup pass * put junk togr */ if (vflg) strip(); if(!aflg) for (ip = tab; ip < &tab[size]; ip++) if (ip->name[0]) { for(j=0; j<8; j++) if(ip->name[j] == '?') goto yes; if(ip->count != 1) continue; yes: if(junkp == 0) junkp = enter("***other"); junkp->count =+ ip->count; junkp->realt =+ ip->realt; junkp->cput =+ ip->cput; junkp->syst =+ ip->syst; ip->name[0] = 0; } for (ip = kp = tab; ip < &tab[size]; ip++) if(ip->name[0]) { for(j=0; j<8; j++) kp->name[j] = ip->name[j]; tcopy(ip, kp); kp++; } k = kp-tab; if (sflg) { signal(2, 1); i = creat("/usr/adm/shm", 0666); write(i, user, sizeof(user)); close(i); if ((i = creat("/usr/adm/sht", 0666))<0) { printf("Can't save\n"); exit(); } write(i, tab, k*sizeof(*tab)); close(i); if (sname) { if ((i = creat(sname, 0666))<0) printf("Can't truncate\n"); close(i); } signal(2, 0); } /* * sort and print */ if (mflg) { printmoney(); flush(); exit(); } qsort(tab, k, sizeof *tab, nflg? &ncmp: (bflg?&bcmp:&tcmp)); printf("%8s", ""); column(ncom, treal, tcpu, tsys); for (ip=tab; ipname[0]) { ft = ip->count; printf("%-8.8s", ip->name); column(ft, ip->realt, ip->cput, ip->syst); } flush(); } printmoney() { register i; char buf[128]; register char *cp; for (i=0; i<256; i++) { if (user[i].ncomm) { if (getpw(i, buf)!=0) printf("%-8d", i); else { cp = buf; while (*cp!=':' &&*cp!='\n' && *cp) cp++; *cp = 0; printf("%-8s", buf); } printf("%5l %7.2f\n", user[i].ncomm, user[i].fctime/60); } } } column(n, a, b, c) double n, a, b, c; { register i; printf("%6d", i = n); if(cflg) { if(n == ncom) printf("%7s", ""); else printf("%6.2f%%", 100.*n/ncom); } col(n, a, treal); if(lflg) { col(n, b, tcpu); col(n, c, tsys); } else col(n, b+c, tcpu+tsys); if(tflg) printf("%6.1f", a/(b+c)); putchar('\n'); } col(n, a, m) double n, a, m; { if(jflg) printf("%9.2f", a/(n*60.)); else printf("%9.2f", a/3600.); if(cflg) { if(a == m) printf("%7s", ""); else printf("%6.2f%%", 100.*a/m); } } acct(f) char *f; { register ff; register struct tab *ip; float x; struct ftab fbuf; register char *cp; register int c; extern double ltod(); if (sflg && sname) { printf("Only 1 file with -s\n"); exit(); } if (sflg) sname = f; if ((ff=open(f, 0))<0) { printf("Can't open %s\n", f); return; } while (read(ff, &fbuf, sizeof(fbuf))==sizeof(fbuf)) { for (cp = fbuf.name; cp < &fbuf.name[8]; cp++) { c = *cp & 0377; if (c && (c < ' ' || c >= 0200)) *cp = '?'; } if (uflg) { printdate(fbuf.fdatet); printf(" %3d %.8s\n", fbuf.uid, fbuf.name); continue; } if (fbuf.shf==0) { c = fbuf.uid&0377; user[c].ncomm++; user[c].fctime =+ (ltod(fbuf.fcput)+ltod(fbuf.fsyst))/60; } ncom =+ 1.0; ip = enter(&fbuf); ip->count++; x = ltod(fbuf.frealt); x =* 60.; ip->realt =+ x; treal =+ x; x = ltod(fbuf.fcput); ip->cput =+ x; tcpu =+ x; x = ltod(fbuf.fsyst); ip->syst =+ x; tsys =+ x; } close(ff); } ncmp(p1, p2) struct tab *p1, *p2; { if(p1->count == p2->count) return(tcmp(p1, p2)); if(rflg) return(p1->count - p2->count); return(p2->count - p1->count); } bcmp(p1, p2) struct tab *p1, *p2; { float f1, f2; extern float sum(); f1 = sum(p1)/p1->count; f2 = sum(p2)/p2->count; if(f1 < f2) { if(rflg) return(-1); return(1); } if(f1 > f2) { if(rflg) return(1); return(-1); } return(0); } tcmp(p1, p2) struct tab *p1, *p2; { extern float sum(); float f1, f2; f1 = sum(p1); f2 = sum(p2); if(f1 < f2) { if(rflg) return(-1); return(1); } if(f1 > f2) { if(rflg) return(1); return(-1); } return(0); } float sum(p) struct tab *p; { if(p->name[0] == 0) return(0.0); return( p->cput+ p->syst); } init() { struct tab tbuf; register i, j, f; register struct tab *ip; /*** tab must be obtained dynamically to avoid Interdata ***/ /*** assembler bug! ***/ tab = sbrk(size * sizeof *tab); if ((f=open("/usr/adm/sht", 0))<0) goto gshm; while (read(f, &tbuf, sizeof(tbuf)) == sizeof(tbuf)) { ip = enter(&tbuf); tcopy(&tbuf, ip); ncom =+ tbuf.count; treal =+ tbuf.realt; tcpu =+ tbuf.cput; tsys =+ tbuf.syst; } close(f); gshm: if ((f=open("/usr/adm/shm", 0)) < 0) return; read(f, user, sizeof(user)); close(f); } struct ftab *enter(fbuf) struct ftab *fbuf; { register i, j; struct ftab *ip; i = 0; for (j=0; j<8; j++) { i = i*7 + fbuf->fname[j]; } if(i < 0) i = -i; for (i=%size; (ip = &tab[i])->name[0]; i = (i+1)%size) { for (j=0; j<8; j++) if (ip->name[j]!=fbuf->fname[j]) goto no; goto yes; no:; } for (j=0; j<8; j++) ip->name[j] = fbuf->fname[j]; yes: return(ip); } tcopy(from, to) int *from, *to; { register i; for (i=2; i<6; i++) to[i] = from[i]; } strip() { register k, c; register struct tab *ip, *jp; jp = enter("**junk**"); for (ip = tab; ip < &tab[size]; ip++) { if (ip->name[0] && ip->count<=thres) { printf("%.8s--", ip->name); flush(); if ((c=getchar())=='y') { ip->name[0] = '\0'; jp->count =+ ip->count; jp->realt =+ ip->realt; jp->cput =+ ip->cput; jp->syst =+ ip->syst; } while (c && c!='\n') c = getchar(); } } } printdate(tvec) int tvec[2]; { register int *lt; int *localtime(); lt = localtime(tvec); printf("%3d ", lt[7]); pair(lt[2]); pair(lt[1]); pair(lt[0]); printf(" %d", lt[6]); } pair(n) { printf("%c%c", n/10+'0', n%10+'0'); } /*** temporary ltod() -- long integer->float conversion ***/ double ltod(d) int d[2]; { float x; return(x = d[1]); } /*** temporary getpw() - get password file entry ***/ getpw() { return(-1); }