Annotation of 3BSD/cmd/sa.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.