1: #define size 2000 2: /* interpret command time accounting */ 3: 4: int lflg; 5: int cflg; 6: int jflg; 7: int nflg; 8: int aflg; 9: int rflg; 10: int tflg; 11: int vflg; 12: int uflg; 13: int thres 1; 14: int sflg; 15: int bflg; 16: int mflg; 17: int fout; 18: 19: struct user { 20: int ncomm; 21: int fill; 22: float fctime; 23: } user[256]; 24: struct tab { 25: char name[8]; 26: int count; 27: float realt; 28: float cput; 29: float syst; 30: } tab[size]; 31: 32: struct 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: }; 41: float treal; 42: float tcpu; 43: float tsys; 44: int junkp -1; 45: char *sname; 46: float ncom; 47: 48: main(argc, argv) 49: char **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: 210: printmoney() 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: 233: column(n, a, b, c) 234: double 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: 254: col(n, a, m) 255: double 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: 268: acct(f) 269: char *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: 321: ncmp(p1, p2) 322: struct 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: 332: bcmp(p1, p2) 333: struct 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: } 352: tcmp(p1, p2) 353: struct 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: 373: float sum(p) 374: struct tab *p; 375: { 376: 377: if(p->name[0] == 0) 378: return(0.0); 379: return( 380: p->cput+ 381: p->syst); 382: } 383: 384: init() 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: 410: enter(fbuf) 411: struct 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]; 430: yes: 431: return(i); 432: } 433: 434: strip() 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: 456: printdate(tvec) 457: int 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: 467: pair(n) 468: { 469: return(n/10+'0' | (n%10+'0')<<8); 470: }