home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1865 / w.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  5.5 KB  |  233 lines

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/file.h>
  4. #include <sys/fs/s5dir.h>
  5. #include <sys/signal.h>
  6. #include <sys/user.h>
  7. #include <fcntl.h>
  8.  
  9. #include <sys/immu.h>
  10. #include <sys/region.h>
  11. #include <sys/param.h>
  12. #include <sys/proc.h>
  13.  
  14. #include <sys/sysi86.h>
  15.  
  16. #include <utmp.h>
  17. #include <sys/stat.h>
  18. #include <time.h>
  19.  
  20. #include <sys/ipc.h>
  21. #include <sys/shm.h>
  22.  
  23. struct info {
  24.     struct info    *next;
  25.     struct utmp    ut;        /* need user, line, and time */
  26.     time_t        atime;        /* last mod time of line, for idle */
  27.     dev_t        device;        /* device id of the line */
  28.     char        *command;    /* user.u_psargs[] */
  29.     time_t        jcpu;        /* sum of all children and current */
  30.     time_t        pcpu;        /* cpu of current processes */
  31. };
  32.  
  33. char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  34.           "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  35. char *weekday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
  36.  
  37. main(argc, argv)
  38.     int argc;
  39.     char *argv[];
  40. {
  41.     struct utmp *utp;
  42.     struct user uu;
  43.     struct proc pp, *pro;
  44.     struct stat stbuf;
  45.     struct info *ip, *head;
  46.     struct tm *tmp, nowtm;
  47.     int pid, fd, s, nusers;
  48.     int c, errflag, hflag, sflag;
  49.     short pgrp;
  50.     char *user = NULL;
  51.     time_t now, boot;
  52.     extern int optind;
  53.     extern char *calloc(), *malloc();
  54.  
  55.     errflag = hflag = sflag = 0;
  56.     while ((c = getopt(argc, argv, "hls")) != EOF) {
  57.         switch (c) {
  58.         case 'h':    ++hflag; break;
  59.         case 's':    ++sflag; break;
  60.         case 'l':    sflag = 0; break;
  61.         default:    ++errflag; break;
  62.         }
  63.     }
  64.     if (optind < argc)
  65.         user = argv[optind++];
  66.     if (errflag || optind < argc) {
  67.         fprintf(stderr, "Usage: %s [-hls] [user]\n", argv[0]);
  68.         exit(1);
  69.     }
  70.     (void) chdir("/dev");
  71.     now = time(0);
  72.     nowtm = *(localtime(&now));
  73.     ip = head = NULL;
  74.     nusers = 0;
  75.     /* find out all the tty devices used (from utmp) */
  76.     while ((utp = (struct utmp *)getutent()) != NULL) {
  77.         if (utp->ut_type == BOOT_TIME)
  78.             boot = utp->ut_time;
  79.         if (utp->ut_type != USER_PROCESS)
  80.             continue;
  81.         ++nusers;
  82.         if (ip != NULL) {
  83.             ip->next = (struct info *)calloc(1, sizeof (struct info));
  84.             ip = ip->next;
  85.         } else
  86.             ip = (struct info *)calloc(1, sizeof (struct info));
  87.         ip->command = "-";
  88.         ip->jcpu = ip->pcpu = 0;
  89.         if (head == NULL)
  90.             head = ip;
  91.         ip->ut = *utp;
  92.         if (stat(utp->ut_line, &stbuf) < 0) {
  93.             ip->atime = now;
  94.             ip->device = 0;
  95.         } else {
  96.             ip->atime = stbuf.st_atime;
  97.             ip->device = stbuf.st_rdev;
  98.         }
  99.     }
  100.     boot = now - boot;
  101.     if (!strcmp(argv[0],"uptime")) {
  102.         uptime(&nowtm, boot, nusers);
  103.         exit(0);
  104.     }
  105.     if ((fd = open("/dev/kmem", O_RDONLY)) < 0) {
  106.         perror("/dev/kmem");
  107.         exit(1);
  108.     }
  109.  
  110.     for (ip = head; ip != NULL; ip = ip->next) {
  111.         if (sysi86(RDUBLK, ip->ut.ut_pid, &uu, sizeof uu) < sizeof uu) {
  112.             perror("sysi86");
  113.             exit(1);
  114.         }
  115.         if (ip == NULL)
  116.             continue;
  117.  
  118.         for(pro=uu.u_procp;pro;pro=pp.p_child) {
  119.             (void) lseek(fd, (ulong)pro, 0);
  120.             read(fd, &pp, sizeof pp);
  121.         }
  122.  
  123.         if (sysi86(RDUBLK, pp.p_pid, &uu, sizeof uu) < sizeof uu) {
  124.             perror("sysi86");
  125.             exit(1);
  126.         }
  127.  
  128.         (void) lseek(fd, (ulong)(uu.u_ttyp), 0);
  129.         read(fd, &pgrp, sizeof pgrp);
  130.  
  131.         if (pgrp == pp.p_pgrp) {
  132.             ip->command = malloc(strlen(uu.u_psargs)+1);
  133.             strcpy(ip->command, uu.u_psargs);
  134.         }
  135.         ip->pcpu += uu.u_utime + uu.u_stime;
  136.         ip->jcpu += uu.u_utime + uu.u_stime + uu.u_cutime + uu.u_cstime;
  137.  
  138. #if    0
  139. printf("pid=%d ttyp=%x ttyd=%x ttyip=%x procp=%x args=%s\n", pid,
  140.             uu.u_ttyp, uu.u_ttyd, uu.u_ttyip, uu.u_procp,
  141.             uu.u_psargs);
  142. printf("uid=%d pid=%d ppid=%d flag=%x pp.p_pgrp=%d pgrp=%d\n",
  143.             pp.p_uid, pp.p_pid, pp.p_ppid, pp.p_flag,
  144.             pp.p_pgrp, pgrp);
  145. #endif
  146.     }
  147.     close(fd);
  148.  
  149.     if (!hflag) {
  150.         uptime(&nowtm, boot, nusers);
  151.         printf("User     tty       login@  idle   JCPU   PCPU  what\n");
  152.     }
  153.  
  154.     for (ip = head; ip != NULL; ip = ip->next) {
  155.         if (user && strncmp(user, ip->ut.ut_user, 8) != 0)
  156.             continue;
  157.         printf("%-8.8s %-8.8s ", ip->ut.ut_user, ip->ut.ut_line);
  158.         tmp = localtime(&ip->ut.ut_time);
  159.         if (now - ip->ut.ut_time > 60*60*24*7)    /* > 1 week */
  160.             printf("%2d%3s%2d", tmp->tm_mday,
  161.                 month[tmp->tm_mon], tmp->tm_year%100);
  162.         else if (now - ip->ut.ut_time > 60*60*24)    /* > 1 day */
  163.             printf("%3s%2d%2s", weekday[tmp->tm_wday],
  164.                 (tmp->tm_hour % 12) +
  165.                     ((tmp->tm_hour % 12) == 0 ? 12 : 0),
  166.                 (tmp->tm_hour < 12) ? "am" : "pm");
  167.         else
  168.             printtime(tmp);
  169.         s = now-(ip->atime);
  170.         if (s < 60)
  171.             printf("      ");
  172.         else if (s < 60*60)
  173.             printf("    %2d", s/60);
  174.         else
  175.             printf("%3d:%02d", s/(60*60), (s%(60*60))/60);
  176.         printcpu(ip->jcpu);
  177.         printcpu(ip->pcpu);
  178.         printf("  %s\n", ip->command);
  179.     }
  180.     exit(0);
  181. }
  182.  
  183. printtime(tmp)
  184.     struct tm *tmp;
  185. {
  186.     printf("%2d:%02d%2s",
  187.         (tmp->tm_hour % 12) + ((tmp->tm_hour % 12) == 0 ? 12 : 0),
  188.         tmp->tm_min, (tmp->tm_hour < 12) ? "am" : "pm");
  189. }
  190.  
  191. printcpu(s)
  192.     int s;
  193. {
  194.     if (s < 100)
  195.         printf("       ");
  196.     else if (s < 6000)
  197.         printf("%7d", s/100);
  198.     else
  199.         printf("%4d:%02d", (s/100/60), (s/100)%60);
  200. }
  201.  
  202. uptime(nowtmp, sinceboot, nusers)
  203.     struct tm *nowtmp;
  204.     time_t sinceboot;
  205.     int nusers;
  206. {
  207.     int id;
  208.     float *lav;
  209.  
  210.     putchar(' ');
  211.     printtime(nowtmp);
  212.     printf("  up ");
  213.     if (sinceboot > 2*24*60*60)
  214.         printf("%d days, ", sinceboot/24/60/60);
  215.     else if (sinceboot > 24*60*60)
  216.         printf("%d day, ", sinceboot/24/60/60);
  217.     sinceboot %= 24*60*60;
  218.     if (sinceboot > 60*60)
  219.         printf("%2d:%02d", sinceboot/60/60, (sinceboot%(60*60))/60);
  220.     else
  221.         printf("%d mins", sinceboot/60);
  222.     printf(",  %d user%s", nusers, nusers == 1 ? "," : "s,");
  223.     printf("  load average: ");
  224.     id = shmget(ftok("/dev/kmem", 'lav'), 4 * sizeof (float), 0400);
  225.     if (id < 0
  226.         || (lav = (float *)shmat(id, (char *)0, SHM_RDONLY)) == (float *)-1)
  227.         printf("hard to get\n");
  228.     else {
  229.         printf("%.2f, %.2f, %.2f\n", lav[0], lav[1], lav[2]);
  230.         (void) shmdt(lav);
  231.     }
  232. }
  233.