home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume5 / xenix.w / w.c < prev   
Encoding:
C/C++ Source or Header  |  1989-02-03  |  7.0 KB  |  352 lines

  1. /*
  2.  * %W% %E% %U% ncoast!bsa %Z%
  3.  * %Z% Copyright (C) 1985 by Brandon S. Allbery, All Rights Reserved %Z%
  4.  *
  5.  *    8-Jul-88 John F. Haugh II (jfh@rpp386)
  6.  *    Major hacks to force to work on SCO Xenix 386
  7.  */
  8.  
  9. #ifndef lint
  10. static char _SccsId[] = "%W% %E% %U% ncoast!bsa %Z%";
  11. static char _CopyRt[] = "%Z% Copyright (C) 1985 by Brandon S. Allbery %Z%";
  12. #endif  lint
  13.  
  14. #include <stdio.h>
  15. #include <time.h>
  16. #include <signal.h>
  17. #include <a.out.h>
  18. #include <sys/types.h>
  19. #include <sys/page.h>
  20. #include <sys/seg.h>
  21. #include <sys/param.h>
  22. #include <sys/var.h>
  23. #include <sys/proc.h>
  24. #include <sys/dir.h>
  25. #include <sys/user.h>
  26. #include <sys/stat.h>
  27. #include <sys/ipc.h>
  28. #include <sys/shm.h>
  29. #include <sys/sysmacros.h>
  30. #include <utmp.h>
  31.  
  32. #define UTMP           "/etc/utmp"
  33. #ifndef KERNEL
  34. #define KERNEL         "/xenix"
  35. #endif
  36. #define KMEM           "/dev/kmem"
  37. #define PMEM           "/dev/mem"
  38. #define SMEM           "/dev/swap"
  39.  
  40. #define MIN            (60)
  41. #define HOUR           (MIN * 60)
  42. #define DAY            (HOUR * 24)
  43. #define WEEK           (DAY * 7)
  44. #define MONTH          (DAY * 30)
  45.  
  46. FILE *kfd;
  47. FILE *mfd;
  48. FILE *sfd;
  49. FILE *utmp;
  50. long nproc;
  51. char _SObuf[BUFSIZ];
  52. daddr_t swplo;
  53. short mypid;
  54.  
  55. struct xlist kernel[] = {
  56.     {0, 0, 0, "_v"},
  57.     {0, 0, 0, "_proc"},
  58.     {0, 0, 0, "_swplo"},
  59.     {0, 0, 0, "_lbolt"},
  60.     {0, 0, 0, (char *) 0},
  61. };
  62.  
  63. char *months[] = {
  64.     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  65.     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
  66. };
  67.  
  68. struct tm *localtime();
  69. char *vtime();
  70. char *uptime();
  71. char *itoa();
  72.  
  73. main() {
  74.     struct utmp user;
  75.     short ucnt;
  76.     long now;
  77.     struct var vars;
  78.     
  79.     setbuf(stdout, _SObuf);
  80.     mypid = getpid();
  81.     time(&now);
  82.     if (xlist(KERNEL, kernel) == -1) {
  83.         perror(KERNEL);
  84.         exit(2);
  85.     }
  86.     if ((utmp = fopen(UTMP, "r")) == NULL) {
  87.         perror(UTMP);
  88.         exit(1);
  89.     }
  90.     ucnt = 0;
  91.     while (fread(&user, sizeof user, 1, utmp) > 0) {
  92.         if (user.ut_type != USER_PROCESS)
  93.             continue;
  94.         ucnt++;
  95.     }
  96.     if (kfd == NULL) {
  97.         if ((kfd = fopen(KMEM, "r")) == NULL) {
  98.             perror(KMEM);
  99.             exit(3);
  100.         }
  101.     }
  102.     fseek(kfd, kernel[0].xl_value, 0);
  103.     fread(&vars, sizeof vars, 1, kfd);
  104.     nproc = vars.v_proc;
  105.     fseek(kfd, kernel[2].xl_value, 0);
  106.     fread(&swplo, sizeof swplo, 1, kfd);
  107.     if (mfd == NULL) {
  108.         if ((mfd = fopen(PMEM, "r")) == NULL) {
  109.             perror(PMEM);
  110.             exit(4);
  111.         }
  112.     }
  113.     if (sfd == NULL) {
  114.         if ((sfd = fopen(SMEM, "r")) == NULL) {
  115.             perror(SMEM);
  116.             exit(5);
  117.         }
  118.     }
  119.     printf(" %s  up%s,  %d users\nUser     tty       login@  idle   JCPU   PCPU what\n", vtime(&now), uptime(), ucnt);
  120.     rewind(utmp);
  121.     while (fread(&user, sizeof user, 1, utmp) > 0) {
  122.         if (user.ut_type != USER_PROCESS)
  123.             continue;
  124.         show(&user);
  125.     }
  126.     fclose(utmp);
  127.     exit(0);
  128. }
  129.  
  130. char *uptime() {
  131.     static char timebuf[128];
  132.     struct proc swapper;
  133.     struct user bootproc;
  134.     long oldpos, now;
  135.     short cnt, ocnt;
  136.     long boottime = 0L;
  137.     
  138.     oldpos = fseek(kfd, 0L, 1);
  139.     fseek(kfd, kernel[3].xl_value, 0);
  140.     fread(&boottime, sizeof boottime, 1, kfd);
  141.     now = boottime / HZ;
  142.  
  143.     if (now < 0L)
  144.         return " with strange clock time";
  145.     timebuf[0] = '\0';
  146.     ocnt = 0;
  147.     cnt = 0;
  148.     while (now >= MONTH) {
  149.         cnt++;
  150.         now -= MONTH;
  151.     }
  152.     if (cnt > 0) {
  153.         strcat(timebuf, itoa(cnt));
  154.         strcat(timebuf, " mon");
  155.         if (cnt > 1)
  156.             strcat(timebuf, "s");
  157.         if (++ocnt == 2)
  158.             return timebuf;
  159.     }
  160.     cnt = 0;
  161.     while (now >= WEEK) {
  162.         cnt++;
  163.         now -= WEEK;
  164.     }
  165.     if (cnt > 0) {
  166.         strcat(timebuf, itoa(cnt));
  167.         strcat(timebuf, " wk");
  168.         if (cnt > 1)
  169.             strcat(timebuf, "s");
  170.         if (++ocnt == 2)
  171.             return timebuf;
  172.     }
  173.     cnt = 0;
  174.     while (now >= DAY) {
  175.         cnt++;
  176.         now -= DAY;
  177.     }
  178.     if (cnt > 0) {
  179.         strcat(timebuf, itoa(cnt));
  180.         strcat(timebuf, " day");
  181.         if (cnt > 1)
  182.             strcat(timebuf, "s");
  183.         if (++ocnt == 2)
  184.             return timebuf;
  185.     }
  186.     cnt = 0;
  187.     while (now >= HOUR) {
  188.         cnt++;
  189.         now -= HOUR;
  190.     }
  191.     if (cnt > 0) {
  192.         strcat(timebuf, itoa(cnt));
  193.         strcat(timebuf, " hr");
  194.         if (cnt > 1)
  195.             strcat(timebuf, "s");
  196.     }
  197.     return timebuf;
  198. }
  199.  
  200. char *itoa(n)
  201. int n; {
  202.     static char buf[20];
  203.     
  204.     sprintf(buf, " %d", n);
  205.     return buf;
  206. }
  207.  
  208. findu (proc, slot, user)
  209. struct    proc    *proc;
  210. int    slot;
  211. struct    user    *user;
  212. {
  213.     struct    proc    *procs = (struct proc *) kernel[1].xl_value;
  214.     long    swapaddr;
  215.     int    i;
  216.  
  217.     if ((proc->p_flag & (SSWAP|SSPART)) || ! (proc->p_flag & SLOAD)) {
  218.         swapaddr = proc->p_addr[0].te_frameno * NBPC;
  219.         if (fseek (sfd, swapaddr, 0) == -1L)
  220.             fprintf (stderr, "error in lseek\n");
  221.         fread (user, sizeof *user, 1, sfd);
  222.     } else {
  223.         if (fseek (mfd, proc->p_addr[0].te_frameno * NBPC, 0) == -1L)
  224.             fprintf (stderr, "error in lseek\n");
  225.         fread (user, sizeof *user, 1, mfd);
  226.     }
  227.     if (user->u_procp - procs == slot)
  228.         return (1);
  229.     else
  230.         return (0);
  231. }
  232.  
  233. show(uinfo)
  234. struct utmp *uinfo;
  235. {
  236.     struct stat sbuf;
  237.     struct proc proc;
  238.     struct user prog;
  239.     char ttydev[16];
  240.     long now, cnt, offset, jcpu;
  241.     short mpid, isswap;
  242.     FILE *ufd;
  243.     
  244.     strcpy(ttydev, "/dev/");
  245.     strncpy(&ttydev[5], uinfo->ut_line, 8);
  246.     ttydev[13] = '\0';
  247.     if (stat(ttydev, &sbuf) != 0) {
  248.         perror(ttydev);
  249.         return;
  250.     }
  251.     time(&now);
  252.     now -= sbuf.st_atime;
  253.     printf("%-8.8s %-8.8s %7s ", uinfo->ut_name, uinfo->ut_line, vtime(&uinfo->ut_time));
  254.     if (now > DAY)
  255.         printf("%4dd", now / DAY);
  256.     else if (now > HOUR)
  257.         printf("%2d:%02d", now / HOUR, (now % HOUR) / 60);
  258.     else if (now > MIN)
  259.         printf("%5d", now / MIN);
  260.     else
  261.         printf("     ");
  262.     putchar(' ');
  263.     mpid = -1;
  264.     jcpu = 0;
  265.     for (cnt = 0; cnt < nproc; cnt++) {
  266.         fseek (kfd, kernel[1].xl_value + (cnt * sizeof proc), 0);
  267.         fread(&proc, sizeof proc, 1, kfd);
  268.         if (proc.p_stat == 0 || proc.p_stat == SZOMB || proc.p_stat == SWAIT)
  269.             continue;
  270.  
  271.         if (findu (&proc, cnt, &prog) == 0)
  272.             continue;
  273.  
  274.         if (prog.u_ttyp == NULL)
  275.             continue;
  276.         if (sbuf.st_rdev != prog.u_ttyd)
  277.             continue;
  278.         jcpu += prog.u_utime + prog.u_stime +
  279.             prog.u_cutime + prog.u_cstime;
  280.         if (proc.p_pid == mypid)
  281.             continue;
  282.         if (proc.p_pid > mpid)
  283.             mpid = proc.p_pid;
  284.     }
  285.     if (mpid == -1)
  286.         printf("[can't stat]");
  287.     else {
  288.         fseek(kfd, kernel[1].xl_value, 0);
  289.         for (cnt = 0; cnt < nproc; cnt++) {
  290.             fread(&proc, sizeof proc, 1, kfd);
  291.             if (proc.p_pid == mpid)
  292.                 break;
  293.         }
  294.         if (proc.p_pid != mpid)
  295.             printf("[interstice]");
  296.         else {
  297.             if (findu (&proc, cnt, &prog) == 0)
  298.                 fprintf (stderr, "can't find parent\n");
  299.  
  300.             printf("%3d:%02d %3d:%02d ",
  301.                 (jcpu / HZ) / MIN, (jcpu / HZ) % MIN,
  302.                 ((prog.u_utime + prog.u_stime) / HZ) / MIN,
  303.                 ((prog.u_utime + prog.u_stime) / HZ) % MIN);
  304.             prog.u_procp = &proc;
  305.             pcmd(&prog);
  306.         }
  307.     }
  308.     putchar('\n');
  309. }
  310.  
  311. char *vtime(when)
  312. long *when; {
  313.     struct tm then, now;
  314.     static char buf[20];
  315.     short hour, min, ampm;
  316.     long clock;
  317.  
  318.     time(&clock);
  319.     now = *localtime(&clock);
  320.     then = *localtime(when);
  321.     if (then.tm_mon != now.tm_mon || then.tm_mday != now.tm_mday) {
  322.         sprintf(buf, "%s %2d", months[then.tm_mon], then.tm_mday);
  323.         return buf;
  324.     }
  325.     min = then.tm_min;
  326.     if (then.tm_hour == 0) {
  327.         ampm = 'a';
  328.         hour = 12;
  329.     }
  330.     else if (then.tm_hour > 0 && then.tm_hour < 12) {
  331.         ampm = 'a';
  332.         hour = then.tm_hour;
  333.     }
  334.     else if (then.tm_hour == 12) {
  335.         ampm = 'p';
  336.         hour = 12;
  337.     }
  338.     else {
  339.         ampm = 'p';
  340.         hour = then.tm_hour - 12;
  341.     }
  342.     sprintf(buf, "%d:%02d%cm", hour, min, ampm);
  343.     return buf;
  344. }
  345.  
  346. pcmd(uinfo)
  347. struct user *uinfo;
  348. {
  349.     /* someday look up the user's command line */
  350.     printf("%-.14s", uinfo->u_comm);
  351. }
  352.