]> mj.ucw.cz Git - ywho.git/commitdiff
Released version 1.10. See ChangeLog for changes.
authorMartin Mares <mj@ucw.cz>
Fri, 5 Jul 2002 23:12:57 +0000 (23:12 +0000)
committerMartin Mares <mj@ucw.cz>
Fri, 5 Jul 2002 23:12:57 +0000 (23:12 +0000)
ChangeLog
Makefile
ywho.c
ywho.lsm

index 50351b524c3f93c8cee9051cb1b69e6138675dfc..a62211e06d3f7abd6e83501f72a827d63fb1f18c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2002-07-06  Martin Mares  <mj@atrey.karlin.mff.cuni.cz>
+
+       * Released as version 1.10.
+
+       * ywho.c (solve): Rewritten the logic for determining commands
+       run by users. Session ID's are no longer honored as they change
+       within a single login session if you use some configurations of
+       GNU screen or OpenSSH with privilege separation. Now we use one
+       of maximum depth leaves in the process tree rooted at the login
+       process mentioned in utmp. Also, cleaned up rest of the solving
+       function, so it's less hairy.
+
+       * ywho.c: Renamed "usr" fields to "uid" and some other cleanups.
+
+       * ywho.c (readproc): Avoid using uninitialized memory if reading
+       of process status fails.
+
+       * ywho.c: Sanitized debugging dumps.
+
+2002-07-05  Martin Mares  <mj@atrey.karlin.mff.cuni.cz>
+
+       * ywho.c (readproc): Record names of swapped-out processes as well.
+
+       * Split the package to ywho and nwho.
+
 2001-02-06  Martin Mares  <mj@atrey.karlin.mff.cuni.cz>
 
        * Released as version 1.9.
index 6d7f9888b129309248405bcaf351949c8ac3d426..155843a3d16bfec513e5057f79b988d3092778cf 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
 CFLAGS=-O2 -Wall -Wno-parentheses
 LDFLAGS=-s
 ROOT=/
-REL=ywho-1.9
+REL=ywho-1.10
 
 all: ywho
 
@@ -13,7 +13,6 @@ ywho.o: ywho.c
 
 clean:
        rm -f *.o ywho *~
-       rm -rf dist
 
 install:
        strip ywho
@@ -21,7 +20,8 @@ install:
        install -s -m 755 ywho $(ROOT)/usr/bin
 
 dist: clean
-       mkdir dist
-       cp -a . dist/$(REL)
-       rm -rf `find dist/$(REL) -name CVS -o -name tmp` dist/$(REL)/dist
-       cd dist ; tar czvvf /tmp/$(REL).tar.gz $(REL)
+       mkdir -p ~/tmp
+       cp -a . ~/tmp/$(REL)
+       rm -rf `find ~/tmp/$(REL) -name CVS -o -name tmp`
+       cd ~/tmp ; tar czvvf $(REL).tar.gz $(REL)
+       rm -rf ~/tmp/$(REL)
diff --git a/ywho.c b/ywho.c
index f734ba1f371419cd7ecd0070aee85caa524c680b..5c23a7f5f4586268daf5467653f552d68bfc1658 100644 (file)
--- a/ywho.c
+++ b/ywho.c
@@ -1,7 +1,7 @@
 /*
- *     Extended `who' command, version 1.9.
+ *     Extended `who' command, version 1.10.
  *
- *     (c) 1996--2001 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *     (c) 1996--2002 Martin Mares <mj@ucw.cz>
  *
  *     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.
 #undef DEBUG
 #define MAXHOSTSIZE 24
 
+#ifdef DEBUG
+#define DBG(x,y...) printf(x,##y)
+#else
+#define DBG(x,y...) do { } while(0)
+#endif
+
 struct procrec {
   struct procrec *next;
   int pid, ppid, pgrp, sess;
-  int usr, state;
+  int uid, state, distance;
   time_t ctim, tim;
+  struct utrec *user;
   char cmd_line[1];
 };
 
@@ -40,7 +47,7 @@ struct utrec {
   char line[UT_LINESIZE];
   time_t login_time, click_time, total_time;
   char user_name[UT_NAMESIZE+1];
-  int usr;
+  int uid;
   char host_name[MAXHOSTSIZE+1];
   int mesg, detach;
   struct procrec *proc;
@@ -84,6 +91,7 @@ readutmp(void)
        struct stat st;
        char device[32];
        size_t hlen;
+       bzero(u, sizeof(*u));
        u->next = first_utrec;
        first_utrec = u;
        u->login_pid = ut->ut_pid;
@@ -101,9 +109,9 @@ readutmp(void)
        strcpy_padded(u->user_name, ut->ut_user, UT_NAMESIZE);
        pw = getpwnam(u->user_name);
        if (pw)
-         u->usr = pw->pw_uid;
+         u->uid = pw->pw_uid;
        else
-         u->usr = -1;
+         u->uid = -1;
        strcpy_padded(u->host_name, ut->ut_host,
          (MAXHOSTSIZE > UT_HOSTSIZE ? UT_HOSTSIZE : MAXHOSTSIZE));
        if ((hlen = strlen(u->host_name)) > maxhost)
@@ -141,10 +149,8 @@ readutmp(void)
          }
        u->detach = 0;
        usercnt++;
-#ifdef DEBUG
-       printf("UT %s %s %d %d\n", u->user_name, u->host_name,
-              u->usr, u->login_pid);
-#endif
+       DBG("UTMP: %s %s %d %d\n", u->user_name, u->host_name,
+           u->uid, u->login_pid);
       }
   endutent();
 }
@@ -365,7 +371,7 @@ readproc(void)
   if (!ioctl(1, TIOCGWINSZ, &win) && win.ws_col >= LEFTSIZE + maxhost + 10 && win.ws_col < 1024)
     cmdcols = win.ws_col;
   else cmdcols = 80;
-    cmdcols -= LEFTSIZE + maxhost;
+  cmdcols -= LEFTSIZE + maxhost;
   if (d = opendir("/proc"))
     {
       while (e = readdir(d))
@@ -377,22 +383,24 @@ readproc(void)
              struct stat st;
              char name[256], eman[1024];
              int fil;
+             bzero(p, sizeof(*p));
              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;
+                 p->uid = st.st_uid;
                  strcpy(eman, name);
                  strcat(eman, "/cmdline");
                  if ((fil = open(eman, O_RDONLY)) >= 0)
                    {
-                     int z = read(fil, p->cmd_line, cmdcols);
+                     int y, z = read(fil, p->cmd_line, cmdcols);
                      if (z < 0)
                        z = 0;
-                     p->cmd_line[z] = 0x91;
+                     for (y=0; y<z; y++)
+                       if (!p->cmd_line[y])
+                         p->cmd_line[y] = ' ';
+                     p->cmd_line[z] = 0;
                      close(fil);
                    }
                  strcpy(eman, name);
@@ -400,14 +408,19 @@ readproc(void)
                  if ((fil = open(eman, O_RDONLY)) >= 0)
                    {
                      int z = read(fil, eman, 1023);
-                     char *k;
+                     char *j, *k;
                      int trash, utim, stim, cutim, cstim;
                      if (z < 0)
                        z = 0;
                      eman[z] = 0;
-                     k = strchr(eman, ')');
-                     if (k)
+                     if ((j = strchr(eman, '(')) && (k = strchr(j+1, ')')))
                        {
+                         *k = 0;
+                         if (!p->cmd_line[0])
+                           {
+                             strncpy(p->cmd_line, j+1, cmdcols);
+                             p->cmd_line[cmdcols] = 0;
+                           }
                          p->state = k[2];
                          if (p->state == 'Z')
                            zombies++;
@@ -415,6 +428,9 @@ readproc(void)
                                 &p->ppid, &p->pgrp, &p->sess, &trash, &trash,
                                 &trash, &trash, &trash, &trash, &trash, &utim,
                                 &stim, &cutim, &cstim);
+                         DBG("PROC: pid=%d ppid=%d pgrp=%d sess=%d uid=%d\n", p->pid, p->ppid, p->pgrp, p->sess, p->uid);
+                         p->next = first_procrec;
+                         first_procrec = p;
                        }
                      p->tim = utim + stim;
                      p->ctim = cutim + cstim;
@@ -435,87 +451,71 @@ readproc(void)
 static void
 solve(void)
 {
-  struct utrec *u = first_utrec;
-  struct procrec *m, *n, *o, *q;
+  struct utrec *u;
+  struct procrec *m, *n;
   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)
-               {
-                 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);
-       }
-#endif
-      u = u->next;
-    }
-  for(u=first_utrec; u; u=u->next)
+  int cnt;
+
+  /* Recognize login session process trees and find leaves of these trees */
+  for (u=first_utrec; u; u=u->next)
     {
-      for(m=first_procrec; m; m=m->next)
-       if (u->usr == m->usr)
+      for (m=first_procrec; m; m=m->next)
+       if (m->pid == u->login_pid)
          {
-           m->usr = -1;
-           u->detach++;
-#ifdef DEBUG
-           printf("** %s %s\n", u->user_name, m->cmd_line);
-#endif
+           m->user = u;
+           u->total_time = m->ctim;
+           u->proc = m;
+           DBG("** %d is login process for %s@%s\n", m->pid, u->user_name, u->line);
          }
     }
+  do
+    {
+      cnt = 0;
+      for (m=first_procrec; m; m=m->next)
+       if (!m->user)
+         for (n=first_procrec; n; n=n->next)
+           if (n->pid == m->ppid && n->user)
+             {
+               u = m->user = n->user;
+               m->distance = n->distance + 1;
+               if (!u->proc || u->proc->distance < m->distance)
+                 u->proc = m;
+               cnt++;
+               DBG("** %d at distance %d for %s@%s\n", m->pid, m->distance, u->user_name, u->line);
+               break;
+             }
+    }
+  while (cnt);
+
+  /* Process the remaining processes */
   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[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->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);
-#endif
-      }
+    {
+      if (m->user)
+       continue;
+      for(u=first_utrec; u; u=u->next)
+       if (u->uid == m->uid)
+         break;
+      if (!u)
+       {
+         if (m->uid < 2 || m->ppid != 1)
+           continue;
+         u = xmalloc(sizeof(struct utrec));
+         bzero(u, sizeof(*u));
+         u->next = first_utrec;
+         first_utrec = u;
+         pw = getpwuid(u->uid = m->uid);
+         if (pw)
+           strcpy(u->user_name, pw->pw_name);
+         else
+           sprintf(u->user_name, "<%d>", m->uid);
+         u->mesg = 3;
+       }
+      if (!u->proc)
+       u->proc = m;
+      u->total_time += m->ctim;
+      u->detach++;
+      DBG("** daemon %s (%s)\n", m->cmd_line, u->user_name);
+    }
 }
 
 static inline int
@@ -595,7 +595,7 @@ show(void)
          putchar(' ');
          puttime((unsigned)u->total_time/(unsigned)HZ);
          putchar(' ');
-         for (c = u->proc->cmd_line; *c != 0x91; c++)
+         for (c = u->proc->cmd_line; *c; c++)
            {
              if (*c < 0x20 || (*c >= 0x7f && *c < 0xa0))
                putchar(' ');
index 9dcccdccb00c36b22042eba71f1ed6b58e87b7ad..bfb95791ee5bf0467b4abfb7990c6299755e7426 100644 (file)
--- a/ywho.lsm
+++ b/ywho.lsm
@@ -1,15 +1,15 @@
 Begin3
 Title:         ywho
-Version:       1.9
-Entered-date:  990328
+Version:       1.10
+Entered-date:  020705
 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
+Keywords:      who
 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/ywho-1.9.tar.gz
+Primary-site:  atrey.karlin.mff.cuni.cz/pub/local/mj/linux/ywho-1.10.tar.gz
 Alternate-site:        metalab.unc.edu/pub/Linux/system/status
 Copying-policy:        GPL
 End