]> mj.ucw.cz Git - ywho.git/commitdiff
Introduced the nwho service.
authorMartin Mares <mj@ucw.cz>
Sat, 27 Sep 1997 11:34:41 +0000 (11:34 +0000)
committerMartin Mares <mj@ucw.cz>
Sat, 27 Sep 1997 11:34:41 +0000 (11:34 +0000)
ChangeLog [new file with mode: 0644]
Makefile
ywho.c
ywho.lsm [new file with mode: 0644]

diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..524abb0
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,15 @@
+Fri Sep 26 23:45:57 1997  Martin Mares  <mj@albireo.mj.gts.cz>
+
+       * Added nwhod, nwho and nuptime. Released as version 1.8.
+
+Ancient history:
+
+ *     1.3 (16-09-96) - idle derived from atime instead of mtime.
+ *                    - displaying of current command fixed.
+ *     1.4 (09-05-97) - "mesg n" state now based on group write
+ *     1.5 (13-07-97) - correctly parses 2.1.X /proc/meminfo
+ *                    - source re-indented
+ *                    - fixed zombie detector
+ *                    - changed rules for kilo/mega/gigabyte printing
+ *     1.6 (29-07-97) - ignores unprintable characters in process cmdlines.
+ *     1.7 (01-09-97) - added missing newline in zombie detector.
index 3d997d0b9731ae7c128e438d141a89a4666f9d65..1cffb0e46cf89b4fe3ee4e74a49f3198c22fe4e9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,28 @@
-# Makefile for YWHO
+# Makefile for the ywho toolkit
 
-ywho: ywho.c
-       gcc -s -N -O2 -m486 -fomit-frame-pointer -Wall -Wno-parentheses ywho.c -o ywho
+CFLAGS=-O2 -m486 -fomit-frame-pointer -Wall -Wno-parentheses -malign-loops=0 -malign-jumps=0 -malign-functions=2
+LDFLAGS=-s
+
+all: ywho nwhod nwho
+
+ywho: ywho.o
+
+ywho.o: ywho.c
+
+nwhod: nwhod.o
+
+nwhod.o: nwhod.c net.h
+
+nwho: nwho.o
+
+nwho.o: nwho.c net.h
 
 clean:
-       rm *.o ywho
+       rm -f *.o ywho nwhod nwho *~
 
 install:
        strip ywho
-       mv ywho /usr/local/bin
+       install -s -m 755 ywho nwho /usr/bin
+       ln -sf nwho /usr/bin/nuptime
+       install -s -m 755 nwhod /usr/sbin
+       install -d -m 755 /var/spool/nwho
diff --git a/ywho.c b/ywho.c
index 568ed64286ab3686ed2977e15d4c6def494aa084..373e61369ec75a81a17661f5be93e09c1aa027f8 100644 (file)
--- a/ywho.c
+++ b/ywho.c
@@ -1,10 +1,10 @@
 /*
- *             Extended `who' command, version 1.3.
+ *     Extended `who' command, version 1.8.
  *
- *             (c) 1996 Martin Mares <mj@k332.feld.cvut.cz>
+ *     (c) 1996, 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
  *
- *             1.3 (16-96-96) - idle derived from atime instead of mtime.
- *                                                     - displaying of current command fixed.
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU General Public License. See file COPYING in any of the GNU packages.
  */
 
 #include <stdio.h>
 #undef DEBUG
 
 struct procrec {
-       struct procrec *next;
-       int pid, ppid, pgrp, sess;
-       int usr, state;
-       time_t ctim, tim;
-       char cmd_line[34];
-       };
+  struct procrec *next;
+  int pid, ppid, pgrp, sess;
+  int usr, state;
+  time_t ctim, tim;
+  char cmd_line[34];
+};
 
 static struct procrec *first_procrec;
 
 struct utrec {
-       struct utrec *next;
-       pid_t login_pid;
-       char line_id[4];
-       time_t login_time, click_time, total_time;
-       char user_name[UT_NAMESIZE+1];
-       int usr;
-       char host_name[17];
-       char line_name[12];
-       int mesg, detach;
-       struct procrec *proc;
-       };
+  struct utrec *next;
+  pid_t login_pid;
+  char line_id[4];
+  time_t login_time, click_time, total_time;
+  char user_name[UT_NAMESIZE+1];
+  int usr;
+  char host_name[17];
+  char line_name[12];
+  int mesg, detach;
+  struct procrec *proc;
+};
 
 static struct utrec *first_utrec;
 static int usercnt, zombies;
@@ -51,530 +51,540 @@ static time_t now;
 static void *
 xmalloc(int i)
 {
-void *z;
-       z = malloc(i);
-       if (!z)
-               {
-               fprintf(stderr, "xwho: out of memory!\n");
-               exit(1);
-               }
-       return z;
+  void *z;
+  z = malloc(i);
+  if (!z)
+    {
+      fprintf(stderr, "ywho: out of memory!\n");
+      exit(1);
+    }
+  return z;
 }
 
 static void
 strcpy_padded(char *to, char *from, int size)
 {
-       memcpy(to, from, size);
-       to[size] = 0;
+  memcpy(to, from, size);
+  to[size] = 0;
 }
 
 static void
 readutmp(void)
 {
-static struct utmp *ut;
-static struct passwd *pw;
-       utmpname(UTMP_FILE);
-       while (ut = getutent())
-               if (ut->ut_type == USER_PROCESS && ut->ut_user[0])
-                       {
-                       struct utrec *u = xmalloc(sizeof(struct utrec));
-                       struct stat st;
-                       char device[32];
-                               u->next = first_utrec;
-                               first_utrec = u;
-                               u->login_pid = ut->ut_pid;
-                               u->line_id[0] = ut->ut_id[0];
-                               u->line_id[1] = ut->ut_id[1];
-                               u->line_id[2] = 0;
-                               u->login_time = ut->ut_time;
-                               strcpy_padded(u->user_name, ut->ut_user, UT_NAMESIZE);
-                               pw = getpwnam(u->user_name);
-                               if (pw)
-                                       u->usr = pw->pw_uid;
-                               else
-                                       u->usr = -1;
-                               strcpy_padded(u->host_name, ut->ut_host, 16);
-                               strcpy(u->line_name, ut->ut_line);
-                               if (!u->line_id[0])
-                                       {
-                                       char *z = u->line_name;
-                                       if (!strncmp(u->line_name, "tty", 3))
-                                               z += 3;
-                                       strncpy(u->line_id, z, 3);
-                                       u->line_id[3] = 0;
-                                       }
-                               strcpy(device, "/dev/");
-                               strcat(device, u->line_name);
-                               if (stat(device, &st))
-                                       u->mesg = 2;
-                               else
-                                       {
-                                       u->mesg = !!(S_IWOTH & st.st_mode);
-                                       u->click_time = st.st_atime;
-                                       if (u->click_time < st.st_atime)
-                                               u->click_time = st.st_atime;
-                                       if (u->click_time < st.st_ctime)
-                                               u->click_time = st.st_ctime;
-                                       }
-                               u->detach = 0;
-                               usercnt++;
+  static struct utmp *ut;
+  static struct passwd *pw;
+  utmpname(UTMP_FILE);
+  while (ut = getutent())
+    if (ut->ut_type == USER_PROCESS && ut->ut_user[0])
+      {
+       struct utrec *u = xmalloc(sizeof(struct utrec));
+       struct stat st;
+       char device[32];
+       u->next = first_utrec;
+       first_utrec = u;
+       u->login_pid = ut->ut_pid;
+       u->line_id[0] = ut->ut_id[0];
+       u->line_id[1] = ut->ut_id[1];
+       u->line_id[2] = 0;
+       u->login_time = ut->ut_time;
+       strcpy_padded(u->user_name, ut->ut_user, UT_NAMESIZE);
+       pw = getpwnam(u->user_name);
+       if (pw)
+         u->usr = pw->pw_uid;
+       else
+         u->usr = -1;
+       strcpy_padded(u->host_name, ut->ut_host, 16);
+       strcpy(u->line_name, ut->ut_line);
+       if (!u->line_id[0])
+         {
+           char *z = u->line_name;
+           if (!strncmp(u->line_name, "tty", 3))
+             z += 3;
+           strncpy(u->line_id, z, 3);
+           u->line_id[3] = 0;
+         }
+       strcpy(device, "/dev/");
+       strcat(device, u->line_name);
+       if (stat(device, &st))
+         u->mesg = 2;
+       else
+         {
+           u->mesg = !!(S_IWGRP & st.st_mode);
+           u->click_time = st.st_atime;
+           if (u->click_time < st.st_atime)
+             u->click_time = st.st_atime;
+           if (u->click_time < st.st_ctime)
+             u->click_time = st.st_ctime;
+         }
+       u->detach = 0;
+       usercnt++;
 #ifdef DEBUG
-                               printf("UT %s %s %d %d\n", u->user_name, u->host_name,
-                                       u->usr, u->login_pid);
+       printf("UT %s %s %d %d\n", u->user_name, u->host_name,
+              u->usr, u->login_pid);
 #endif
-                       }
-       endutent();
+      }
+  endutent();
 }
 
 static void
 puttime(int s)
 {
-int d, h, m;
-       if (s < 100)
-               printf("%4ds", s);
-       else
-               {
-               m = s/60;
-               s %= 60;
-               h = m/60;
-               m %= 60;
-               if (h < 100)
-                       printf("%02d.%02d", h, m);
-               else
-                       {
-                       d = h/24;
-                       h %= 24;
-                       if (d < 100)
-                               printf("%2dd%02d", d, h);
-                       else
-                               printf("%4dd", d);
-                       }
-               }
+  int d, h, m;
+  if (s < 100)
+    printf("%4ds", s);
+  else
+    {
+      m = s/60;
+      s %= 60;
+      h = m/60;
+      m %= 60;
+      if (h < 100)
+       printf("%02d.%02d", h, m);
+      else
+       {
+         d = h/24;
+         h %= 24;
+         if (d < 100)
+           printf("%2dd%02d", d, h);
+         else
+           printf("%4dd", d);
+       }
+    }
 }
 
 static void
 memory(unsigned int i)
 {
-       if (i < 1000)
-               printf("%dB", i);
-       else
-               {
-               i = (i+511)/1024;
-               if (i < 1000)
-                       printf("%dK", i);
-               else
-                       {
-                       i = (i+511)/1024;
-                       if (i < 1000)
-                               printf("%dM", i);
-                       else
-                               printf("%dG", (i+511U)/1024U);
-                       }
-               }
+  if (i < 10240)
+    printf("%dB", i);
+  else
+    {
+      i = (i+511U)/1024U;
+      if (i < 2048)
+       printf("%dK", i);
+      else
+       {
+         i = (i+511)/1024;
+         if (i < 2048)
+           printf("%dM", i);
+         else
+           printf("%dG", (i+511U)/1024U);
+       }
+    }
 }
 
 static void
 dispsys(void)
 {
-FILE *f;
-char line[256], a[32], b[32], c[32];
-char *z, *w;
-       w = NULL;
-       if (f = fopen("/proc/version", "r"))
-               {
-               fgets(line, 256, f);
-               z = strchr(line, '(');
-               if (z)
-                       {
-                       while (z != line && z[-1] == ' ')
-                               z--;
-                       }
-               else
-                       z = line + strlen(line) - 1;
-               *z = 0;
-               z = strstr(line, " version");
-               if (z)
-                       memmove(z, z+8, strlen(z+8)+1);
-               printf(line);
-               fclose(f);
-               }
-       if (f = fopen("/proc/cpuinfo", "r"))
-               {
-               strcpy(a, "???");
-               b[0] = 0;
-               c[0] = 0;
-               for(;;)
-                       {
-                       fgets(line, 256, f);
-                       if (feof(f))
-                               break;
-                       if (!strncmp(line, "cpu\t\t: ", 7))
-                               {
-                               z = line+7;
-                               w = a;
-                               }
-                       else if (!strncmp(line, "model\t\t: ", 9))
-                               {
-                               z = line+9;
-                               w = b;
-                               }
-                       else if (!strncmp(line, "mask\t\t: ", 8))
-                               {
-                               z = line+8;
-                               w = c;
-                               }
-                       else
-                               z = NULL;
-                       if (z)
-                               {
-                               line[strlen(line)-1] = 0;
-                               strcpy(w, z);
-                               if (!strcmp(w, "Unknown"))
-                                       w[0] = 0;
-                               }
-                       }
-               printf(" on %s", a);
-               if (*b)
-                       printf("-%s", b);
-               if (*c)
-                       printf("-%s", c);
-               fclose(f);
-               }
-       if (f = fopen("/proc/uptime", "r"))
-               {
-               int p,q,p1,q1;
-               fgets(line, 256, f);
-               sscanf(line, "%d.%d%d.%d", &p, &p1, &q, &q1);
-               printf(", up ");
-               puttime(p);
-               printf(", run ");
-               puttime(p-q);
-               fclose(f);
-               }
+  FILE *f;
+  char line[256], a[32], b[32], c[32];
+  char *z, *w;
+  w = NULL;
+  if (f = fopen("/proc/version", "r"))
+    {
+      fgets(line, 256, f);
+      z = strchr(line, '(');
+      if (z)
        {
-       struct tm *tm;
-               now = time(NULL);
-               tm = localtime(&now);
-               printf(" at %02d-%02d-%02d/%d %02d.%02d:%02d\n", tm->tm_mday, tm->tm_mon+1,
-                       tm->tm_year, (tm->tm_wday+6)%7, tm->tm_hour, tm->tm_min, tm->tm_sec);
+         while (z != line && z[-1] == ' ')
+           z--;
        }
-       if (f = fopen("/proc/loadavg", "r"))
-               {
-               int i = 3;
-               fgets(line, 256, f);
-               *strchr(line, '\n') = 0;
-               z = line-1;
-               while (i-- && z)
-                       {
-                       *z = '/';
-                       z = strchr(z, ' ');
-                       }
-               if (z)
-                       {
-                       char *k;
-                       *z++ = 0;
-                       k = strchr(z, ' ');
-                       if (k)
-                         *k = 0;
-                       printf("R/T=%s, ", z);
-                       }
-               else
-                       z = line;
-               printf("LAV=%s", line);
-               fclose(f);
-               }
-       if (f = fopen("/proc/meminfo", "r"))
-               {
-               int total, used, free, shared, buffers, totals, useds, frees;
-               fgets(line, 256, f);
-               fgets(line, 256, f);
-               sscanf(line, "Mem:%d%d%d%d%d", &total, &used, &free, &shared, &buffers);
-               fgets(line, 256, f);
-               sscanf(line, "Swap:%d%d%d", &totals, &useds, &frees);
-               printf(", free ");
-               memory(free+buffers);
-               printf(" of RAM");
-               if (useds)
-                       {
-                       printf(", used ");
-                       memory(useds);
-                       printf(" of swap");
-                       }
-               }
-       printf(", %d user%s.\n", usercnt, usercnt == 1 ? "" : "s");
+      else
+       z = line + strlen(line) - 1;
+      *z = 0;
+      z = strstr(line, " version");
+      if (z)
+       memmove(z, z+8, strlen(z+8)+1);
+      printf(line);
+      fclose(f);
+    }
+  if (f = fopen("/proc/cpuinfo", "r"))
+    {
+      strcpy(a, "???");
+      b[0] = 0;
+      c[0] = 0;
+      for(;;)
+       {
+         fgets(line, 256, f);
+         if (feof(f))
+           break;
+         if (!strncmp(line, "cpu\t\t: ", 7))
+           {
+             z = line+7;
+             w = a;
+           }
+         else if (!strncmp(line, "model\t\t: ", 9))
+           {
+             z = line+9;
+             w = b;
+           }
+         else if (!strncmp(line, "mask\t\t: ", 8))
+           {
+             z = line+8;
+             w = c;
+           }
+         else
+           z = NULL;
+         if (z)
+           {
+             line[strlen(line)-1] = 0;
+             strcpy(w, z);
+             if (!strcmp(w, "Unknown"))
+               w[0] = 0;
+           }
+       }
+      printf(" on %s", a);
+      if (*b)
+       printf("-%s", b);
+      if (*c)
+       printf("-%s", c);
+      fclose(f);
+    }
+  if (f = fopen("/proc/uptime", "r"))
+    {
+      int p,q,p1,q1;
+      fgets(line, 256, f);
+      sscanf(line, "%d.%d%d.%d", &p, &p1, &q, &q1);
+      printf(", up ");
+      puttime(p);
+      printf(", run ");
+      puttime(p-q);
+      fclose(f);
+    }
+  {
+    struct tm *tm;
+    now = time(NULL);
+    tm = localtime(&now);
+    printf(" at %02d-%02d-%02d/%d %02d.%02d:%02d\n", tm->tm_mday, tm->tm_mon+1,
+          tm->tm_year, (tm->tm_wday+6)%7, tm->tm_hour, tm->tm_min, tm->tm_sec);
+  }
+  if (f = fopen("/proc/loadavg", "r"))
+    {
+      int i = 3;
+      fgets(line, 256, f);
+      *strchr(line, '\n') = 0;
+      z = line-1;
+      while (i-- && z)
+       {
+         *z = '/';
+         z = strchr(z, ' ');
+       }
+      if (z)
+       {
+         char *k;
+         *z++ = 0;
+         k = strchr(z, ' ');
+         if (k)
+           *k = 0;
+         printf("R/T=%s, ", z);
+       }
+      else
+       z = line;
+      printf("LAV=%s", line);
+      fclose(f);
+    }
+  if (f = fopen("/proc/meminfo", "r"))
+    {
+      int free, buffers, stotal, sfree;
+      free = buffers = stotal = sfree = 0;
+      while (fgets(line, 256, f))
+       {
+         if (!strncmp(line, "MemFree:", 8))
+           sscanf(line+8, "%d", &free);
+         else if (!strncmp(line, "Buffers:", 8))
+           sscanf(line+8, "%d", &buffers);
+         else if (!strncmp(line, "SwapTotal:", 10))
+           sscanf(line+10, "%d", &stotal);
+         else if (!strncmp(line, "SwapFree:", 9))
+           sscanf(line+9, "%d", &sfree);
+       }
+      printf(", free ");
+      memory(1024*(free+buffers));
+      printf(" of RAM");
+      if (stotal != sfree)
+       {
+         printf(", used ");
+         memory(1024*(stotal - sfree));
+         printf(" of swap");
+       }
+    }
+  printf(", %d user%s.\n", usercnt, usercnt == 1 ? "" : "s");
 }
 
 static void
 readproc(void)
 {
-DIR *d;
-struct dirent *e;
-       if (d = opendir("/proc"))
+  DIR *d;
+  struct dirent *e;
+  if (d = opendir("/proc"))
+    {
+      while (e = readdir(d))
+       {
+         int i;
+         sscanf(e->d_name, "%d", &i);
+         if (i)
+           {
+             struct procrec *p = xmalloc(sizeof(struct procrec));
+             struct stat st;
+             char name[256], eman[1024];
+             int fil;
+             p->pid = i;
+             strcpy(name, "/proc/");
+             strcat(name, e->d_name);
+             if (!stat(name, &st))
                {
-               while (e = readdir(d))
+                 p->next = first_procrec;
+                 first_procrec = p;
+                 p->usr = st.st_uid;
+                 strcpy(eman, name);
+                 strcat(eman, "/cmdline");
+                 if ((fil = open(eman, O_RDONLY)) >= 0)
+                   {
+                     int z = read(fil, p->cmd_line, sizeof(p->cmd_line) - 1);
+                     if (z < 0)
+                       z = 0;
+                     p->cmd_line[z] = 0x91;
+                     close(fil);
+                   }
+                 strcpy(eman, name);
+                 strcat(eman, "/stat");
+                 if ((fil = open(eman, O_RDONLY)) >= 0)
+                   {
+                     int z = read(fil, eman, 1023);
+                     char *k;
+                     int trash, utim, stim, cutim, cstim;
+                     if (z < 0)
+                       z = 0;
+                     eman[z] = 0;
+                     k = strchr(eman, ')');
+                     if (k)
                        {
-                       int i;
-                               sscanf(e->d_name, "%d", &i);
-                               if (i)
-                                       {
-                                       struct procrec *p = xmalloc(sizeof(struct procrec));
-                                       struct stat st;
-                                       char name[256], eman[1024];
-                                       int fil;
-                                               p->pid = i;
-                                               strcpy(name, "/proc/");
-                                               strcat(name, e->d_name);
-                                               if (!stat(name, &st))
-                                                       {
-                                                       p->next = first_procrec;
-                                                       first_procrec = p;
-                                                       p->usr = st.st_uid;
-                                                       strcpy(eman, name);
-                                                       strcat(eman, "/cmdline");
-                                                       if ((fil = open(eman, O_RDONLY)) >= 0)
-                                                               {
-                                                               int z = read(fil, p->cmd_line, 33);
-                                                               if (z < 0)
-                                                                       z = 0;
-                                                               p->cmd_line[z] = 0xff;
-                                                               close(fil);
-                                                               }
-                                                       strcpy(eman, name);
-                                                       strcat(eman, "/stat");
-                                                       if ((fil = open(eman, O_RDONLY)) >= 0)
-                                                               {
-                                                               int z = read(fil, eman, 1023);
-                                                               char *k;
-                                                               int trash, utim, stim, cutim, cstim;
-                                                                       if (z < 0)
-                                                                               z = 0;
-                                                                       eman[z] = 0;
-                                                                       k = strchr(eman, ')');
-                                                                       if (k)
-                                                                               {
-                                                                               p->state = k[1];
-                                                                               if (p->state == 'Z')
-                                                                                       zombies++;
-                                                                               sscanf(k+3, "%d%d%d%d%d%d%d%d%d%d%d%d%d%d",
-                                                                                       &p->ppid, &p->pgrp, &p->sess, &trash, &trash,
-                                                                                       &trash, &trash, &trash, &trash, &trash, &utim,
-                                                                                       &stim, &cutim, &cstim);
-                                                                               }
-                                                                       p->tim = utim + stim;
-                                                                       p->ctim = cutim + cstim;
-                                                                       close(fil);
-                                                               }
-                                                       }
-                                       }
+                         p->state = k[2];
+                         if (p->state == 'Z')
+                           zombies++;
+                         sscanf(k+4, "%d%d%d%d%d%d%d%d%d%d%d%d%d%d",
+                                &p->ppid, &p->pgrp, &p->sess, &trash, &trash,
+                                &trash, &trash, &trash, &trash, &trash, &utim,
+                                &stim, &cutim, &cstim);
                        }
-               closedir(d);
-               }
-       else
-               {
-               perror("unable to scan /proc");
-               exit(1);
+                     p->tim = utim + stim;
+                     p->ctim = cutim + cstim;
+                     close(fil);
+                   }
                }
+           }
+       }
+      closedir(d);
+    }
+  else
+    {
+      perror("unable to scan /proc");
+      exit(1);
+    }
 }
 
 static void
 solve(void)
 {
-struct utrec *u = first_utrec;
-struct procrec *m, *n, *o, *q;
-struct passwd *pw;
-       while (u)
+  struct utrec *u = first_utrec;
+  struct procrec *m, *n, *o, *q;
+  struct passwd *pw;
+  while (u)
+    {
+      m = first_procrec;
+      while (m && m->pid != u->login_pid)
+       m = m->next;
+      o = m;
+      if (m)
+       {
+       retry:
+         n = first_procrec;
+         q = o;
+         while (n)
+           {
+             if (q->sess == n->sess)
+               n->usr = -1;
+             if (q->pid == n->ppid && n->usr == -1)
                {
-               m = first_procrec;
-               while (m && m->pid != u->login_pid)
-                       m = m->next;
-               o = m;
-               if (m)
-                       {
-               retry:
-                       n = first_procrec;
-                       q = o;
-                       while (n)
-                               {
-                               if (q->sess == n->sess)
-                                       n->usr = -1;
-                               if (q->pid == n->ppid && n->usr == -1)
-                                       {
-                                       o = n;
-                                       goto retry;
-                                       }
-                               n = n->next;
-                               }
-                       }
-               u->proc = o;
-               if (m)
-                       u->total_time = m->ctim;
+                 o = n;
+                 goto retry;
+               }
+             n = n->next;
+           }
+       }
+      u->proc = o;
+      if (m)
+       u->total_time = m->ctim;
 #ifdef DEBUG
-               if (o)
-                       {
-                       printf("%s %s\n", u->user_name, o->cmd_line);
-                       }
+      if (o)
+       {
+         printf("%s %s\n", u->user_name, o->cmd_line);
+       }
 #endif
-               u = u->next;
-               }
-       for(u=first_utrec; u; u=u->next)
-               {
-               for(m=first_procrec; m; m=m->next)
-                       if (u->usr == m->usr)
-                               {
-                               m->usr = -1;
-                               u->detach++;
+      u = u->next;
+    }
+  for(u=first_utrec; u; u=u->next)
+    {
+      for(m=first_procrec; m; m=m->next)
+       if (u->usr == m->usr)
+         {
+           m->usr = -1;
+           u->detach++;
 #ifdef DEBUG
-                               printf("** %s %s\n", u->user_name, m->cmd_line);
+           printf("** %s %s\n", u->user_name, m->cmd_line);
 #endif
-                               }
-               }
-       for(m=first_procrec; m; m=m->next)
-               if (m->usr >= 2 && m->ppid == 1) /* Exclude no_user,root,bin */
-                       {
-                       for(u=first_utrec; u; u=u->next)
-                               if (u->usr == m->usr)
-                                       break;
-                       if (!u)
-                               {
-                               u = xmalloc(sizeof(struct utrec));
-                               u->next = first_utrec;
-                               first_utrec = u;
-                               u->login_pid = 0;
-                               u->line_id[0] = 0;
-                               pw = getpwuid(u->usr = m->usr);
-                               if (pw)
-                                       strcpy(u->user_name, pw->pw_name);
-                               else
-                                       sprintf(u->user_name, "<%d>", m->usr);
-                               u->host_name[0] = 0;
-                               u->line_name[0] = 0;
-                               u->mesg = 3;
-                               u->detach = 0;
-                               u->proc = NULL;
-                               u->total_time = 0;
-                               }
-                       if (!u->proc)
-                               u->proc = m;
-                       u->total_time += m->ctim;
-                       u->detach ++;
+         }
+    }
+  for(m=first_procrec; m; m=m->next)
+    if (m->usr >= 2 && m->ppid == 1) /* Exclude no_user,root,bin */
+      {
+       for(u=first_utrec; u; u=u->next)
+         if (u->usr == m->usr)
+           break;
+       if (!u)
+         {
+           u = xmalloc(sizeof(struct utrec));
+           u->next = first_utrec;
+           first_utrec = u;
+           u->login_pid = 0;
+           u->line_id[0] = 0;
+           pw = getpwuid(u->usr = m->usr);
+           if (pw)
+             strcpy(u->user_name, pw->pw_name);
+           else
+             sprintf(u->user_name, "<%d>", m->usr);
+           u->host_name[0] = 0;
+           u->line_name[0] = 0;
+           u->mesg = 3;
+           u->detach = 0;
+           u->proc = NULL;
+           u->total_time = 0;
+         }
+       if (!u->proc)
+         u->proc = m;
+       u->total_time += m->ctim;
+       u->detach ++;
 #ifdef DEBUG
-                       printf("// %s %s\n", u->user_name, m->cmd_line);
+       printf("// %s %s\n", u->user_name, m->cmd_line);
 #endif
-                       }
+      }
 }
 
 static inline int
 comp(struct utrec *a, struct utrec *b)
 {
-int k;
-       if (b->mesg == 3)
-               return -1;
-       k = strcmp(a->user_name, b->user_name);
-       if (k)
-               return k;
-       if (!a->host_name[0] && b->host_name[0])
-               return -1;
-       return strcmp(a->line_id, b->line_id);
+  int k;
+  if (b->mesg == 3)
+    return -1;
+  k = strcmp(a->user_name, b->user_name);
+  if (k)
+    return k;
+  if (!a->host_name[0] && b->host_name[0])
+    return -1;
+  return strcmp(a->line_id, b->line_id);
 }
 
 static void
 sort(void)
 {
-struct utrec *fi = NULL;
-struct utrec *z, **y, **m, **l;
-       l = &fi;
-       while (first_utrec)
-               {
-               y = &first_utrec;
-               m = y;
-               while (z = *y)
-                       {
-                       if (comp(z, *m) < 0)
-                               m = y;
-                       y = &z->next;
-                       }
-               z = *m;
-               *m = z->next;
-               *l = z;
-               z->next = NULL;
-               l = &z->next;
-               }
-       first_utrec = fi;
+  struct utrec *fi = NULL;
+  struct utrec *z, **y, **m, **l;
+  l = &fi;
+  while (first_utrec)
+    {
+      y = &first_utrec;
+      m = y;
+      while (z = *y)
+       {
+         if (comp(z, *m) < 0)
+           m = y;
+         y = &z->next;
+       }
+      z = *m;
+      *m = z->next;
+      *l = z;
+      z->next = NULL;
+      l = &z->next;
+    }
+  first_utrec = fi;
 }
 
 static void
 show(void)
 {
-struct utrec *u;
-int i;
-unsigned char *c;
-       printf("Name     Li  MD From              LogT  IdleT RunT  Command\n");
-       for(u=first_utrec; u; u=u->next)
-               {
-               if (!u->line_id[1])
-                       {
-                       if (u->line_id[0])
-                               {
-                               u->line_id[1] = u->line_id[0];
-                               u->line_id[0] = 'c';
-                               }
-                       else    
-                               u->line_id[0] = u->line_id[1] = '-';
-                       }
-               printf("%-8.8s %-3s %c%c %-17.17s ",
-                       u->user_name,
-                       u->line_id,
-                       u->mesg ? ' ' : '-',
-                       u->detach ? 'D' : ' ',
-                       u->host_name);
-               if (u->mesg <= 1)
-                       {
-                       if (u->login_time > now)
-                               u->login_time = now;
-                       puttime(now - u->login_time);
-                       putchar(' ');
-                       if (u->click_time > now)
-                               u->click_time = now;
-                       if (now - u->click_time >= 60)
-                               puttime(now - u->click_time);
-                       else
-                               printf("     ");
-                       }
-               else
-                       printf("?????      ");
-               if (u->proc)
-                       {
-                       putchar(' ');
-                       puttime((unsigned)u->total_time/(unsigned)HZ);
-                       putchar(' ');
-                       i = 24;
-                       c = u->proc->cmd_line;
-                       while (*c != 0xff && i--)
-                               {
-                               putchar(*c ? *c : ' ');
-                               c++;
-                               }
-                       }
-               else
-                       printf(" <nothing>");
-               putchar('\n');
-               }
+  struct utrec *u;
+  int i;
+  unsigned char *c;
+  printf("Name     Li  MD From              LogT  IdleT RunT  Command\n");
+  for(u=first_utrec; u; u=u->next)
+    {
+      if (!u->line_id[1])
+       {
+         if (u->line_id[0])
+           {
+             u->line_id[1] = u->line_id[0];
+             u->line_id[0] = 'c';
+           }
+         else  
+           u->line_id[0] = u->line_id[1] = '-';
+       }
+      printf("%-8.8s %-3s %c%c %-17.17s ",
+            u->user_name,
+            u->line_id,
+            u->mesg ? ' ' : '-',
+            u->detach ? 'D' : ' ',
+            u->host_name);
+      if (u->mesg <= 1)
+       {
+         if (u->login_time > now)
+           u->login_time = now;
+         puttime(now - u->login_time);
+         putchar(' ');
+         if (u->click_time > now)
+           u->click_time = now;
+         if (now - u->click_time >= 60)
+           puttime(now - u->click_time);
+         else
+           printf("     ");
+       }
+      else
+       printf("?????      ");
+      if (u->proc)
+       {
+         putchar(' ');
+         puttime((unsigned)u->total_time/(unsigned)HZ);
+         putchar(' ');
+         i = 24;
+         c = u->proc->cmd_line;
+         while (*c != 0x91 && i--)
+           {
+             if (*c < 0x20 || (*c >= 0x7f && *c < 0xa0))
+               putchar(' ');
+             else
+               putchar(*c);
+             c++;
+           }
+       }
+      else
+       printf(" <nothing>");
+      putchar('\n');
+    }
 }
 
 int main(void)
 {
-       readutmp();
-       dispsys();
-       readproc();
-       solve();
-       sort();
-       show();
-       if (zombies)
-               {
-               printf("There %s %d zombie%s walking around.",
-                       zombies == 1 ? "is" : "are",
-                       zombies,
-                       zombies == 1 ? "" : "s" );
-               }
-       return 0;
+  readutmp();
+  dispsys();
+  readproc();
+  solve();
+  sort();
+  show();
+  if (zombies)
+    {
+      printf("!!! There %s %d zombie%s walking around.\n",
+            zombies == 1 ? "is" : "are",
+            zombies,
+            zombies == 1 ? "" : "s" );
+    }
+  return 0;
 }
diff --git a/ywho.lsm b/ywho.lsm
new file mode 100644 (file)
index 0000000..75ae290
--- /dev/null
+++ b/ywho.lsm
@@ -0,0 +1,16 @@
+Begin3
+Title:         ywho
+Version:       1.8
+Entered-date:  27SEP97
+Description:   A who-type utility displaying not only who is logged in, but
+               also general system information and commands run by the users.
+               Includes a rwhod replacement with central server, allowing
+               user information to be gathered across routers.
+Keywords:      who, rwho
+Author:                Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+Maintained-by: Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+Primary-site:  atrey.karlin.mff.cuni.cz pub/local/mj/linux
+               10 kB ywho-1.8.tar.gz
+Alternate-site:        sunsite.unc.edu /pub/Linux/system/?????
+Copying-policy:        GNU
+End