|
|
1.1 ! root 1: static char *sccsid = "@(#)sa.c 4.1 (Berkeley) 10/1/80"; ! 2: #include <stdio.h> ! 3: #include <sys/types.h> ! 4: #include <sys/acct.h> ! 5: #include <signal.h> ! 6: ! 7: /* interpret command time accounting */ ! 8: ! 9: #define size 2500 ! 10: #define NC sizeof(acctbuf.ac_comm) ! 11: struct acct acctbuf; ! 12: int lflg; ! 13: int cflg; ! 14: int Dflg; ! 15: int dflg; ! 16: int iflg; ! 17: int jflg; ! 18: int Kflg; ! 19: int kflg; ! 20: int nflg; ! 21: int aflg; ! 22: int rflg; ! 23: int oflg; ! 24: int tflg; ! 25: int vflg; ! 26: int uflg; ! 27: int thres = 1; ! 28: int sflg; ! 29: int bflg; ! 30: int mflg; ! 31: ! 32: struct user { ! 33: int us_cnt; ! 34: double us_ctime; ! 35: double us_io; ! 36: double us_imem; ! 37: } user[1000]; ! 38: ! 39: struct tab { ! 40: char name[NC]; ! 41: int count; ! 42: double realt; ! 43: double cput; ! 44: double syst; ! 45: double imem; ! 46: double io; ! 47: } tab[size]; ! 48: ! 49: double treal; ! 50: double tcpu; ! 51: double tsys; ! 52: double tio; ! 53: double timem; ! 54: int junkp = -1; ! 55: char *sname; ! 56: double ncom; ! 57: time_t expand(); ! 58: char *getname(); ! 59: ! 60: main(argc, argv) ! 61: char **argv; ! 62: { ! 63: FILE *ff; ! 64: int i, j, k; ! 65: int (*cmp)(); ! 66: extern tcmp(), ncmp(), bcmp(), dcmp(), Dcmp(), kcmp(), Kcmp(); ! 67: extern double sum(); ! 68: double ft; ! 69: ! 70: cmp = tcmp; ! 71: if (argc>1) ! 72: if (argv[1][0]=='-') { ! 73: argv++; ! 74: argc--; ! 75: for(i=1; argv[0][i]; i++) ! 76: switch(argv[0][i]) { ! 77: ! 78: case 'o': ! 79: oflg++; ! 80: break; ! 81: ! 82: case 'i': ! 83: iflg++; ! 84: break; ! 85: ! 86: case 'b': ! 87: bflg++; ! 88: cmp = bcmp; ! 89: break; ! 90: ! 91: case 'l': ! 92: lflg++; ! 93: break; ! 94: ! 95: case 'c': ! 96: cflg++; ! 97: break; ! 98: ! 99: case 'd': ! 100: dflg++; ! 101: cmp = dcmp; ! 102: break; ! 103: ! 104: case 'D': ! 105: Dflg++; ! 106: cmp = Dcmp; ! 107: break; ! 108: ! 109: case 'j': ! 110: jflg++; ! 111: break; ! 112: ! 113: case 'k': ! 114: kflg++; ! 115: cmp = kcmp; ! 116: break; ! 117: ! 118: case 'K': ! 119: Kflg++; ! 120: cmp = Kcmp; ! 121: break; ! 122: ! 123: case 'n': ! 124: nflg++; ! 125: cmp = ncmp; ! 126: break; ! 127: ! 128: case 'a': ! 129: aflg++; ! 130: break; ! 131: ! 132: case 'r': ! 133: rflg++; ! 134: break; ! 135: ! 136: case 't': ! 137: tflg++; ! 138: break; ! 139: ! 140: case 's': ! 141: sflg++; ! 142: aflg++; ! 143: break; ! 144: ! 145: case '0': ! 146: case '1': ! 147: case '2': ! 148: case '3': ! 149: case '4': ! 150: case '5': ! 151: case '6': ! 152: case '7': ! 153: case '8': ! 154: case '9': ! 155: thres = argv[0][i]-'0'; ! 156: break; ! 157: ! 158: case 'v': ! 159: vflg++; ! 160: break; ! 161: ! 162: case 'u': ! 163: uflg++; ! 164: break; ! 165: ! 166: case 'm': ! 167: mflg++; ! 168: break; ! 169: } ! 170: } ! 171: if (iflg==0) ! 172: init(); ! 173: if (argc<2) ! 174: doacct("/usr/adm/acct"); ! 175: else while (--argc) ! 176: doacct(*++argv); ! 177: if (uflg) { ! 178: return; ! 179: } ! 180: ! 181: /* ! 182: * cleanup pass ! 183: * put junk together ! 184: */ ! 185: ! 186: if (vflg) ! 187: strip(); ! 188: if(!aflg) ! 189: for (i=0; i<size; i++) ! 190: if (tab[i].name[0]) { ! 191: for(j=0; j<NC; j++) ! 192: if(tab[i].name[j] == '?') ! 193: goto yes; ! 194: if(tab[i].count != 1) ! 195: continue; ! 196: yes: ! 197: if(junkp == -1) ! 198: junkp = enter("***other"); ! 199: tab[junkp].count += tab[i].count; ! 200: tab[junkp].realt += tab[i].realt; ! 201: tab[junkp].cput += tab[i].cput; ! 202: tab[junkp].syst += tab[i].syst; ! 203: tab[junkp].imem += tab[i].imem; ! 204: tab[junkp].io += tab[i].io; ! 205: tab[i].name[0] = 0; ! 206: } ! 207: for(i=k=0; i<size; i++) ! 208: if(tab[i].name[0]) { ! 209: tab[k] = tab[i]; ! 210: k++; ! 211: } ! 212: if (sflg) { ! 213: signal(SIGINT, SIG_IGN); ! 214: if ((ff = fopen("/usr/adm/usracct", "w")) != NULL) { ! 215: fwrite((char *)user, sizeof(user), 1, ff); ! 216: fclose(ff); ! 217: } ! 218: if ((ff = fopen("/usr/adm/savacct", "w")) == NULL) { ! 219: printf("Can't save\n"); ! 220: exit(0); ! 221: } ! 222: fwrite((char *)tab, sizeof(tab[0]), k, ff); ! 223: fclose(ff); ! 224: creat("/usr/adm/acct", 0644); ! 225: signal(SIGINT, SIG_DFL); ! 226: } ! 227: /* ! 228: * sort and print ! 229: */ ! 230: ! 231: if (mflg) { ! 232: printmoney(); ! 233: exit(0); ! 234: } ! 235: qsort(tab, k, sizeof(tab[0]), cmp); ! 236: column(ncom, treal, tcpu, tsys, timem, tio); ! 237: printf("\n"); ! 238: for (i=0; i<k; i++) ! 239: if (tab[i].name[0]) { ! 240: ft = tab[i].count; ! 241: column(ft, tab[i].realt, tab[i].cput, tab[i].syst, tab[i].imem, tab[i].io); ! 242: printf(" %.14s\n", tab[i].name); ! 243: } ! 244: } ! 245: ! 246: printmoney() ! 247: { ! 248: register i; ! 249: char buf[128]; ! 250: register char *cp; ! 251: ! 252: for (i=0; i<sizeof(user)/sizeof(user[0]); i++) { ! 253: if (user[i].us_cnt && user[i].us_ctime) { ! 254: cp = getname(i); ! 255: if (cp == 0) ! 256: printf("%-8d", i); ! 257: else ! 258: printf("%-8s", cp); ! 259: printf("%7u %9.2fcpu %10.0ftio %12.0fk*sec\n", ! 260: user[i].us_cnt, user[i].us_ctime/60, ! 261: user[i].us_io, ! 262: user[i].us_imem / (60 * 2)); ! 263: } ! 264: } ! 265: } ! 266: ! 267: column(n, a, b, c, d, e) ! 268: double n, a, b, c, d, e; ! 269: { ! 270: ! 271: printf("%8.0f", n); ! 272: if(cflg) { ! 273: if(n == ncom) ! 274: printf("%9s", ""); else ! 275: printf("%8.2f%%", 100.*n/ncom); ! 276: } ! 277: col(n, a, treal, "re"); ! 278: if (oflg) ! 279: col(n, 3600*(b/(b+c)), tcpu+tsys, "u/s"); ! 280: else if(lflg) { ! 281: col(n, b, tcpu, "u"); ! 282: col(n, c, tsys, "s"); ! 283: } else ! 284: col(n, b+c, tcpu+tsys, "cp"); ! 285: if(tflg) ! 286: printf("%8.1f", a/(b+c), "re/cp"); ! 287: if(dflg || !Dflg) ! 288: printf("%10.0favio", e/(n?n:1)); ! 289: else ! 290: printf("%10.0ftio", e); ! 291: if (kflg || !Kflg) ! 292: printf("%10.0fk", d/(2*((b+c)!=0.0?(b+c):1.0))); ! 293: else ! 294: printf("%10.0fk*sec", d/(2*60)); ! 295: } ! 296: ! 297: col(n, a, m, cp) ! 298: double n, a, m; ! 299: char *cp; ! 300: { ! 301: ! 302: if(jflg) ! 303: printf("%11.2f%s", a/(n*60.), cp); else ! 304: printf("%11.2f%s", a/3600., cp); ! 305: if(cflg) { ! 306: if(a == m) ! 307: printf("%9s", ""); else ! 308: printf("%8.2f%%", 100.*a/m); ! 309: } ! 310: } ! 311: ! 312: doacct(f) ! 313: char *f; ! 314: { ! 315: int i; ! 316: FILE *ff; ! 317: long x, y, z; ! 318: struct acct fbuf; ! 319: register char *cp; ! 320: register int c; ! 321: ! 322: if (sflg && sname) { ! 323: printf("Only 1 file with -s\n"); ! 324: exit(0); ! 325: } ! 326: if (sflg) ! 327: sname = f; ! 328: if ((ff = fopen(f, "r"))==NULL) { ! 329: printf("Can't open %s\n", f); ! 330: return; ! 331: } ! 332: while (fread((char *)&fbuf, sizeof(fbuf), 1, ff) == 1) { ! 333: if (fbuf.ac_comm[0]==0) { ! 334: fbuf.ac_comm[0] = '?'; ! 335: } ! 336: for (cp = fbuf.ac_comm; cp < &fbuf.ac_comm[NC]; cp++) { ! 337: c = *cp & 0377; ! 338: if (c && (c < ' ' || c >= 0200)) { ! 339: *cp = '?'; ! 340: } ! 341: } ! 342: if (fbuf.ac_flag&AFORK) { ! 343: for (cp=fbuf.ac_comm; cp < &fbuf.ac_comm[NC]; cp++) ! 344: if (*cp==0) { ! 345: *cp = '*'; ! 346: break; ! 347: } ! 348: } ! 349: x = expand(fbuf.ac_utime) + expand(fbuf.ac_stime); ! 350: y = fbuf.ac_mem; ! 351: z = expand(fbuf.ac_io); ! 352: if (uflg) { ! 353: printf("%3d%6.1fcp %6dmem %6dio %.14s\n", ! 354: fbuf.ac_uid, x/60.0, y, z, ! 355: fbuf.ac_comm); ! 356: continue; ! 357: } ! 358: c = fbuf.ac_uid; ! 359: user[c].us_cnt++; ! 360: user[c].us_ctime += x/60.; ! 361: user[c].us_imem += x * y; ! 362: user[c].us_io += z; ! 363: ncom += 1.0; ! 364: i = enter(fbuf.ac_comm); ! 365: tab[i].imem += x * y; ! 366: timem += x * y; ! 367: tab[i].count++; ! 368: x = expand(fbuf.ac_etime)*60; ! 369: tab[i].realt += x; ! 370: treal += x; ! 371: x = expand(fbuf.ac_utime); ! 372: tab[i].cput += x; ! 373: tcpu += x; ! 374: x = expand(fbuf.ac_stime); ! 375: tab[i].syst += x; ! 376: tsys += x; ! 377: tab[i].io += z; ! 378: tio += z; ! 379: } ! 380: fclose(ff); ! 381: } ! 382: ! 383: ncmp(p1, p2) ! 384: struct tab *p1, *p2; ! 385: { ! 386: ! 387: if(p1->count == p2->count) ! 388: return(tcmp(p1, p2)); ! 389: if(rflg) ! 390: return(p1->count - p2->count); ! 391: return(p2->count - p1->count); ! 392: } ! 393: ! 394: bcmp(p1, p2) ! 395: struct tab *p1, *p2; ! 396: { ! 397: double f1, f2; ! 398: double sum(); ! 399: ! 400: f1 = sum(p1)/p1->count; ! 401: f2 = sum(p2)/p2->count; ! 402: if(f1 < f2) { ! 403: if(rflg) ! 404: return(-1); ! 405: return(1); ! 406: } ! 407: if(f1 > f2) { ! 408: if(rflg) ! 409: return(1); ! 410: return(-1); ! 411: } ! 412: return(0); ! 413: } ! 414: ! 415: Kcmp(p1, p2) ! 416: struct tab *p1, *p2; ! 417: { ! 418: ! 419: if (p1->imem < p2->imem) { ! 420: if(rflg) ! 421: return(-1); ! 422: return(1); ! 423: } ! 424: if (p1->imem > p2->imem) { ! 425: if(rflg) ! 426: return(1); ! 427: return(-1); ! 428: } ! 429: return(0); ! 430: } ! 431: ! 432: kcmp(p1, p2) ! 433: struct tab *p1, *p2; ! 434: { ! 435: double a1, a2; ! 436: ! 437: a1 = p1->imem / ((p1->cput+p1->syst)?(p1->cput+p1->syst):1); ! 438: a2 = p2->imem / ((p2->cput+p2->syst)?(p2->cput+p2->syst):1); ! 439: if (a1 < a2) { ! 440: if(rflg) ! 441: return(-1); ! 442: return(1); ! 443: } ! 444: if (a1 > a2) { ! 445: if(rflg) ! 446: return(1); ! 447: return(-1); ! 448: } ! 449: return(0); ! 450: } ! 451: ! 452: dcmp(p1, p2) ! 453: struct tab *p1, *p2; ! 454: { ! 455: double a1, a2; ! 456: ! 457: a1 = p1->io / (p1->count?p1->count:1); ! 458: a2 = p2->io / (p2->count?p2->count:1); ! 459: if (a1 < a2) { ! 460: if(rflg) ! 461: return(-1); ! 462: return(1); ! 463: } ! 464: if (a1 > a2) { ! 465: if(rflg) ! 466: return(1); ! 467: return(-1); ! 468: } ! 469: return(0); ! 470: } ! 471: ! 472: Dcmp(p1, p2) ! 473: struct tab *p1, *p2; ! 474: { ! 475: ! 476: if (p1->io < p2->io) { ! 477: if(rflg) ! 478: return(-1); ! 479: return(1); ! 480: } ! 481: if (p1->io > p2->io) { ! 482: if(rflg) ! 483: return(1); ! 484: return(-1); ! 485: } ! 486: return(0); ! 487: } ! 488: ! 489: tcmp(p1, p2) ! 490: struct tab *p1, *p2; ! 491: { ! 492: extern double sum(); ! 493: double f1, f2; ! 494: ! 495: f1 = sum(p1); ! 496: f2 = sum(p2); ! 497: if(f1 < f2) { ! 498: if(rflg) ! 499: return(-1); ! 500: return(1); ! 501: } ! 502: if(f1 > f2) { ! 503: if(rflg) ! 504: return(1); ! 505: return(-1); ! 506: } ! 507: return(0); ! 508: } ! 509: ! 510: double sum(p) ! 511: struct tab *p; ! 512: { ! 513: ! 514: if(p->name[0] == 0) ! 515: return(0.0); ! 516: return( ! 517: p->cput+ ! 518: p->syst); ! 519: } ! 520: ! 521: init() ! 522: { ! 523: struct tab tbuf; ! 524: int i; ! 525: FILE *f; ! 526: ! 527: if ((f = fopen("/usr/adm/savacct", "r")) == NULL) ! 528: goto gshm; ! 529: while (fread((char *)&tbuf, sizeof(tbuf), 1, f) == 1) { ! 530: i = enter(tbuf.name); ! 531: ncom += tbuf.count; ! 532: tab[i].count = tbuf.count; ! 533: treal += tbuf.realt; ! 534: tab[i].realt = tbuf.realt; ! 535: tcpu += tbuf.cput; ! 536: tab[i].cput = tbuf.cput; ! 537: tsys += tbuf.syst; ! 538: tab[i].syst = tbuf.syst; ! 539: tio += tbuf.io; ! 540: tab[i].io = tbuf.io; ! 541: timem += tbuf.imem; ! 542: tab[i].imem = tbuf.imem; ! 543: } ! 544: fclose(f); ! 545: gshm: ! 546: if ((f = fopen("/usr/adm/usracct", "r")) == NULL) ! 547: return; ! 548: fread((char *)user, sizeof(user), 1, f); ! 549: fclose(f); ! 550: } ! 551: ! 552: enter(np) ! 553: char *np; ! 554: { ! 555: int i, j; ! 556: ! 557: for (i=j=0; i<NC; i++) { ! 558: if (np[i]==0) ! 559: j = i; ! 560: if (j) ! 561: np[i] = 0; ! 562: } ! 563: for (i=j=0; j<NC; j++) { ! 564: i = i*7 + np[j]; ! 565: } ! 566: if (i < 0) ! 567: i = -i; ! 568: for (i%=size; tab[i].name[0]; i = (i+1)%size) { ! 569: for (j=0; j<NC; j++) ! 570: if (tab[i].name[j]!=np[j]) ! 571: goto no; ! 572: goto yes; ! 573: no:; ! 574: } ! 575: for (j=0; j<NC; j++) ! 576: tab[i].name[j] = np[j]; ! 577: yes: ! 578: return(i); ! 579: } ! 580: ! 581: strip() ! 582: { ! 583: int i, j, c; ! 584: ! 585: j = enter("**junk**"); ! 586: for (i = 0; i<size; i++) { ! 587: if (tab[i].name[0] && tab[i].count<=thres) { ! 588: printf("%.14s--", tab[i].name); ! 589: if ((c=getchar())=='y') { ! 590: tab[i].name[0] = '\0'; ! 591: tab[j].count += tab[i].count; ! 592: tab[j].realt += tab[i].realt; ! 593: tab[j].cput += tab[i].cput; ! 594: tab[j].syst += tab[i].syst; ! 595: } ! 596: while (c && c!='\n') ! 597: c = getchar(); ! 598: } ! 599: } ! 600: } ! 601: ! 602: time_t ! 603: expand(t) ! 604: unsigned t; ! 605: { ! 606: register time_t nt; ! 607: ! 608: nt = t&017777; ! 609: t >>= 13; ! 610: while (t!=0) { ! 611: t--; ! 612: nt <<= 3; ! 613: } ! 614: return(nt); ! 615: } ! 616: ! 617: #include <utmp.h> ! 618: #include <pwd.h> ! 619: ! 620: struct utmp utmp; ! 621: #define NMAX sizeof (utmp.ut_name) ! 622: #define NUID 2048 ! 623: ! 624: char names[NUID][NMAX+1]; ! 625: ! 626: char * ! 627: getname(uid) ! 628: { ! 629: register struct passwd *pw; ! 630: static init; ! 631: struct passwd *getpwent(); ! 632: ! 633: if (names[uid][0]) ! 634: return (&names[uid][0]); ! 635: if (init == 2) ! 636: return (0); ! 637: if (init == 0) ! 638: setpwent(), init = 1; ! 639: while (pw = getpwent()) { ! 640: if (pw->pw_uid >= NUID) ! 641: continue; ! 642: if (names[pw->pw_uid][0]) ! 643: continue; ! 644: strncpy(names[pw->pw_uid], pw->pw_name, NMAX); ! 645: if (pw->pw_uid == uid) ! 646: return (&names[uid][0]); ! 647: } ! 648: init = 2; ! 649: endpwent(); ! 650: return (0); ! 651: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.