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    1000
   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[256];
  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:         signal(SIGINT, SIG_DFL);
 193:     }
 194: /*
 195:  * sort and print
 196:  */
 197: 
 198:     if (mflg) {
 199:         printmoney();
 200:         exit(0);
 201:     }
 202:     qsort(tab, k, sizeof(tab[0]), nflg? ncmp: (bflg?bcmp:tcmp));
 203:     column(ncom, treal, tcpu, tsys);
 204:     printf("\n");
 205:     for (i=0; i<k; i++)
 206:     if (tab[i].name[0]) {
 207:         ft = tab[i].count;
 208:         column(ft, tab[i].realt, tab[i].cput, tab[i].syst);
 209:         printf("   %.10s\n", tab[i].name);
 210:     }
 211: }
 212: 
 213: printmoney()
 214: {
 215:     register i;
 216:     char buf[128];
 217:     register char *cp;
 218: 
 219:     for (i=0; i<256; i++) {
 220:         if (user[i].ncomm) {
 221:             if (getpw(i, buf)!=0)
 222:                 printf("%-8d", i);
 223:             else {
 224:                 cp = buf;
 225:                 while (*cp!=':' &&*cp!='\n' && *cp)
 226:                     cp++;
 227:                 *cp = 0;
 228:                 printf("%-8s", buf);
 229:             }
 230:             printf("%5u %7.2f\n",
 231:                 user[i].ncomm, user[i].fctime/60);
 232:         }
 233:     }
 234: }
 235: 
 236: column(n, a, b, c)
 237: double n, a, b, c;
 238: {
 239: 
 240:     printf("%6.0f", n);
 241:     if(cflg) {
 242:         if(n == ncom)
 243:             printf("%7s", ""); else
 244:             printf("%6.2f%%", 100.*n/ncom);
 245:     }
 246:     col(n, a, treal);
 247:     if (oflg)
 248:         col(n, 3600*(b/(b+c)), tcpu+tsys);
 249:     else if(lflg) {
 250:         col(n, b, tcpu);
 251:         col(n, c, tsys);
 252:     } else
 253:         col(n, b+c, tcpu+tsys);
 254:     if(tflg)
 255:         printf("%6.1f", a/(b+c));
 256: }
 257: 
 258: col(n, a, m)
 259: double n, a, m;
 260: {
 261: 
 262:     if(jflg)
 263:         printf("%9.2f", a/(n*60.)); else
 264:         printf("%9.2f", a/3600.);
 265:     if(cflg) {
 266:         if(a == m)
 267:             printf("%7s", ""); else
 268:             printf("%6.2f%%", 100.*a/m);
 269:     }
 270: }
 271: 
 272: doacct(f)
 273: char *f;
 274: {
 275:     int i;
 276:     FILE *ff;
 277:     long x;
 278:     struct acct fbuf;
 279:     register char *cp;
 280:     register int c;
 281: 
 282:     if (sflg && sname) {
 283:         printf("Only 1 file with -s\n");
 284:         exit(0);
 285:     }
 286:     if (sflg)
 287:         sname = f;
 288:     if ((ff = fopen(f, "r"))==NULL) {
 289:         printf("Can't open %s\n", f);
 290:         return;
 291:     }
 292:     while (fread((char *)&fbuf, sizeof(fbuf), 1, ff) == 1) {
 293:         if (fbuf.ac_comm[0]==0) {
 294:             fbuf.ac_comm[0] = '?';
 295:         }
 296:         for (cp = fbuf.ac_comm; cp < &fbuf.ac_comm[NC]; cp++) {
 297:             c = *cp & 0377;
 298:             if (c && (c < ' ' || c >= 0200)) {
 299:                 *cp = '?';
 300:             }
 301:         }
 302:         if (fbuf.ac_flag&AFORK) {
 303:             for (cp=fbuf.ac_comm; cp < &fbuf.ac_comm[NC]; cp++)
 304:                 if (*cp==0) {
 305:                     *cp = '*';
 306:                     break;
 307:                 }
 308:         }
 309:         x = expand(fbuf.ac_utime) + expand(fbuf.ac_stime);
 310:         if (uflg) {
 311:             printf("%3d%6.1f %.10s\n", fbuf.ac_uid&0377, x/60.0,
 312:                fbuf.ac_comm);
 313:             continue;
 314:         }
 315:         c = fbuf.ac_uid&0377;
 316:         user[c].ncomm++;
 317:         user[c].fctime += x/60.;
 318:         ncom += 1.0;
 319:         i = enter(fbuf.ac_comm);
 320:         tab[i].count++;
 321:         x = expand(fbuf.ac_etime)*60;
 322:         tab[i].realt += x;
 323:         treal += x;
 324:         x = expand(fbuf.ac_utime);
 325:         tab[i].cput += x;
 326:         tcpu += x;
 327:         x = expand(fbuf.ac_stime);
 328:         tab[i].syst += x;
 329:         tsys += x;
 330:     }
 331:     fclose(ff);
 332: }
 333: 
 334: ncmp(p1, p2)
 335: struct tab *p1, *p2;
 336: {
 337: 
 338:     if(p1->count == p2->count)
 339:         return(tcmp(p1, p2));
 340:     if(rflg)
 341:         return(p1->count - p2->count);
 342:     return(p2->count - p1->count);
 343: }
 344: 
 345: bcmp(p1, p2)
 346: struct tab *p1, *p2;
 347: {
 348:     float f1, f2;
 349:     float sum();
 350: 
 351:     f1 = sum(p1)/p1->count;
 352:     f2 = sum(p2)/p2->count;
 353:     if(f1 < f2) {
 354:         if(rflg)
 355:             return(-1);
 356:         return(1);
 357:     }
 358:     if(f1 > f2) {
 359:         if(rflg)
 360:             return(1);
 361:         return(-1);
 362:     }
 363:     return(0);
 364: }
 365: tcmp(p1, p2)
 366: struct tab *p1, *p2;
 367: {
 368:     extern float sum();
 369:     float f1, f2;
 370: 
 371:     f1 = sum(p1);
 372:     f2 = sum(p2);
 373:     if(f1 < f2) {
 374:         if(rflg)
 375:             return(-1);
 376:         return(1);
 377:     }
 378:     if(f1 > f2) {
 379:         if(rflg)
 380:             return(1);
 381:         return(-1);
 382:     }
 383:     return(0);
 384: }
 385: 
 386: float sum(p)
 387: struct tab *p;
 388: {
 389: 
 390:     if(p->name[0] == 0)
 391:         return(0.0);
 392:     return(
 393:         p->cput+
 394:         p->syst);
 395: }
 396: 
 397: init()
 398: {
 399:     struct tab tbuf;
 400:     int i;
 401:     FILE *f;
 402: 
 403:     if ((f = fopen("/usr/adm/savacct", "r")) == NULL)
 404:         goto gshm;
 405:     while (fread((char *)&tbuf, sizeof(tbuf), 1, f) == 1) {
 406:         i = enter(tbuf.name);
 407:         ncom += tbuf.count;
 408:         tab[i].count = tbuf.count;
 409:         treal += tbuf.realt;
 410:         tab[i].realt = tbuf.realt;
 411:         tcpu += tbuf.cput;
 412:         tab[i].cput = tbuf.cput;
 413:         tsys += tbuf.syst;
 414:         tab[i].syst = tbuf.syst;
 415:     }
 416:     fclose(f);
 417:  gshm:
 418:     if ((f = fopen("/usr/adm/usracct", "r")) == NULL)
 419:         return;
 420:     fread((char *)user, sizeof(user), 1, f);
 421:     fclose(f);
 422: }
 423: 
 424: enter(np)
 425: char *np;
 426: {
 427:     int i, j;
 428: 
 429:     for (i=j=0; i<NC; i++) {
 430:         if (np[i]==0)
 431:             j = i;
 432:         if (j)
 433:             np[i] = 0;
 434:     }
 435:     for (i=j=0; j<NC; j++) {
 436:         i = i*7 + np[j];
 437:     }
 438:     if (i < 0)
 439:         i = -i;
 440:     for (i%=size; tab[i].name[0]; i = (i+1)%size) {
 441:         for (j=0; j<NC; j++)
 442:             if (tab[i].name[j]!=np[j])
 443:                 goto no;
 444:         goto yes;
 445:     no:;
 446:     }
 447:     for (j=0; j<NC; j++)
 448:         tab[i].name[j] = np[j];
 449: yes:
 450:     return(i);
 451: }
 452: 
 453: strip()
 454: {
 455:     int i, j, c;
 456: 
 457:     j = enter("**junk**");
 458:     for (i = 0; i<size; i++) {
 459:         if (tab[i].name[0] && tab[i].count<=thres) {
 460:             printf("%.10s--", tab[i].name);
 461:             if ((c=getchar())=='y') {
 462:                 tab[i].name[0] = '\0';
 463:                 tab[j].count += tab[i].count;
 464:                 tab[j].realt += tab[i].realt;
 465:                 tab[j].cput += tab[i].cput;
 466:                 tab[j].syst += tab[i].syst;
 467:             }
 468:             while (c && c!='\n')
 469:                 c = getchar();
 470:         }
 471:     }
 472: }
 473: 
 474: time_t
 475: expand(t)
 476: unsigned t;
 477: {
 478:     register time_t nt;
 479: 
 480:     nt = t&017777;
 481:     t >>= 13;
 482:     while (t!=0) {
 483:         t--;
 484:         nt <<= 3;
 485:     }
 486:     return(nt);
 487: }

Defined functions

bcmp defined in line 345; used 2 times
col defined in line 258; used 5 times
column defined in line 236; used 2 times
doacct defined in line 272; used 2 times
enter defined in line 424; used 4 times
expand defined in line 474; used 6 times
init defined in line 397; used 1 times
main defined in line 49; never used
ncmp defined in line 334; used 2 times
printmoney defined in line 213; used 1 times
strip defined in line 453; used 1 times
sum defined in line 386; used 7 times
tcmp defined in line 365; used 3 times

Defined variables

acctbuf defined in line 10; used 1 times
  • in line 9
aflg defined in line 16; used 3 times
bflg defined in line 24; used 2 times
cflg defined in line 12; used 3 times
iflg defined in line 13; used 2 times
jflg defined in line 14; used 2 times
junkp defined in line 44; used 6 times
lflg defined in line 11; used 2 times
mflg defined in line 25; used 2 times
ncom defined in line 46; used 5 times
nflg defined in line 15; used 2 times
oflg defined in line 18; used 2 times
rflg defined in line 17; used 6 times
sflg defined in line 23; used 4 times
sname defined in line 45; used 2 times
tab defined in line 39; used 56 times
tcpu defined in line 42; used 6 times
tflg defined in line 19; used 2 times
thres defined in line 22; used 2 times
treal defined in line 41; used 4 times
tsys defined in line 43; used 6 times
uflg defined in line 21; used 3 times
user defined in line 31; used 9 times
vflg defined in line 20; used 2 times

Defined struct's

tab defined in line 33; used 10 times
user defined in line 27; never used

Defined macros

NC defined in line 9; used 9 times
size defined in line 8; used 6 times
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1480
Valid CSS Valid XHTML 1.0 Strict