[libgtop] openbsd: merge patches from ports tree



commit 4cd3e4fed692dae5b1f238ac11ca03bf044e350e
Author: Antoine Jacoutot <ajacoutot gnome org>
Date:   Mon Feb 3 10:56:02 2014 +0100

    openbsd: merge patches from ports tree
    
    Bring OpenBSD closer to FreeBSD to help checking what is missing/different.
    Also we make sure to use and build mountlist and fsusage from the
    sysdeps/openbsd directory instead of the common one.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=723521

 libgtop-sysdeps.m4               |    2 +
 sysdeps/openbsd/Makefile.am      |   23 +++--
 sysdeps/openbsd/cpu.c            |    4 +-
 sysdeps/openbsd/fsusage.c        |   80 ++++++++++---------
 sysdeps/openbsd/glibtop_server.h |   10 +-
 sysdeps/openbsd/loadavg.c        |    4 +-
 sysdeps/openbsd/mem.c            |   15 +---
 sysdeps/openbsd/mountlist.c      |  168 ++++++++++++++++++++++++++++++++++++++
 sysdeps/openbsd/nosuid.c         |    8 --
 sysdeps/openbsd/open.c           |   64 +--------------
 sysdeps/openbsd/procaffinity.c   |    2 +-
 sysdeps/openbsd/prockernel.c     |   38 ++++++--
 sysdeps/openbsd/procmap.c        |   18 +++-
 sysdeps/openbsd/proctime.c       |   53 ------------
 sysdeps/openbsd/procwd.c         |   52 ------------
 sysdeps/openbsd/suid_open.c      |   92 +++++++++++++++++++++
 sysdeps/openbsd/uptime.c         |    6 +-
 17 files changed, 378 insertions(+), 261 deletions(-)
---
diff --git a/libgtop-sysdeps.m4 b/libgtop-sysdeps.m4
index fad6af9..5d84430 100644
--- a/libgtop-sysdeps.m4
+++ b/libgtop-sysdeps.m4
@@ -79,6 +79,8 @@ AC_DEFUN([GNOME_LIBGTOP_SYSDEPS],[
          libgtop_sysdeps_dir=openbsd
          libgtop_use_machine_h=yes
          libgtop_need_server=yes
+         libgtop_sysdeps_private_mountlist=yes
+         libgtop_sysdeps_private_fsusage=yes
          libgtop_postinstall='chgrp kmem $(bindir)/libgtop_server2 && chmod 2555 $(bindir)/libgtop_server2'
          ;;
        freebsd*|kfreebsd*)
diff --git a/sysdeps/openbsd/Makefile.am b/sysdeps/openbsd/Makefile.am
index cfa84f4..0c9f527 100644
--- a/sysdeps/openbsd/Makefile.am
+++ b/sysdeps/openbsd/Makefile.am
@@ -2,18 +2,23 @@ INCLUDES                      = @INCLUDES@
 
 noinst_LTLIBRARIES             = libgtop_sysdeps-2.0.la libgtop_sysdeps_suid-2.0.la
 
-libgtop_sysdeps_2_0_la_SOURCES = nosuid.c siglist.c sysinfo.c
+libgtop_sysdeps_2_0_la_SOURCES = nosuid.c siglist.c sysinfo.c \
+                                 cpu.c loadavg.c \
+                                 uptime.c netlist.c fsusage.c mem.c \
+                                 mountlist.c procopenfiles.c procwd.c \
+                                 procaffinity.c glibtop_private.c open.c
 
 libgtop_sysdeps_2_0_la_LDFLAGS = $(LT_VERSION_INFO)
 
-libgtop_sysdeps_suid_2_0_la_LIBADD     = $(KVM_LIBS)
-libgtop_sysdeps_suid_2_0_la_SOURCES    = open.c close.c cpu.c mem.c swap.c \
-                                 uptime.c loadavg.c shm_limits.c msg_limits.c \
-                                 sem_limits.c proclist.c procstate.c procuid.c \
-                                 proctime.c procmem.c procsignal.c prockernel.c \
-                                 procsegment.c procargs.c procmap.c netlist.c \
-                                 netload.c ppp.c procopenfiles.c fsusage.c \
-                                 procwd.c procaffinity.c glibtop_private.c
+libgtop_sysdeps_suid_2_0_la_LIBADD     = $(KVM_LIBS) $(EXTRA_SYSDEPS_LIBS)
+libgtop_sysdeps_suid_2_0_la_SOURCES    =  suid_open.c close.c swap.c \
+                                 proclist.c procstate.c procuid.c \
+                                 proctime.c procmem.c procsignal.c \
+                                 prockernel.c procsegment.c procargs.c \
+                                 procmap.c netload.c ppp.c
+
+# TODO should be made nosuid like FreeBSD
+libgtop_sysdeps_suid_2_0_la_SOURCES += shm_limits.c msg_limits.c sem_limits.c
 
 libgtop_sysdeps_suid_2_0_la_LDFLAGS    = $(LT_VERSION_INFO)
 
diff --git a/sysdeps/openbsd/cpu.c b/sysdeps/openbsd/cpu.c
index 533e04b..5560a3b 100644
--- a/sysdeps/openbsd/cpu.c
+++ b/sysdeps/openbsd/cpu.c
@@ -42,7 +42,7 @@ static int mib2 [] = { CTL_KERN, KERN_CPTIME };
 /* Init function. */
 
 void
-_glibtop_init_cpu_p (glibtop *server)
+_glibtop_init_cpu_s (glibtop *server)
 {
        server->sysdeps.cpu = _glibtop_sysdeps_cpu;
 }
@@ -50,7 +50,7 @@ _glibtop_init_cpu_p (glibtop *server)
 /* Provides information about cpu usage. */
 
 void
-glibtop_get_cpu_p (glibtop *server, glibtop_cpu *buf)
+glibtop_get_cpu_s (glibtop *server, glibtop_cpu *buf)
 {
        gulong cpts [CPUSTATES];
 
diff --git a/sysdeps/openbsd/fsusage.c b/sysdeps/openbsd/fsusage.c
index 7abafe6..832d036 100644
--- a/sysdeps/openbsd/fsusage.c
+++ b/sysdeps/openbsd/fsusage.c
@@ -1,13 +1,4 @@
 #include <config.h>
-
-/*
- * statvfs is lacking various members which are present in statfs,
- * like f_(a)syncreads and f_(a)syncwrites. So eventhough we have
- * statvfs, undef it here untill those members are added.
- */
-#undef HAVE_SYS_STATVFS_H
-#undef STAT_STATVFS
-
 #include <glibtop.h>
 #include <glibtop/error.h>
 #include <glibtop/fsusage.h>
@@ -18,44 +9,57 @@
 
 #include <unistd.h>
 #include <sys/param.h>
-#if defined (HAVE_SYS_STATVFS_H)
-#include <sys/statvfs.h>
-#else
 #include <sys/mount.h>
-#endif
+#include <sys/statvfs.h>
 
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 
-void
-_glibtop_openbsd_get_fsusage_read_write(glibtop *server,
-                                     glibtop_fsusage *buf,
-                                     const char *path);
+static const unsigned long _glibtop_sysdeps_fsusage =
+(1L << GLIBTOP_FSUSAGE_BLOCKS) + (1L << GLIBTOP_FSUSAGE_BFREE)
++ (1L << GLIBTOP_FSUSAGE_BAVAIL) + (1L << GLIBTOP_FSUSAGE_FILES)
++ (1L << GLIBTOP_FSUSAGE_FFREE) + (1L << GLIBTOP_FSUSAGE_BLOCK_SIZE);
+
+static void
+_glibtop_get_fsusage_read_write (glibtop *server, glibtop_fsusage *buf, const char *path)
+{
+        int result;
+        struct statfs sfs;
+
+        result = statfs (path, &sfs);
+
+        if (result == -1) {
+                glibtop_warn_io_r (server, "statfs");
+                return;
+        }
+
+        buf->read = sfs.f_syncreads + sfs.f_asyncreads;
+        buf->write = sfs.f_syncwrites + sfs.f_asyncwrites;
+        buf->flags |= (1 << GLIBTOP_FSUSAGE_READ) | (1 << GLIBTOP_FSUSAGE_WRITE);
+}
 
 void
-_glibtop_openbsd_get_fsusage_read_write(glibtop *server,
-                                     glibtop_fsusage *buf,
-                                     const char *path)
+glibtop_get_fsusage_s(glibtop *server, glibtop_fsusage *buf, const char *path)
 {
-       int result;
-#if defined (STAT_STATVFS)
-       struct statvfs sfs;
-#else
-       struct statfs sfs;
-#endif
-
-#if defined (STAT_STATVFS)
-       result = statvfs (path, &sfs);
-#else
-       result = statfs (path, &sfs);
-#endif
-
-       if (result == -1) {
+       struct statvfs fsd;
+
+       glibtop_init_r (&server, 0, 0);
+
+       memset (buf, 0, sizeof (glibtop_fsusage));
+
+       if (statvfs (path, &fsd) < 0)
                return;
-       }
 
-       buf->read = sfs.f_syncreads + sfs.f_asyncreads;
-       buf->write = sfs.f_syncwrites + sfs.f_asyncwrites;
-       buf->flags |= (1 << GLIBTOP_FSUSAGE_READ) | (1 << GLIBTOP_FSUSAGE_WRITE);
+       buf->block_size = fsd.f_frsize;
+       buf->blocks = fsd.f_blocks;
+       buf->bfree  = fsd.f_bfree;
+       buf->bavail = (fsd.f_bavail > fsd.f_bfree) ? 0 : fsd.f_bavail;
+       buf->files  = fsd.f_files;
+       buf->ffree  = fsd.f_ffree;
+
+       buf->flags = _glibtop_sysdeps_fsusage;
+
+       _glibtop_get_fsusage_read_write(server, buf, path);
 }
+
diff --git a/sysdeps/openbsd/glibtop_server.h b/sysdeps/openbsd/glibtop_server.h
index 3db000e..f93ffdd 100644
--- a/sysdeps/openbsd/glibtop_server.h
+++ b/sysdeps/openbsd/glibtop_server.h
@@ -24,11 +24,7 @@
 
 G_BEGIN_DECLS
 
-#define GLIBTOP_SUID_CPU               (1 << GLIBTOP_SYSDEPS_CPU)
-#define GLIBTOP_SUID_MEM               (1 << GLIBTOP_SYSDEPS_MEM)
 #define GLIBTOP_SUID_SWAP              (1 << GLIBTOP_SYSDEPS_SWAP)
-#define GLIBTOP_SUID_UPTIME            (1 << GLIBTOP_SYSDEPS_UPTIME)
-#define GLIBTOP_SUID_LOADAVG           (1 << GLIBTOP_SYSDEPS_LOADAVG)
 #define GLIBTOP_SUID_SHM_LIMITS                (1 << GLIBTOP_SYSDEPS_SHM_LIMITS)
 #define GLIBTOP_SUID_MSG_LIMITS                (1 << GLIBTOP_SYSDEPS_MSG_LIMITS)
 #define GLIBTOP_SUID_SEM_LIMITS                (1 << GLIBTOP_SYSDEPS_SEM_LIMITS)
@@ -43,8 +39,12 @@ G_BEGIN_DECLS
 #define GLIBTOP_SUID_PROC_ARGS         (1 << GLIBTOP_SYSDEPS_PROC_ARGS)
 #define GLIBTOP_SUID_PROC_MAP          (1 << GLIBTOP_SYSDEPS_PROC_MAP)
 #define GLIBTOP_SUID_NETLOAD           (1 << GLIBTOP_SYSDEPS_NETLOAD)
-#define GLIBTOP_SUID_NETLIST           0
 #define GLIBTOP_SUID_PPP               (1 << GLIBTOP_SYSDEPS_PPP)
+#define GLIBTOP_SUID_CPU               0
+#define GLIBTOP_SUID_MEM               0
+#define GLIBTOP_SUID_UPTIME            0
+#define GLIBTOP_SUID_LOADAVG           0
+#define GLIBTOP_SUID_NETLIST           0
 #define GLIBTOP_SUID_PROC_WD           0
 #define GLIBTOP_SUID_PROC_AFFINITY     0
 
diff --git a/sysdeps/openbsd/loadavg.c b/sysdeps/openbsd/loadavg.c
index 6bee934..c35c14e 100644
--- a/sysdeps/openbsd/loadavg.c
+++ b/sysdeps/openbsd/loadavg.c
@@ -32,7 +32,7 @@ static const unsigned long _glibtop_sysdeps_loadavg =
 /* Init function. */
 
 void
-_glibtop_init_loadavg_p (glibtop *server)
+_glibtop_init_loadavg_s (glibtop *server)
 {
        server->sysdeps.loadavg = _glibtop_sysdeps_loadavg;
 }
@@ -40,7 +40,7 @@ _glibtop_init_loadavg_p (glibtop *server)
 /* Provides load averange. */
 
 void
-glibtop_get_loadavg_p (glibtop *server, glibtop_loadavg *buf)
+glibtop_get_loadavg_s (glibtop *server, glibtop_loadavg *buf)
 {
        double ldavg[3];
        int i;
diff --git a/sysdeps/openbsd/mem.c b/sysdeps/openbsd/mem.c
index 2abd3c3..6a49415 100644
--- a/sysdeps/openbsd/mem.c
+++ b/sysdeps/openbsd/mem.c
@@ -48,12 +48,6 @@ static int pageshift;                /* log base 2 of the pagesize */
 /* define pagetok in terms of pageshift */
 #define pagetok(size) ((size) << pageshift)
 
-/* nlist structure for kernel access */
-static struct nlist nlst [] = {
-       { "_bufpages" },
-       { 0 }
-};
-
 /* MIB array for sysctl */
 static int vmmeter_mib [] = { CTL_VM, VM_METER };
 static int uvmexp_mib  [] = { CTL_VM, VM_UVMEXP };
@@ -62,15 +56,10 @@ static int bcstats_mib [] = { CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT };
 /* Init function. */
 
 void
-_glibtop_init_mem_p (glibtop *server)
+_glibtop_init_mem_s (glibtop *server)
 {
        register int pagesize;
 
-       if (kvm_nlist (server->machine.kd, nlst) < 0) {
-               glibtop_warn_io_r (server, "kvm_nlist (mem)");
-               return;
-       }
-
        /* get the page size and calculate pageshift from it */
        pagesize = sysconf(_SC_PAGESIZE);
        pageshift = 0;
@@ -86,7 +75,7 @@ _glibtop_init_mem_p (glibtop *server)
 }
 
 void
-glibtop_get_mem_p (glibtop *server, glibtop_mem *buf)
+glibtop_get_mem_s (glibtop *server, glibtop_mem *buf)
 {
        struct vmtotal vmt;
        struct uvmexp uvmexp;
diff --git a/sysdeps/openbsd/mountlist.c b/sysdeps/openbsd/mountlist.c
new file mode 100644
index 0000000..1e33485
--- /dev/null
+++ b/sysdeps/openbsd/mountlist.c
@@ -0,0 +1,168 @@
+/* mountlist.c -- return a list of mounted filesystems
+   Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include <config.h>
+
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+
+#include <string.h>
+
+#include <glibtop.h>
+#include <glibtop/mountlist.h>
+
+/* A mount table entry. */
+struct mount_entry
+{
+  char *me_devname;             /* Device node pathname, including "/dev/". */
+  char *me_mountdir;            /* Mount point directory pathname. */
+  char *me_type;                /* "nfs", "4.2", etc. */
+  dev_t me_dev;                 /* Device number of me_mountdir. */
+  struct mount_entry *me_next;
+};
+
+static struct mount_entry *read_filesystem_list (void);
+
+/* Return a list of the currently mounted filesystems, or NULL on error.
+   Add each entry to the tail of the list so that they stay in order.
+*/
+
+static struct mount_entry *
+read_filesystem_list (void)
+{
+  struct mount_entry *mount_list;
+  struct mount_entry *me;
+  struct mount_entry *mtail;
+
+  /* Start the list off with a dummy entry. */
+  me = g_new (struct mount_entry, 1);
+  me->me_next = NULL;
+  mount_list = mtail = me;
+  {
+    struct statfs *fsp;
+    int entries;
+
+    entries = getmntinfo (&fsp, MNT_NOWAIT);
+    if (entries < 0)
+      return NULL;
+    while (entries-- > 0)
+      {
+       me = (struct mount_entry *) g_malloc (sizeof (struct mount_entry));
+       me->me_devname = g_strdup (fsp->f_mntfromname);
+       me->me_mountdir = g_strdup (fsp->f_mntonname);
+       me->me_type = g_strdup (fsp->f_fstypename);
+       me->me_dev = (dev_t) -1;        /* Magic; means not known yet. */
+       me->me_next = NULL;
+
+       /* Add to the linked list. */
+       mtail->me_next = me;
+       mtail = me;
+       fsp++;
+      }
+  }
+
+  /* Free the dummy head. */
+  me = mount_list;
+  mount_list = mount_list->me_next;
+  g_free (me);
+  return mount_list;
+}
+
+static gboolean ignore_mount_entry(const struct mount_entry *me)
+{
+       /* keep sorted */
+       static const char ignored[][17] = {
+               "autofs",
+               "devfs",
+               "fusectl",
+               "linprocfs",
+               "linsysfs",
+               "mfs",
+               "none",
+               "nfs",
+               "nullfs",
+               "nwfs",
+               "portalfs",
+               "proc",
+               "procfs",
+               "smbfs",
+               "tmpfs",
+               "unionfs",
+               "unknown"
+       };
+
+       typedef int (*Comparator)(const void*, const void*);
+
+       return bsearch(me->me_type,
+                      ignored, G_N_ELEMENTS(ignored), sizeof ignored[0],
+                      (Comparator) strcmp) != NULL;
+}
+
+
+glibtop_mountentry *
+glibtop_get_mountlist_s (glibtop *server, glibtop_mountlist *buf, int all_fs)
+{
+       struct mount_entry *entries, *cur, *next;
+
+       GArray *mount_array = g_array_new(FALSE, FALSE,
+                                         sizeof(glibtop_mountentry));
+
+       glibtop_init_r (&server, 0, 0);
+
+       memset (buf, 0, sizeof (glibtop_mountlist));
+
+       /* Read filesystem list. */
+
+       if((entries = read_filesystem_list ()) == NULL)
+               return NULL;
+
+       for (cur = &entries[0]; cur != NULL; cur = next) {
+
+               if(all_fs || !ignore_mount_entry(cur)) {
+                       /* add a new glibtop_mountentry */
+                       glibtop_mountentry e;
+
+                       g_strlcpy(e.devname,  cur->me_devname,  sizeof e.devname);
+                       g_strlcpy(e.mountdir, cur->me_mountdir, sizeof e.mountdir);
+                       g_strlcpy(e.type,     cur->me_type,     sizeof e.type);
+                       e.dev = cur->me_dev;
+
+                       g_array_append_val(mount_array, e);
+               }
+
+               /* free current mount_entry and move to the next */
+               next = cur->me_next;
+               g_free(cur->me_devname);
+               g_free(cur->me_mountdir);
+               g_free(cur->me_type);
+               g_free(cur);
+       }
+
+       buf->size   = sizeof (glibtop_mountentry);
+       buf->number = mount_array->len;
+       buf->total  = buf->number * buf->size;
+
+       buf->flags  = (1 << GLIBTOP_MOUNTLIST_SIZE)
+         | (1 << GLIBTOP_MOUNTLIST_NUMBER)
+         | (1 << GLIBTOP_MOUNTLIST_TOTAL);
+
+       return (glibtop_mountentry*) g_array_free(mount_array, FALSE);
+}
diff --git a/sysdeps/openbsd/nosuid.c b/sysdeps/openbsd/nosuid.c
index b43eaca..0394540 100644
--- a/sysdeps/openbsd/nosuid.c
+++ b/sysdeps/openbsd/nosuid.c
@@ -21,16 +21,8 @@
 
 #include <config.h>
 #include <glibtop.h>
-#include <glibtop/open.h>
 #include <glibtop/close.h>
 
 void
-glibtop_open_s (glibtop *server,
-               const char *program_name,
-               const unsigned long features,
-               const unsigned flags)
-{ }
-
-void
 glibtop_close_s (glibtop *server)
 { }
diff --git a/sysdeps/openbsd/open.c b/sysdeps/openbsd/open.c
index 2ced09a..66f0cdb 100644
--- a/sysdeps/openbsd/open.c
+++ b/sysdeps/openbsd/open.c
@@ -20,75 +20,17 @@
 */
 
 #include <config.h>
+#include <sys/types.h>
 #include <glibtop.h>
-#include <glibtop/error.h>
 #include <glibtop/open.h>
-#include <glibtop/init_hooks.h>
 
-/* !!! THIS FUNCTION RUNS SUID ROOT - CHANGE WITH CAUTION !!! */
+#include <glibtop_private.h>
 
-void
-glibtop_init_p (glibtop *server, const unsigned long features,
-               const unsigned flags)
-{
-       const _glibtop_init_func_t *init_fkt;
-
-       if (server == NULL)
-               glibtop_error_r (NULL, "glibtop_init_p (server == NULL)");
-
-       /* Do the initialization, but only if not already initialized. */
-
-       if ((server->flags & _GLIBTOP_INIT_STATE_SYSDEPS) == 0) {
-               glibtop_open_p (server, "glibtop", features, flags);
-
-               for (init_fkt = _glibtop_init_hook_p; *init_fkt; init_fkt++)
-                       (*init_fkt) (server);
-
-               server->flags |= _GLIBTOP_INIT_STATE_SYSDEPS;
-       }
-}
 
 void
-glibtop_open_p (glibtop *server, const char *program_name,
+glibtop_open_s (glibtop *server, const char *program_name,
                const unsigned long features,
                const unsigned flags)
 {
-       char errbuf[_POSIX2_LINE_MAX];
-#ifdef DEBUG
-       fprintf (stderr, "DEBUG (%d): glibtop_open_p ()\n", getpid ());
-#endif
-
-       /* !!! WE ARE ROOT HERE - CHANGE WITH CAUTION !!! */
-
-       server->machine.uid = getuid ();
-       server->machine.euid = geteuid ();
-       server->machine.gid = getgid ();
-       server->machine.egid = getegid ();
-
        server->os_version_code = OpenBSD;
-
-       /* Setup machine-specific data */
-       server->machine.kd = kvm_openfiles (NULL, NULL, NULL, O_RDONLY, errbuf);
-
-       if (server->machine.kd == NULL)
-               glibtop_error_io_r (server, "kvm_open");
-
-       /* Drop priviledges. */
-
-       if (setreuid (server->machine.euid, server->machine.uid))
-               _exit (1);
-
-       if (setregid (server->machine.egid, server->machine.gid))
-               _exit (1);
-
-       /* !!! END OF SUID ROOT PART !!! */
-
-       /* Our effective uid is now those of the user invoking the server,
-        * so we do no longer have any priviledges. */
-
-       /* NOTE: On FreeBSD, we do not need to be suid root, we just need to
-        * be sgid kmem.
-        *
-        * The server will only use setegid() to get back it's priviledges,
-        * so it will fail if it is suid root and not sgid kmem. */
 }
diff --git a/sysdeps/openbsd/procaffinity.c b/sysdeps/openbsd/procaffinity.c
index a8957e9..4164cd9 100644
--- a/sysdeps/openbsd/procaffinity.c
+++ b/sysdeps/openbsd/procaffinity.c
@@ -1,5 +1,5 @@
 /*
- * procaffinity stub.
+ * TODO (procaffinity stub)
  */
 
 #include <config.h>
diff --git a/sysdeps/openbsd/prockernel.c b/sysdeps/openbsd/prockernel.c
index 9d1a214..698c5c5 100644
--- a/sysdeps/openbsd/prockernel.c
+++ b/sysdeps/openbsd/prockernel.c
@@ -34,12 +34,13 @@
 #include <fcntl.h>
 
 static const unsigned long _glibtop_sysdeps_proc_kernel_pstats =
+(1L << GLIBTOP_PROC_KERNEL_K_FLAGS) +
 (1L << GLIBTOP_PROC_KERNEL_MIN_FLT) +
 (1L << GLIBTOP_PROC_KERNEL_MAJ_FLT);
 
 static const unsigned long _glibtop_sysdeps_proc_kernel_wchan =
-(1L << GLIBTOP_PROC_KERNEL_NWCHAN) +
-(1L << GLIBTOP_PROC_KERNEL_WCHAN);
+(1L << GLIBTOP_PROC_KERNEL_WCHAN) +
+(1L << GLIBTOP_PROC_KERNEL_NWCHAN);
 
 /* Init function. */
 
@@ -68,22 +69,39 @@ glibtop_get_proc_kernel_p (glibtop *server,
        /* It does not work for the swapper task. */
        if (pid == 0) return;
 
+       glibtop_suid_enter (server);
+
        /* Get the process information */
        pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid,
                              sizeof(*pinfo), &count);
        if ((pinfo == NULL) || (count != 1)) {
                glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid);
+               glibtop_suid_leave (server);
                return;
        }
 
-       buf->min_flt = pinfo[0].p_uru_minflt;
-       buf->maj_flt = pinfo[0].p_uru_majflt;
+       glibtop_suid_leave (server);
+
+#define        PROC_WCHAN      p_wchan
+#define        PROC_WMESG      p_wmesg
+
+       buf->nwchan = (unsigned long) pinfo [0].PROC_WCHAN;
+
+       buf->flags |= (1L << GLIBTOP_PROC_KERNEL_NWCHAN);
+
+       if (pinfo [0].PROC_WCHAN && pinfo [0].PROC_WMESG[0] != 0) {
+               g_strlcpy (buf->wchan, pinfo [0].PROC_WMESG,
+                        sizeof buf->wchan);
+               buf->flags |= (1L << GLIBTOP_PROC_KERNEL_WCHAN);
+       } else {
+               buf->wchan [0] = 0;
+       }
+
+       buf->k_flags = (unsigned long) pinfo [0].p_flag;
+       buf->min_flt = (unsigned long) pinfo [0].p_uru_minflt;
+       buf->maj_flt = (unsigned long) pinfo [0].p_uru_majflt;
 
-       buf->nwchan = pinfo[0].p_wchan;
-       if (pinfo[0].p_wchan && pinfo[0].p_wmesg)
-               g_strlcpy(buf->wchan, pinfo[0].p_wmesg,
-                         sizeof buf->wchan);
+       buf->flags |= _glibtop_sysdeps_proc_kernel_pstats;
 
-       buf->flags |= (_glibtop_sysdeps_proc_kernel_wchan
-               | _glibtop_sysdeps_proc_kernel_pstats);
+       return;
 }
diff --git a/sysdeps/openbsd/procmap.c b/sysdeps/openbsd/procmap.c
index 7984f3d..9a01d2e 100644
--- a/sysdeps/openbsd/procmap.c
+++ b/sysdeps/openbsd/procmap.c
@@ -191,8 +191,11 @@ glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf,
 
        if (kvm_read (server->machine.kd,
                      (unsigned long) pinfo [0].p_vmspace,
-                     (char *) &vmspace, sizeof (vmspace)) != sizeof (vmspace))
-               glibtop_error_io_r (server, "kvm_read (vmspace)");
+                     (char *) &vmspace, sizeof (vmspace)) != sizeof (vmspace)) {
+                       glibtop_warn_io_r (server, "kvm_read (vmspace)");
+                       glibtop_suid_leave (server);
+                       return NULL;
+       }
 
        RB_INIT(&root);
        nentries = load_vmmap_entries(server,
@@ -236,6 +239,7 @@ glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf,
                              &vnode, sizeof (vnode)) != sizeof (vnode)) {
                        glibtop_warn_io_r (server, "kvm_read (vnode)");
                        unload_vmmap_entries(RB_ROOT(&root));
+                       glibtop_suid_leave (server);
                        return (glibtop_map_entry*) g_array_free(maps, TRUE);
                }
 
@@ -248,8 +252,12 @@ glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf,
 
                if (kvm_read (server->machine.kd,
                              (unsigned long) vnode.v_data,
-                             &inode, sizeof (inode)) != sizeof (inode))
-                       glibtop_error_io_r (server, "kvm_read (inode)");
+                             &inode, sizeof (inode)) != sizeof (inode)) {
+                       glibtop_warn_io_r (server, "kvm_read (inode)");
+                       unload_vmmap_entries(RB_ROOT(&root));
+                       glibtop_suid_leave (server);
+                       return (glibtop_map_entry*) g_array_free(maps, TRUE);
+               }
 
                inum  = inode.i_number;
                dev = inode.i_dev;
@@ -276,6 +284,8 @@ glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf,
                        mentry->perm |= GLIBTOP_MAP_PERM_EXECUTE;
        }
 
+       glibtop_suid_leave (server);
+
        buf->flags = _glibtop_sysdeps_proc_map;
 
        buf->number = maps->len;
diff --git a/sysdeps/openbsd/proctime.c b/sysdeps/openbsd/proctime.c
index 2d1230e..af8551d 100644
--- a/sysdeps/openbsd/proctime.c
+++ b/sysdeps/openbsd/proctime.c
@@ -56,59 +56,6 @@ _glibtop_init_proc_time_p (glibtop *server)
                _glibtop_sysdeps_proc_time_user;
 }
 
-/* Taken from /usr/src/sys/kern/kern_resource.c */
-
-/*
- * Transform the running time and tick information in proc p into user,
- * system, and interrupt time usage.
- */
-
-static void
-calcru(struct proc *p, struct timeval *up, struct timeval *sp,
-    struct timeval *ip)
-{
-       quad_t totusec;
-       u_quad_t u, st, ut, it, tot;
-        long sec, nsec;
-        struct timeval tv;
-
-       st = p->p_sticks;
-       ut = p->p_uticks;
-       it = p->p_iticks;
-
-       tot = st + ut + it;
-       if (tot == 0) {
-               st = 1;
-               tot = 1;
-       }
-
-       sec = p->p_rtime.tv_sec;
-       nsec = p->p_rtime.tv_nsec;
-
-       totusec = (quad_t)sec * 1000000 + nsec/1000;
-
-       if (totusec < 0) {
-               /* XXX no %qd in kernel.  Truncate. */
-               fprintf (stderr, "calcru: negative time: %ld usec\n",
-                        (long)totusec);
-               totusec = 0;
-       }
-
-
-       u = totusec;
-       st = (u * st) / tot;
-       sp->tv_sec = st / 1000000;
-       sp->tv_usec = st % 1000000;
-       ut = (u * ut) / tot;
-       up->tv_sec = ut / 1000000;
-       up->tv_usec = ut % 1000000;
-       if (ip != NULL) {
-               it = (u * it) / tot;
-               ip->tv_sec = it / 1000000;
-               ip->tv_usec = it % 1000000;
-       }
-}
-
 /* Provides detailed information about a process. */
 
 void
diff --git a/sysdeps/openbsd/procwd.c b/sysdeps/openbsd/procwd.c
index fcf386e..ad084f5 100644
--- a/sysdeps/openbsd/procwd.c
+++ b/sysdeps/openbsd/procwd.c
@@ -39,58 +39,6 @@ _glibtop_init_proc_wd_s(glibtop *server)
        server->sysdeps.proc_wd = _glibtop_sysdeps_proc_wd;
 }
 
-static GPtrArray *
-parse_output(const char *output, glibtop_proc_wd *buf)
-{
-       GPtrArray *dirs;
-       char     **lines;
-       gboolean   nextwd = FALSE;
-       gboolean   nextrtd = FALSE;
-       gboolean   havertd = FALSE;
-       guint      i;
-       guint      len;
-
-       dirs = g_ptr_array_sized_new(1);
-
-       lines = g_strsplit(output, "\n", 0);
-       len = g_strv_length(lines);
-
-       for (i = 0; i < len && lines[i]; i++) {
-               if (strlen(lines[i]) < 2)
-                       continue;
-
-               if (!strcmp(lines[i], "fcwd")) {
-                       nextwd = TRUE;
-                       continue;
-               }
-
-               if (!strcmp(lines[i], "frtd")) {
-                       nextrtd = TRUE;
-                       continue;
-               }
-
-               if (!g_str_has_prefix(lines[i], "n"))
-                       continue;
-
-               if (nextwd) {
-                       g_ptr_array_add(dirs, g_strdup(lines[i] + 1));
-                       nextwd = FALSE;
-               }
-
-               if (nextrtd && !havertd) {
-                       g_strlcpy(buf->root, lines[i] + 1,
-                                 sizeof(buf->root));
-                       buf->flags |= (1 << GLIBTOP_PROC_WD_ROOT);
-                       nextrtd = FALSE;
-                       havertd = TRUE;
-               }
-       }
-
-       g_strfreev(lines);
-
-       return dirs;
-}
-
 char**
 glibtop_get_proc_wd_s(glibtop *server, glibtop_proc_wd *buf, pid_t pid)
 {
diff --git a/sysdeps/openbsd/suid_open.c b/sysdeps/openbsd/suid_open.c
new file mode 100644
index 0000000..137a426
--- /dev/null
+++ b/sysdeps/openbsd/suid_open.c
@@ -0,0 +1,92 @@
+/* Copyright (C) 1998 Joshua Sled
+   This file is part of LibGTop 1.0.
+
+   Contributed by Joshua Sled <jsled xcf berkeley edu>, July 1998.
+
+   LibGTop is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License,
+   or (at your option) any later version.
+
+   LibGTop is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with LibGTop; see the file COPYING. If not, write to the
+   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+#include <glibtop.h>
+#include <glibtop/error.h>
+#include <glibtop/cpu.h>
+#include <glibtop/open.h>
+#include <glibtop/init_hooks.h>
+
+
+/* !!! THIS FUNCTION RUNS SUID ROOT - CHANGE WITH CAUTION !!! */
+
+void
+glibtop_init_p (glibtop *server, const unsigned long features,
+               const unsigned flags)
+{
+       const _glibtop_init_func_t *init_fkt;
+
+       if (server == NULL)
+               glibtop_error_r (NULL, "glibtop_init_p (server == NULL)");
+
+       /* Do the initialization, but only if not already initialized. */
+
+       if ((server->flags & _GLIBTOP_INIT_STATE_SYSDEPS) == 0) {
+               glibtop_open_p (server, "glibtop", features, flags);
+
+               for (init_fkt = _glibtop_init_hook_p; *init_fkt; init_fkt++)
+                       (*init_fkt) (server);
+
+               server->flags |= _GLIBTOP_INIT_STATE_SYSDEPS;
+       }
+}
+
+void
+glibtop_open_p (glibtop *server, const char *program_name,
+               const unsigned long features,
+               const unsigned flags)
+{
+       char errbuf[_POSIX2_LINE_MAX];
+#ifdef DEBUG
+       fprintf (stderr, "DEBUG (%d): glibtop_open_p ()\n", getpid ());
+#endif
+
+       /* !!! WE ARE ROOT HERE - CHANGE WITH CAUTION !!! */
+       server->machine.uid = getuid ();
+       server->machine.euid = geteuid ();
+       server->machine.gid = getgid ();
+       server->machine.egid = getegid ();
+       /* Setup machine-specific data */
+       server->machine.kd = kvm_openfiles (NULL, NULL, NULL, O_RDONLY, errbuf);
+
+       if (server->machine.kd == NULL)
+               glibtop_error_io_r (server, "kvm_open");
+
+       /* Drop priviledges. */
+
+       if (setreuid (server->machine.euid, server->machine.uid))
+               _exit (1);
+
+       if (setregid (server->machine.egid, server->machine.gid))
+               _exit (1);
+
+       /* !!! END OF SUID ROOT PART !!! */
+
+       /* Our effective uid is now those of the user invoking the server,
+        * so we do no longer have any priviledges. */
+
+       /* NOTE: On OpenBSD, we do not need to be suid root, we just need to
+        * be sgid kmem.
+        *
+        * The server will only use setegid() to get back it's priviledges,
+        * so it will fail if it is suid root and not sgid kmem. */
+}
diff --git a/sysdeps/openbsd/uptime.c b/sysdeps/openbsd/uptime.c
index 111a2f0..6067fbf 100644
--- a/sysdeps/openbsd/uptime.c
+++ b/sysdeps/openbsd/uptime.c
@@ -37,7 +37,7 @@ static const unsigned long _required_cpu_flags =
 /* Init function. */
 
 void
-_glibtop_init_uptime_p (glibtop *server)
+_glibtop_init_uptime_s (glibtop *server)
 {
        server->sysdeps.uptime = _glibtop_sysdeps_uptime;
 }
@@ -45,7 +45,7 @@ _glibtop_init_uptime_p (glibtop *server)
 /* Provides uptime and idle time. */
 
 void
-glibtop_get_uptime_p (glibtop *server, glibtop_uptime *buf)
+glibtop_get_uptime_s (glibtop *server, glibtop_uptime *buf)
 {
        time_t now;
        int mib[2];
@@ -63,7 +63,7 @@ glibtop_get_uptime_p (glibtop *server, glibtop_uptime *buf)
                buf->boot_time = boottime.tv_sec;
        }
 
-       glibtop_get_cpu_p (server, &cpu);
+       glibtop_get_cpu_s (server, &cpu);
 
        /* Put something clever in buf->idletime: CP_IDLE. */
        buf->idletime = (double) cpu.idle / (double) cpu.frequency;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]