home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / sa.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-05-05  |  7.1 KB  |  488 lines

  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. }
  488.