MiniUnix/usr/source/s2/sa.c
#define size 2000
/* 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;
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[size];
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;
int junkp -1;
char *sname;
float ncom;
main(argc, argv)
char **argv;
{
int i, j, k;
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 together
*/
if (vflg)
strip();
if(!aflg)
for (i=0; i<size; i++)
if (tab[i].name[0]) {
for(j=0; j<8; j++)
if(tab[i].name[j] == '?')
goto yes;
if(tab[i].count != 1)
continue;
yes:
if(junkp == -1)
junkp = enter("***other");
tab[junkp].count =+ tab[i].count;
tab[junkp].realt =+ tab[i].realt;
tab[junkp].cput =+ tab[i].cput;
tab[junkp].syst =+ tab[i].syst;
tab[i].name[0] = 0;
}
for(i=k=0; i<size; i++)
if(tab[i].name[0]) {
for(j=0; j<8; j++)
tab[k].name[j] = tab[i].name[j];
tab[k].count = tab[i].count;
tab[k].realt = tab[i].realt;
tab[k].cput = tab[i].cput;
tab[k].syst = tab[i].syst;
k++;
}
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, 22, nflg? &ncmp: (bflg?&bcmp:&tcmp));
printf("%8s", "");
column(ncom, treal, tcpu, tsys);
for (i=0; i<k; i++)
if (tab[i].name[0]) {
ft = tab[i].count;
printf("%-8.8s", tab[i].name);
column(ft, tab[i].realt, tab[i].cput, tab[i].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;
{
printf("%6.0f", 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;
{
int ff, i, j;
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;
i = enter(&fbuf);
tab[i].count++;
x = ltod(fbuf.frealt);
x =* 60.;
tab[i].realt =+ x;
treal =+ x;
x = ltod(fbuf.fcput);
tab[i].cput =+ x;
tcpu =+ x;
x = ltod(fbuf.fsyst);
tab[i].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;
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;
int i, j, f;
if ((f=open("/usr/adm/sht", 0))<0)
goto gshm;
while (read(f, &tbuf, sizeof(tbuf)) == sizeof(tbuf)) {
i = enter(&tbuf);
ncom =+ tbuf.count;
tab[i].count = tbuf.count;
treal =+ tbuf.realt;
tab[i].realt = tbuf.realt;
tcpu =+ tbuf.cput;
tab[i].cput = tbuf.cput;
tsys =+ tbuf.syst;
tab[i].syst = tbuf.syst;
}
close(f);
gshm:
if ((f=open("/usr/adm/shm", 0)) < 0)
return;
read(f, user, sizeof(user));
close(f);
}
enter(fbuf)
struct ftab *fbuf;
{
int i, j;
i = 0;
for (j=0; j<8; j++) {
i = i*7 + fbuf->fname[j];
}
if(i < 0)
i = -i;
for (i=%size; tab[i].name[0]; i = (i+1)%size) {
for (j=0; j<8; j++)
if (tab[i].name[j]!=fbuf->fname[j])
goto no;
goto yes;
no:;
}
for (j=0; j<8; j++)
tab[i].name[j] = fbuf->fname[j];
yes:
return(i);
}
strip()
{
int i, j, k, c;
j = enter("**junk**");
for (i = 0; i<size; i++) {
if (tab[i].name[0] && tab[i].count<=thres) {
printf("%.8s--", tab[i].name);
flush();
if ((c=getchar())=='y') {
tab[i].name[0] = '\0';
tab[j].count =+ tab[i].count;
tab[j].realt =+ tab[i].realt;
tab[j].cput =+ tab[i].cput;
tab[j].syst =+ tab[i].syst;
}
while (c && c!='\n')
c = getchar();
}
}
}
printdate(tvec)
int tvec[2];
{
int *lt;
int *localtime();
lt = localtime(tvec);
printf("%3d %c%c%c %d", lt[7],
pair(lt[2]), pair(lt[1]), pair(lt[0]), lt[6]);
}
pair(n)
{
return(n/10+'0' | (n%10+'0')<<8);
}