summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarlos Perelló Marín <carlos@gnome.org>2003-10-19 16:55:56 +0000
committerCarlos Perelló Marín <carlos@src.gnome.org>2003-10-19 16:55:56 +0000
commit4c8ae9e25c1940d8876ca3f2330426863cae4737 (patch)
treec43f97bc0647546b0ed87022db0749c137f24edc /src
parentbae16b467f90df94d80feae41dceb7e816f16c61 (diff)
downloadlibgtop-4c8ae9e25c1940d8876ca3f2330426863cae4737.tar.gz
Reverted libgtop changes. It's a common module and I should not modify it.
2003-10-19 Carlos Perelló Marín <carlos@gnome.org> * support/*: Reverted libgtop changes. It's a common module and I should not modify it. * Added/removed files. Now the move should be done.
Diffstat (limited to 'src')
-rw-r--r--src/daemon/.cvsignore7
-rw-r--r--src/daemon/ChangeLog104
-rw-r--r--src/daemon/Makefile.am53
-rw-r--r--src/daemon/daemon.h81
-rw-r--r--src/daemon/gnuserv.c643
-rw-r--r--src/daemon/io.c98
-rw-r--r--src/daemon/main.c237
-rw-r--r--src/daemon/server.c110
-rw-r--r--src/daemon/server_config.h11
-rw-r--r--src/daemon/server_config.h.in44
-rwxr-xr-xsrc/daemon/server_config.pl111
-rw-r--r--src/daemon/slave.c256
-rw-r--r--src/daemon/version.c62
-rw-r--r--src/inodedb/file_by_inode2.c (renamed from src/inodedb/file_by_inode.c)46
-rw-r--r--src/inodedb/mkinodedb.c137
-rw-r--r--src/inodedb/mkinodedb2.c135
16 files changed, 1974 insertions, 161 deletions
diff --git a/src/daemon/.cvsignore b/src/daemon/.cvsignore
new file mode 100644
index 00000000..ccdb1c11
--- /dev/null
+++ b/src/daemon/.cvsignore
@@ -0,0 +1,7 @@
+Makefile.in
+Makefile
+libgtop_daemon2
+libgtop_server2
+server.conf
+.libs
+.deps
diff --git a/src/daemon/ChangeLog b/src/daemon/ChangeLog
new file mode 100644
index 00000000..2ddb846e
--- /dev/null
+++ b/src/daemon/ChangeLog
@@ -0,0 +1,104 @@
+2003-05-11 Andrew Sobala <aes@gnome.org>
+
+ * gnuserv.c: (permitted): fix buffer overflow vulnerability
+
+2001-02-14 Martin Baulig <baulig@suse.de>
+
+ * Makefile.am (libgtop_server_LDADD): Removed @LIBSUPPORT@.
+
+1999-11-28 Martin Baulig <martin@home-of-linux.org>
+
+ * gnuserv.c (setup_table): Don't dump core when the table of
+ permitted host names contains a NULL pointer.
+
+1999-07-29 Martin Baulig <martin@home-of-linux.org>
+
+ * Makefile.am: Link the `libgtop_daemon' and the `libgtop_server'
+ statically if possible.
+
+1999-05-07 Martin Baulig <martin@home-of-linux.org>
+
+ * server.c (main): There's some problem with uname () - some systems
+ like Solaris or Digital Unix return a nonnegative value on success,
+ some others like Linux return 0. Since all known systems seem to return
+ a negative value on failure, we simply check whether the return value is
+ not negative here.
+
+1999-02-19 Martin Baulig <martin@home-of-linux.org>
+
+ * Makefile.am (LIBGTOP_COMPILE_SYSTEM): Hardcoded system name.
+ (LIBGTOP_COMPILE_RELEASE): Hardcoded system release.
+ (LIBGTOP_COMPILE_MACHINE): Hardcoded machine type.
+
+ * src/daemon/Makefile.am (libgtop_server_SOURCES): Don't use
+ `@INTLLIBS@' for the server.
+
+ * server.c (main): Abort if not running on the system the server
+ was compiled on.
+
+1999-02-10 Martin Baulig <martin@home-of-linux.org>
+
+ * gnuserv.c (program_invocation_*_name): Declare this as `extern'
+ if necessary.
+
+1998-12-17 Martin Baulig <baulig@merkur.uni-trier.de>
+
+ * gnuserv.c: Don't include <gnome-argp.h>.
+ (program_invocation_name, program_invocation_short_name): Define
+ this here.
+
+1998-12-09 Martin Baulig <martin@home-of-linux.org>
+
+ Larger changes to the daemon:
+
+ - Dropped all the unix domain socket stuff - we don't need it for
+ connections on the local host, here we behave just like any normal
+ application.
+ - Added poptimization: use the --help parameter to get usage info
+ - Made it a real daemon, fork into background and write to syslog.
+ - It's now possible to invoke the daemon from inetd, you'll get
+ GNU_SECURE authentication in this case.
+ - Don't make this executable suid/sgid - if invoked as root it
+ sets uid/gid to SERVER_UID/SERVER_GID as defined in server_config.h
+ - Added missing features, so you can now really use this thing.
+
+1998-11-11 Martin Baulig <martin@home-of-linux.org>
+
+ * gnuserv.c (main): Set `server->features' directly rather than
+ calling glibtop_set_parameter_l () since this function no longer
+ allows to modify the features.
+
+ * gnuserv.c, main.c: Use LIBGTOP_ENABLE_DEBUG rather than DEBUG.
+
+1998-11-01 Marc Ewing <marc@tasmanian.redhat.com>
+
+ * Makefile.am: Added $(GLIB_LIBS) to libs. Not sure
+ how it ever built without it.
+
+1998-10-20 Martin Baulig <martin@home-of-linux.org>
+
+ * Makefile.am: Added a notice that this file *requires*
+ libtool 1.2. It may work with 1.1 as well, but that's untested.
+
+1998-10-11 Martin Baulig <martin@home-of-linux.org>
+
+ * Makefile.am (install-exec-hook): Always run `libgtop_postinstall',
+ it's `:' if there's nothing to do since the empty string is no
+ valid shell syntax here.
+
+1998-10-01 Martin Baulig <martin@home-of-linux.org>
+
+ * Makefile.am (install-exec-hook): Use `libgtop_postinstall'
+ here to make the server suid root or sgid kmem if required.
+
+1998-08-25 Martin Baulig <martin@home-of-linux.org>
+
+ * daemon.h (handle_parent_connection): Added prototype.
+ * write.c, io.c: Added cast to `const void *' in calls to
+ `write' and `send' to avoid compiler warnings.
+ * gnuserv.c (handle_signal): Declared static.
+ (main): Casting return value of `getuid' to `int' in
+ debugging statement.
+
+ * ChangeLog: New file.
+
diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am
new file mode 100644
index 00000000..7b1e457a
--- /dev/null
+++ b/src/daemon/Makefile.am
@@ -0,0 +1,53 @@
+## You need libtool 1.2 or newer for this Makefile.am to work.
+##
+## It _may_ work with an older version of libtool, but it also may fail.
+## So if you get any undefined symbols here, please make sure you really
+## have libtool 1.2 or better before reporting this as bug.
+##
+## You'll require libtool 1.2 for other parts of GNOME anyway.
+##
+## Get ftp://ftp.gnu.org/pub/gnu/libtool-1.2.tar.gz
+## (or a newer version if it is available)
+##
+## Martin <martin@home-of-linux.org>
+##
+
+LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@
+
+INCLUDES = $(LIBGTOP_CFLAGS) @INCLUDES@ -D_BSD \
+ -DLIBGTOP_COMPILE_SYSTEM="\"`uname -s`\"" \
+ -DLIBGTOP_COMPILE_RELEASE="\"`uname -r`\"" \
+ -DLIBGTOP_COMPILE_VERSION="\"`uname -v`\"" \
+ -DLIBGTOP_COMPILE_MACHINE="\"`uname -m`\""
+
+if NEED_LIBGTOP
+suid_sysdeps = $(top_builddir)/sysdeps/@sysdeps_dir@/libgtop_sysdeps_suid-2.0.la
+suid_common = $(top_builddir)/sysdeps/common/libgtop_suid_common-2.0.la
+else
+suid_sysdeps =
+suid_common =
+endif
+
+bin_PROGRAMS = libgtop_daemon2 @server_programs@
+
+EXTRA_PROGRAMS = libgtop_server2
+
+libgtop_daemon2_SOURCES = gnuserv.c slave.c main.c io.c version.c \
+ daemon.h server_config.h
+libgtop_daemon2_LDADD = $(top_builddir)/lib/libgtop-2.0.la \
+ $(top_builddir)/sysdeps/common/libgtop_common-2.0.la \
+ $(top_builddir)/sysdeps/@sysdeps_dir@/libgtop_sysdeps-2.0.la \
+ @sysdeps_suid_lib@ \
+ $(suid_sysdeps) $(suid_common)\
+ $(LIBGTOP_LIBS)\
+ @LIBSUPPORT@ @INTLLIBS@ @libs_xauth@
+
+libgtop_server2_SOURCES = server.c slave.c io.c version.c daemon.h
+libgtop_server2_LDADD = $(top_builddir)/sysdeps/@sysdeps_dir@/libgtop_sysdeps_suid-2.0.la \
+ $(top_builddir)/sysdeps/common/libgtop_suid_common-2.0.la
+
+EXTRA_DIST = server_config.h.in server_config.pl
+
+install-exec-hook:
+ -@libgtop_postinstall@
+
diff --git a/src/daemon/daemon.h b/src/daemon/daemon.h
new file mode 100644
index 00000000..9539db37
--- /dev/null
+++ b/src/daemon/daemon.h
@@ -0,0 +1,81 @@
+/* $Id$ */
+
+/* Copyright (C) 1998-99 Martin Baulig
+ This file is part of LibGTop 1.0.
+
+ Contributed by Martin Baulig <martin@home-of-linux.org>, April 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.
+*/
+
+#ifndef __GLIBTOP_DAEMON_H__
+#define __GLIBTOP_DAEMON_H__
+
+#include <glibtop.h>
+#include <glibtop/error.h>
+#include <glibtop/gnuserv.h>
+
+#include <glibtop/open.h>
+#include <glibtop/union.h>
+#include <glibtop/xmalloc.h>
+#include <glibtop/version.h>
+#include <glibtop/command.h>
+#include <glibtop/parameter.h>
+
+#include <fcntl.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <syslog.h>
+
+BEGIN_LIBGTOP_DECLS
+
+/* Some don't have LOG_PERROR */
+#ifndef LOG_PERROR
+#define LOG_PERROR 0
+#endif
+
+#if defined(HAVE_GETDTABLESIZE)
+#define GET_MAX_FDS() getdtablesize()
+#else
+/* Fallthrough case - please add other #elif cases above
+ for different OS's as necessary */
+#define GET_MAX_FDS() 256
+#endif
+
+#define _offset_union(p) ((char *) &resp->u.p - (char *) resp)
+#define _offset_data(p) _offset_union (data.p)
+
+#define MSG_BUFSZ sizeof (struct _glibtop_ipc_message)
+#define MSG_MSGSZ (MSG_BUFSZ - sizeof (long))
+
+void handle_parent_connection (int s);
+void handle_slave_connection (int input, int output);
+void handle_slave_command (glibtop_command *cmnd, glibtop_response *resp,
+ const void *parameter);
+
+void do_output (int s, glibtop_response *resp, off_t offset,
+ size_t data_size, const void *data);
+int do_read (int s, void *ptr, size_t total_size);
+
+void syslog_message (int priority, char *format, ...);
+void syslog_io_message (int priority, char *format, ...);
+
+extern int enable_debug;
+extern int verbose_output;
+
+END_LIBGTOP_DECLS
+
+#endif
diff --git a/src/daemon/gnuserv.c b/src/daemon/gnuserv.c
new file mode 100644
index 00000000..2be6659e
--- /dev/null
+++ b/src/daemon/gnuserv.c
@@ -0,0 +1,643 @@
+/* -*-C-*-
+ * Server code for handling requests from clients and forwarding them
+ * on to the GNU Emacs process.
+ *
+ * This file is part of GNU Emacs.
+ *
+ * Copying is permitted under those conditions described by the GNU
+ * General Public License.
+ *
+ * Copyright (C) 1989 Free Software Foundation, Inc.
+ *
+ * Author: Andy Norman (ange@hplb.hpl.hp.com), based on 'etc/server.c'
+ * from the 18.52 GNU Emacs distribution.
+ *
+ * Please mail bugs and suggestions to the author at the above address.
+ */
+
+/* HISTORY
+ * 11-Nov-1990 bristor@simba
+ * Added EOT stuff.
+ */
+
+/*
+ * This file incorporates new features added by Bob Weiner <weiner@mot.com>,
+ * Darrell Kindred <dkindred@cmu.edu> and Arup Mukherjee <arup@cmu.edu>.
+ * Please see the note at the end of the README file for details.
+ *
+ * (If gnuserv came bundled with your emacs, the README file is probably
+ * ../etc/gnuserv.README relative to the directory containing this file)
+ */
+
+#include <glibtop.h>
+#include <glibtop/open.h>
+#include <glibtop/close.h>
+#include <glibtop/command.h>
+#include <glibtop/xmalloc.h>
+
+#include <glibtop/parameter.h>
+
+#include "server_config.h"
+
+#include <glibtop/gnuserv.h>
+
+#include <errno.h>
+#include <popt-gnome.h>
+
+#include "daemon.h"
+
+#ifdef AIX
+#include <sys/select.h>
+#endif
+
+#ifdef NEED_DECLARATION_PROGRAM_INVOCATION_NAME
+extern char *program_invocation_name, *program_invocation_short_name;
+#endif
+
+#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME
+char *program_invocation_short_name;
+#endif
+
+#ifndef HAVE_PROGRAM_INVOCATION_NAME
+char *program_invocation_name;
+#endif
+
+void handle_parent_connection (int s);
+void handle_slave_connection (int input, int output);
+
+#if !defined(INTERNET_DOMAIN_SOCKETS)
+#error "Internet Domain sockets are required"
+#endif
+
+#ifdef AUTH_MAGIC_COOKIE
+#include <X11/X.h>
+#include <X11/Xauth.h>
+
+static Xauth *server_xauth = NULL;
+
+#endif /* AUTH_MAGIC_COOKIE */
+
+int enable_debug = 0;
+int verbose_output = 0;
+static int no_daemon = 0;
+static int invoked_from_inetd = 0;
+static int changed_uid = 0;
+
+void
+syslog_message (int priority, char *format, ...)
+{
+ va_list ap;
+ char buffer [BUFSIZ];
+
+ va_start (ap, format);
+ vsnprintf (buffer, BUFSIZ-1, format, ap);
+ va_end (ap);
+
+ syslog (priority, "%s", buffer);
+}
+
+void
+syslog_io_message (int priority, char *format, ...)
+{
+ va_list ap;
+ char buffer [BUFSIZ];
+ char buffer2 [BUFSIZ];
+
+ va_start (ap, format);
+ vsnprintf (buffer, BUFSIZ-1, format, ap);
+ va_end (ap);
+
+ snprintf (buffer2, BUFSIZ-1, "%s: %s", buffer, strerror (errno));
+ syslog (priority, "%s", buffer2);
+}
+
+/*
+ * timed_read - Read with timeout.
+ */
+
+static int
+timed_read (int fd, char *buf, int max, int timeout, int one_line)
+{
+ fd_set rmask;
+ struct timeval tv; /* = {timeout, 0}; */
+ char c = 0;
+ int nbytes = 0;
+ int r;
+
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+
+ FD_ZERO (&rmask);
+ FD_SET (fd, &rmask);
+
+ do {
+ r = select (fd + 1, &rmask, NULL, NULL, &tv);
+
+ if (r > 0) {
+ if (read (fd, &c, 1) == 1) {
+ *buf++ = c;
+ ++nbytes;
+ } else {
+ syslog_io_message (LOG_WARNING, "read error on socket");
+ return -1;
+ }
+ } else if (r == 0) {
+ syslog_io_message (LOG_WARNING, "read timed out");
+ return -1;
+ } else {
+ syslog_io_message (LOG_WARNING, "error in select");
+ return -1;
+ }
+ } while ((nbytes < max) && !(one_line && (c == '\n')));
+
+ --buf;
+ if (one_line && *buf == '\n') {
+ *buf = 0;
+ }
+ return nbytes;
+}
+
+
+/*
+ * permitted -- return whether a given host is allowed to connect to the server.
+ */
+
+static int
+permitted (u_long host_addr, int fd)
+{
+ int i;
+
+ char auth_protocol[128];
+ char buf[1024];
+ int auth_data_len;
+
+ /* Read auth protocol name */
+
+ if (timed_read (fd, auth_protocol, AUTH_NAMESZ, AUTH_TIMEOUT, 1) <= 0)
+ return FALSE;
+
+ if (enable_debug)
+ syslog_message (LOG_DEBUG,
+ "Client sent authenticatin protocol '%s'.",
+ auth_protocol);
+
+ if (strcmp (auth_protocol, DEFAUTH_NAME) &&
+ strcmp (auth_protocol, MCOOKIE_NAME)) {
+ syslog_message (LOG_WARNING,
+ "Invalid authentication protocol "
+ "'%s' from client",
+ auth_protocol);
+ return FALSE;
+ }
+
+ if (!strcmp (auth_protocol, MCOOKIE_NAME)) {
+ /*
+ * doing magic cookie auth
+ */
+
+ if (timed_read (fd, buf, 10, AUTH_TIMEOUT, 1) <= 0)
+ return FALSE;
+
+ auth_data_len = atoi (buf);
+
+ if (auth_data_len < 1 || auth_data_len > sizeof(buf)) {
+ syslog_message(LOG_WARNING, "Invalid data length supplied by client");
+ return FALSE;
+ }
+
+ if (timed_read (fd, buf, auth_data_len, AUTH_TIMEOUT, 0) != auth_data_len)
+ return FALSE;
+
+#ifdef AUTH_MAGIC_COOKIE
+ if (!invoked_from_inetd && server_xauth && server_xauth->data &&
+ !memcmp (buf, server_xauth->data, auth_data_len)) {
+ return TRUE;
+ }
+#else
+ syslog_message (LOG_WARNING,
+ "Client tried Xauth, but server is "
+ "not compiled with Xauth");
+#endif
+
+ /*
+ * auth failed, but allow this to fall through to the
+ * GNU_SECURE protocol....
+ */
+
+ if (verbose_output) {
+ if (changed_uid || invoked_from_inetd)
+ syslog_message (LOG_WARNING,
+ "Xauth authentication not allowed, "
+ "trying GNU_SECURE ...");
+ else
+ syslog_message (LOG_WARNING,
+ "Xauth authentication failed, "
+ "trying GNU_SECURE auth...");
+ }
+ }
+
+ /* Other auth protocols go here, and should execute only if
+ * the * auth_protocol name matches. */
+
+ /* Now, try the old GNU_SECURE stuff... */
+
+ if (enable_debug)
+ syslog_message (LOG_DEBUG, "Doing GNU_SECURE auth ...");
+
+ /* Now check the chain for that hash key */
+ for (i = 0; i < HOST_TABLE_ENTRIES; i++) {
+ if (enable_debug)
+ syslog_message (LOG_DEBUG, "Trying %lx - %lx",
+ host_addr, permitted_hosts [i]);
+ if (permitted_hosts [i] == 0L)
+ return (FALSE);
+ if (host_addr == permitted_hosts [i])
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+
+/*
+ * setup_table -- initialise the table of hosts allowed to contact the server,
+ * by reading from the file specified by the GNU_SECURE
+ * environment variable
+ * Put in the local machine, and, if a security file is specifed,
+ * add each host that is named in the file.
+ * Return the number of hosts added.
+ */
+
+static int
+setup_table (void)
+{
+ char hostname [HOSTNAMSZ], screen [BUFSIZ];
+ long host_addr;
+ int i, hosts = 0;
+
+ /* Make sure every entry is null */
+ for (i = 0; i < HOST_TABLE_ENTRIES; i++)
+ permitted_hosts [i] = 0;
+
+ gethostname (hostname, HOSTNAMSZ);
+
+ if ((host_addr = glibtop_internet_addr (hostname)) == -1) {
+ syslog_io_message (LOG_ERR, "Can't resolve '%s'", hostname);
+ exit (1);
+ }
+
+#ifdef AUTH_MAGIC_COOKIE
+
+ sprintf (screen, "%d", SERVER_PORT);
+
+ server_xauth = XauGetAuthByAddr
+ (FamilyInternet,
+ sizeof (host_addr), (char *) &host_addr,
+ strlen (screen), screen,
+ strlen (MCOOKIE_X_NAME), MCOOKIE_X_NAME);
+ hosts++;
+
+#endif /* AUTH_MAGIC_COOKIE */
+
+ /* Resolv host names from permitted_host_names []. */
+
+ for (i = 0; i < HOST_TABLE_ENTRIES; i++) {
+ if (!permitted_host_names [i])
+ continue;
+ if (enable_debug)
+ syslog_message (LOG_DEBUG, "Resolving %s ...",
+ permitted_host_names [i]);
+ permitted_hosts [i] =
+ glibtop_internet_addr (permitted_host_names [i]);
+ if ((long) permitted_hosts [i] == -1) {
+ syslog_io_message (LOG_ERR, "Can't resolve '%s'",
+ permitted_host_names [i]);
+ exit (1);
+ }
+ }
+
+ if (enable_debug)
+ for (i = 0; i < HOST_TABLE_ENTRIES; i++)
+ syslog_message (LOG_DEBUG, "Host %s - %lx",
+ permitted_host_names [i],
+ permitted_hosts [i]);
+
+ hosts += HOST_TABLE_ENTRIES;
+
+ return hosts;
+} /* setup_table */
+
+/*
+ * internet_init -- initialize server, returning an internet socket that can
+ * be listened on.
+ */
+
+static int
+internet_init (void)
+{
+ int ls; /* socket descriptor */
+ struct sockaddr_in server; /* for local socket address */
+
+ if (setup_table () == 0)
+ return -1;
+
+ /* clear out address structure */
+ memset ((char *) &server, 0, sizeof (struct sockaddr_in));
+
+ /* Set up address structure for the listen socket. */
+ server.sin_family = AF_INET;
+ server.sin_addr.s_addr = INADDR_ANY;
+
+ /* We use a fixed port given in the config file. */
+ server.sin_port = htons (SERVER_PORT);
+
+ if (verbose_output)
+ syslog_message (LOG_INFO, "Using port %u.", SERVER_PORT);
+
+ /* Create the listen socket. */
+ if ((ls = socket (AF_INET, SOCK_STREAM, 0)) == -1) {
+ syslog_io_message (LOG_ERR, "unable to create socket");
+ exit (1);
+ }
+
+ /* Bind the listen address to the socket. */
+ if (bind (ls, (struct sockaddr *) &server,
+ sizeof (struct sockaddr_in)) == -1) {
+ syslog_io_message (LOG_ERR, "bind");
+ exit (1);
+ }
+
+ /* Initiate the listen on the socket so remote users * can connect. */
+ if (listen (ls, 20) == -1) {
+ syslog_io_message (LOG_ERR, "listen");
+ exit (1);
+ }
+
+ return (ls);
+} /* internet_init */
+
+
+/*
+ * handle_internet_request -- accept a request from a client and send the
+ * information to stdout (the gnu process).
+ */
+
+static void
+handle_internet_request (int ls)
+{
+ int s;
+ size_t addrlen = sizeof (struct sockaddr_in);
+ struct sockaddr_in peer; /* for peer socket address */
+ pid_t pid;
+
+ memset ((char *) &peer, 0, sizeof (struct sockaddr_in));
+
+ if ((s = accept (ls, (struct sockaddr *) &peer, (void *) &addrlen)) == -1) {
+ syslog_io_message (LOG_ERR, "accept");
+ exit (1);
+ }
+
+ if (verbose_output)
+ syslog_message (LOG_INFO, "Connection was made from %s port %u.",
+ inet_ntoa (peer.sin_addr), ntohs (peer.sin_port));
+
+ /* Check that access is allowed - if not return crud to the client */
+ if (!permitted (peer.sin_addr.s_addr, s)) {
+ close (s);
+ syslog_message (LOG_CRIT, "Refused connection from %s.",
+ inet_ntoa (peer.sin_addr));
+ return;
+ } /* if */
+
+ if (verbose_output)
+ syslog_message (LOG_INFO, "Accepted connection from %s port %u.",
+ inet_ntoa (peer.sin_addr), ntohs (peer.sin_port));
+
+ pid = fork ();
+
+ if (pid == -1) {
+ syslog_io_message (LOG_ERR, "fork failed");
+ exit (1);
+ }
+
+ if (pid) {
+ if (verbose_output)
+ syslog_message (LOG_INFO, "Child pid is %d.", pid);
+ return;
+ }
+
+ handle_parent_connection (s);
+
+ close (s);
+
+ if (verbose_output)
+ syslog_message (LOG_INFO, "Closed connection to %s port %u.",
+ inet_ntoa (peer.sin_addr), ntohs (peer.sin_port));
+
+ _exit (0);
+} /* handle_internet_request */
+
+static void
+handle_signal (int sig)
+{
+ if (sig == SIGCHLD)
+ return;
+
+ syslog_message (LOG_ERR, "Catched signal %d.\n", sig);
+ exit (1);
+}
+
+const struct poptOption popt_options [] = {
+ POPT_AUTOHELP
+ { "debug", 'd', POPT_ARG_NONE, &enable_debug, 0,
+ N_("Enable debugging"), N_("DEBUG") },
+ { "verbose", 'v', POPT_ARG_NONE, &verbose_output, 0,
+ N_("Enable verbose output"), N_("VERBOSE") },
+ { "no-daemon", 'f', POPT_ARG_NONE, &no_daemon, 0,
+ N_("Don't fork into background"), N_("NO-DAEMON") },
+ { "inetd", 'i', POPT_ARG_NONE, &invoked_from_inetd, 0,
+ N_("Invoked from inetd"), N_("INETD") },
+ { NULL, '\0', 0, NULL, 0 }
+};
+
+int
+main (int argc, char *argv [])
+{
+ const unsigned method = GLIBTOP_METHOD_PIPE;
+ const unsigned long features = GLIBTOP_SYSDEPS_ALL;
+ glibtop *server = glibtop_global_server;
+ poptContext context;
+ int nextopt;
+
+ int ils = -1; /* internet domain listen socket */
+
+ /* On non-glibc systems, this is not set up for us. */
+ if (!program_invocation_name) {
+ char *arg;
+
+ program_invocation_name = argv[0];
+ arg = strrchr (argv[0], '/');
+ program_invocation_short_name =
+ arg ? (arg + 1) : program_invocation_name;
+ }
+
+ context = poptGetContext ("libgtop-daemon", argc, argv,
+ popt_options, 0);
+
+ poptReadDefaultConfig (context, TRUE);
+
+ while ((nextopt = poptGetNextOpt (context)) > 0)
+ /* do nothing */ ;
+
+ if(nextopt != -1) {
+ printf (_("Error on option %s: %s.\n"
+ "Run '%s --help' to see a full list of "
+ "available command line options.\n"),
+ poptBadOption (context, 0),
+ poptStrerror (nextopt),
+ argv[0]);
+ exit(1);
+ }
+
+ if (enable_debug)
+ verbose_output = 1;
+
+ if (no_daemon) {
+ openlog ("libgtop-daemon", LOG_PERROR | LOG_PID, LOG_LOCAL0);
+ } else {
+ openlog ("libgtop-daemon", LOG_PID, LOG_LOCAL0);
+ }
+
+ if (!no_daemon && !invoked_from_inetd) {
+ pid_t pid = fork ();
+
+ if (pid == -1) {
+ syslog_io_message (LOG_ERR, "fork failed");
+ exit (1);
+ } else if (pid)
+ exit (0);
+
+ close (0);
+
+ setsid ();
+ }
+
+ glibtop_init_r (&glibtop_global_server, 0, GLIBTOP_INIT_NO_INIT);
+
+ signal (SIGCHLD, handle_signal);
+
+ /* If we are root, completely switch to SERVER_UID and
+ * SERVER_GID. Otherwise we completely drop any priviledges.
+ */
+
+ if (enable_debug)
+ syslog_message (LOG_DEBUG, "Parent ID: (%d, %d) - (%d, %d)",
+ getuid (), geteuid (), getgid (), getegid ());
+
+ if (geteuid () == 0) {
+ changed_uid = 1;
+ if (setregid (SERVER_GID, SERVER_GID)) {
+ syslog_io_message (LOG_ERR, "setregid (SERVER_GID)");
+ exit (1);
+ }
+ if (setreuid (SERVER_UID, SERVER_UID)) {
+ syslog_io_message (LOG_ERR, "setreuid (SERVER_UID)");
+ exit (1);
+ }
+ } else {
+ if (setreuid (geteuid (), geteuid ())) {
+ syslog_io_message (LOG_ERR, "setreuid (euid)");
+ exit (1);
+ }
+ }
+
+ if (enable_debug)
+ syslog_message (LOG_DEBUG, "Parent ID: (%d, %d) - (%d, %d)",
+ getuid (), geteuid (), getgid (), getegid ());
+
+ if (invoked_from_inetd) {
+ size_t addrlen = sizeof (struct sockaddr_in);
+ struct sockaddr_in peer;
+
+ memset ((char *) &peer, 0, sizeof (struct sockaddr_in));
+
+ if (getpeername (0, (struct sockaddr *) &peer, (void *) &addrlen)) {
+ syslog_io_message (LOG_ERR, "getpeername");
+ exit (1);
+ }
+
+ if (verbose_output)
+ syslog_message (LOG_INFO, "Connection was made from %s port %u.",
+ inet_ntoa (peer.sin_addr), ntohs (peer.sin_port));
+
+ /* Check that access is allowed - if not return crud to the client */
+ if (!permitted (peer.sin_addr.s_addr, 0)) {
+ close (0);
+ syslog_message (LOG_CRIT, "Refused connection from %s.",
+ inet_ntoa (peer.sin_addr));
+ exit (1);
+ }
+
+ handle_parent_connection (0);
+ exit (0);
+ }
+
+ /* get a internet domain socket to listen on. */
+ ils = internet_init ();
+
+ if (ils <= 0) {
+ syslog_message (LOG_ERR, "Unable to get internet domain socket.");
+ exit (1);
+ }
+
+ glibtop_set_parameter_l (server, GLIBTOP_PARAM_METHOD,
+ &method, sizeof (method));
+
+ server->features = features;
+
+ glibtop_init_r (&server, 0, 0);
+
+ while (1) {
+ fd_set rmask;
+ int status, ret;
+
+ while ((ret = wait3 (&status, WNOHANG, NULL)) != 0) {
+ if ((ret == -1) && (errno == ECHILD))
+ break;
+
+ if ((ret == -1) && ((errno == EAGAIN)))
+ continue;
+ if (ret == 0) {
+ syslog_io_message (LOG_WARNING, "wait3");
+ continue;
+ }
+
+ if (verbose_output)
+ syslog_message (LOG_INFO, "Child %d exited.", ret);
+ }
+
+ FD_ZERO (&rmask);
+
+ /* Only the child accepts connections from standard
+ * input made by its parent. */
+
+ FD_SET (ils, &rmask);
+
+ if (enable_debug)
+ syslog_message (LOG_DEBUG,
+ "Server ready and waiting for connections.");
+
+ if (select (ils+1, &rmask, (fd_set *) NULL, (fd_set *) NULL,
+ (struct timeval *) NULL) < 0) {
+ if (errno == EINTR)
+ continue;
+ syslog_io_message (LOG_ERR, "select");
+ exit (1);
+ }
+
+ if (FD_ISSET (ils, &rmask))
+ handle_internet_request (ils);
+ }
+
+ return 0;
+}
diff --git a/src/daemon/io.c b/src/daemon/io.c
new file mode 100644
index 00000000..aa38dd40
--- /dev/null
+++ b/src/daemon/io.c
@@ -0,0 +1,98 @@
+/* $Id$ */
+
+/* Copyright (C) 1998-99 Martin Baulig
+ This file is part of LibGTop 1.0.
+
+ Contributed by Martin Baulig <martin@home-of-linux.org>, April 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 "daemon.h"
+
+void
+do_output (int s, glibtop_response *resp, off_t offset,
+ size_t data_size, const void *data)
+{
+#ifdef REAL_DEBUG
+ fprintf (stderr, "Really writing %d bytes at offset %lu.\n",
+ sizeof (glibtop_response), offset);
+#endif
+
+ resp->offset = offset;
+ resp->data_size = data_size;
+
+ if (s == 0) {
+ if (write (1, (const void *) resp, sizeof (glibtop_response)) < 0)
+ glibtop_warn_io ("write");
+ } else {
+ if (send (s, (const void *) resp, sizeof (glibtop_response), 0) < 0)
+ glibtop_warn_io ("send");
+ }
+
+ if (resp->data_size) {
+#ifdef REAL_DEBUG
+ fprintf (stderr, "Writing %d bytes of data.\n", resp->data_size);
+#endif
+
+ if (s == 0) {
+ if (write (1, data, resp->data_size) < 0)
+ glibtop_warn_io ("write");
+ } else {
+ if (send (s, data, resp->data_size, 0) , 0)
+ glibtop_warn_io ("send");
+ }
+ }
+}
+
+int
+do_read (int s, void *ptr, size_t total_size)
+{
+ int nread;
+ char *tmp_ptr;
+ size_t already_read = 0, remaining = total_size;
+
+ while (already_read < total_size) {
+ if (s)
+ nread = recv (s, ptr, remaining, 0);
+ else
+ nread = read (0, ptr, remaining);
+
+ if ((already_read == 0) && (nread == 0)) {
+ glibtop_warn ("pid %d received eof.", getpid ());
+ return 0;
+ }
+
+ if (nread <= 0) {
+ glibtop_warn_io ("recv");
+ return 0;
+ }
+
+ already_read += nread;
+ remaining -= nread;
+ /* (char *) ptr += nread; */
+ tmp_ptr = ptr;
+ tmp_ptr += nread;
+ ptr = tmp_ptr;
+
+#ifdef REAL_DEBUG
+ fprintf (stderr, "READ (%d): %d - %d - %d\n",
+ nread, already_read, remaining, total_size);
+#endif
+ }
+
+ return already_read;
+}
diff --git a/src/daemon/main.c b/src/daemon/main.c
new file mode 100644
index 00000000..36154cfe
--- /dev/null
+++ b/src/daemon/main.c
@@ -0,0 +1,237 @@
+/* $Id$ */
+
+/* Copyright (C) 1998-99 Martin Baulig
+ This file is part of LibGTop 1.0.
+
+ Contributed by Martin Baulig <martin@home-of-linux.org>, April 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 "daemon.h"
+
+#ifdef LIBGTOP_ENABLE_DEBUG
+#ifndef PARENT_DEBUG
+#define PARENT_DEBUG 1
+#endif
+#ifndef DEBUG
+#define DEBUG 1
+#endif
+#endif
+
+void
+handle_parent_connection (int s)
+{
+ glibtop *server = glibtop_global_server;
+ glibtop_response _resp, *resp = &_resp;
+ glibtop_command _cmnd, *cmnd = &_cmnd;
+ glibtop_mountentry *mount_list;
+ char parameter [BUFSIZ];
+ unsigned short device;
+ int64_t *param_ptr;
+ int all_fs;
+ pid_t pid;
+ void *ptr;
+
+ glibtop_send_version (glibtop_global_server, s);
+
+ if (verbose_output)
+ syslog_message (LOG_INFO, "Parent features = %lu",
+ glibtop_server_features);
+
+ if (enable_debug)
+ syslog_message (LOG_DEBUG, "SIZEOF: %u - %u - %u - %u - %u - %u",
+ sizeof (glibtop_command), sizeof (glibtop_response),
+ sizeof (glibtop_mountentry), sizeof (glibtop_union),
+ sizeof (glibtop_sysdeps),
+ sizeof (glibtop_response_union));
+
+ while (do_read (s, cmnd, sizeof (glibtop_command))) {
+ if (enable_debug)
+ syslog_message (LOG_DEBUG,
+ "Parent (%d) received command %d from client.",
+ getpid (), (int) cmnd->command);
+
+ if (cmnd->data_size >= BUFSIZ) {
+ syslog_message (LOG_WARNING,
+ "Client sent %d bytes, but buffer is %d",
+ cmnd->data_size, BUFSIZ);
+ return;
+ }
+
+ memset (resp, 0, sizeof (glibtop_response));
+
+ memset (parameter, 0, sizeof (parameter));
+
+ if (cmnd->data_size) {
+ if (enable_debug)
+ syslog_message (LOG_DEBUG, "Client has %d bytes of data.",
+ (int) cmnd->data_size);
+
+ do_read (s, parameter, cmnd->data_size);
+
+ } else if (cmnd->size) {
+ memcpy (parameter, cmnd->parameter, cmnd->size);
+ }
+
+ switch (cmnd->command) {
+ case GLIBTOP_CMND_QUIT:
+ do_output (s, resp, 0, 0, NULL);
+ return;
+ case GLIBTOP_CMND_SYSDEPS:
+ memcpy (&resp->u.sysdeps, &server->sysdeps,
+ sizeof (glibtop_sysdeps));
+ resp->u.sysdeps.features = GLIBTOP_SYSDEPS_ALL;
+ do_output (s, resp, _offset_union (sysdeps), 0, NULL);
+ break;
+ case GLIBTOP_CMND_CPU:
+ glibtop_get_cpu_l (server, &resp->u.data.cpu);
+ do_output (s, resp, _offset_data (cpu), 0, NULL);
+ break;
+ case GLIBTOP_CMND_MEM:
+ glibtop_get_mem_l (server, &resp->u.data.mem);
+ do_output (s, resp, _offset_data (mem), 0, NULL);
+ break;
+ case GLIBTOP_CMND_SWAP:
+ glibtop_get_swap_l (server, &resp->u.data.swap);
+ do_output (s, resp, _offset_data (swap), 0, NULL);
+ break;
+ case GLIBTOP_CMND_UPTIME:
+ glibtop_get_uptime_l (server, &resp->u.data.uptime);
+ do_output (s, resp, _offset_data (uptime), 0, NULL);
+ break;
+ case GLIBTOP_CMND_LOADAVG:
+ glibtop_get_loadavg_l (server, &resp->u.data.loadavg);
+ do_output (s, resp, _offset_data (loadavg), 0, NULL);
+ break;
+ case GLIBTOP_CMND_SHM_LIMITS:
+ glibtop_get_shm_limits_l
+ (server, &resp->u.data.shm_limits);
+ do_output (s, resp, _offset_data (shm_limits), 0, NULL);
+ break;
+ case GLIBTOP_CMND_MSG_LIMITS:
+ glibtop_get_msg_limits_l
+ (server, &resp->u.data.msg_limits);
+ do_output (s, resp, _offset_data (msg_limits), 0, NULL);
+ break;
+ case GLIBTOP_CMND_SEM_LIMITS:
+ glibtop_get_sem_limits_l
+ (server, &resp->u.data.sem_limits);
+ do_output (s, resp, _offset_data (sem_limits), 0, NULL);
+ break;
+ case GLIBTOP_CMND_PROCLIST:
+ param_ptr = (int64_t *) parameter;
+ ptr = glibtop_get_proclist_l (server,
+ &resp->u.data.proclist,
+ param_ptr [0],
+ param_ptr [1]);
+ do_output (s, resp, _offset_data (proclist),
+ resp->u.data.proclist.total, ptr);
+ glibtop_free_r (server, ptr);
+ break;
+ case GLIBTOP_CMND_PROC_MAP:
+ memcpy (&pid, parameter, sizeof (pid_t));
+ ptr = glibtop_get_proc_map_l (server,
+ &resp->u.data.proc_map,
+ pid);
+ do_output (s, resp, _offset_data (proc_map),
+ resp->u.data.proc_map.total, ptr);
+ glibtop_free_r (server, ptr);
+ break;
+ case GLIBTOP_CMND_PROC_ARGS:
+ memcpy (&pid, parameter, sizeof (pid_t));
+ ptr = glibtop_get_proc_args_l (server,
+ &resp->u.data.proc_args,
+ pid, 0);
+ do_output (s, resp, _offset_data (proc_args),
+ ptr ? resp->u.data.proc_args.size+1 : 0, ptr);
+ glibtop_free_r (server, ptr);
+ break;
+ case GLIBTOP_CMND_PROC_STATE:
+ memcpy (&pid, parameter, sizeof (pid_t));
+ glibtop_get_proc_state_l
+ (server, &resp->u.data.proc_state, pid);
+ do_output (s, resp, _offset_data (proc_state), 0, NULL);
+ break;
+ case GLIBTOP_CMND_PROC_UID:
+ memcpy (&pid, parameter, sizeof (pid_t));
+ glibtop_get_proc_uid_l
+ (server, &resp->u.data.proc_uid, pid);
+ do_output (s, resp, _offset_data (proc_uid), 0, NULL);
+ break;
+ case GLIBTOP_CMND_PROC_MEM:
+ memcpy (&pid, parameter, sizeof (pid_t));
+ glibtop_get_proc_mem_l
+ (server, &resp->u.data.proc_mem, pid);
+ do_output (s, resp, _offset_data (proc_mem), 0, NULL);
+ break;
+ case GLIBTOP_CMND_PROC_TIME:
+ memcpy (&pid, parameter, sizeof (pid_t));
+ glibtop_get_proc_time_l
+ (server, &resp->u.data.proc_time, pid);
+ do_output (s, resp, _offset_data (proc_time), 0, NULL);
+ break;
+ case GLIBTOP_CMND_PROC_SIGNAL:
+ memcpy (&pid, parameter, sizeof (pid_t));
+ glibtop_get_proc_signal_l
+ (server, &resp->u.data.proc_signal, pid);
+ do_output (s, resp, _offset_data (proc_signal), 0, NULL);
+ break;
+ case GLIBTOP_CMND_PROC_KERNEL:
+ memcpy (&pid, parameter, sizeof (pid_t));
+ glibtop_get_proc_kernel_l
+ (server, &resp->u.data.proc_kernel, pid);
+ do_output (s, resp, _offset_data (proc_kernel), 0, NULL);
+ break;
+ case GLIBTOP_CMND_PROC_SEGMENT:
+ memcpy (&pid, parameter, sizeof (pid_t));
+ glibtop_get_proc_segment_l
+ (server, &resp->u.data.proc_segment, pid);
+ do_output (s, resp, _offset_data (proc_segment), 0, NULL);
+ break;
+ case GLIBTOP_CMND_MOUNTLIST:
+ memcpy (&all_fs, parameter, sizeof (all_fs));
+ mount_list = glibtop_get_mountlist_l
+ (server, &resp->u.data.mountlist, all_fs);
+ do_output (s, resp, _offset_data (mountlist),
+ resp->u.data.mountlist.total, mount_list);
+ glibtop_free_r (server, mount_list);
+ break;
+ case GLIBTOP_CMND_FSUSAGE:
+ glibtop_get_fsusage_l
+ (server, &resp->u.data.fsusage, parameter);
+ do_output (s, resp, _offset_data (fsusage),
+ 0, NULL);
+ break;
+ case GLIBTOP_CMND_PPP:
+ memcpy (&device, parameter, sizeof (device));
+ glibtop_get_ppp_l
+ (server, &resp->u.data.ppp, device);
+ do_output (s, resp, _offset_data (ppp), 0, NULL);
+ break;
+ case GLIBTOP_CMND_NETLOAD:
+ glibtop_get_netload_l
+ (server, &resp->u.data.netload, parameter);
+ do_output (s, resp, _offset_data (netload),
+ 0, NULL);
+ break;
+ default:
+ syslog_message (LOG_ERR, "Parent received unknown command %u.",
+ cmnd->command);
+ break;
+ }
+ }
+}
diff --git a/src/daemon/server.c b/src/daemon/server.c
new file mode 100644
index 00000000..0657d5e9
--- /dev/null
+++ b/src/daemon/server.c
@@ -0,0 +1,110 @@
+/* $Id$ */
+
+/* Copyright (C) 1998-99 Martin Baulig
+ This file is part of LibGTop 1.0.
+
+ Contributed by Martin Baulig <martin@home-of-linux.org>, April 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 "daemon.h"
+
+static glibtop _glibtop_global_server;
+glibtop *glibtop_global_server = &_glibtop_global_server;
+
+#include <glibtop.h>
+#include <glibtop/union.h>
+#include <glibtop/sysdeps.h>
+
+#include <sys/utsname.h>
+
+const unsigned long glibtop_server_features =
+GLIBTOP_SUID_CPU +
+GLIBTOP_SUID_MEM +
+GLIBTOP_SUID_SWAP +
+GLIBTOP_SUID_UPTIME +
+GLIBTOP_SUID_LOADAVG +
+GLIBTOP_SUID_SHM_LIMITS +
+GLIBTOP_SUID_MSG_LIMITS +
+GLIBTOP_SUID_SEM_LIMITS +
+GLIBTOP_SUID_PROCLIST +
+GLIBTOP_SUID_PROC_STATE +
+GLIBTOP_SUID_PROC_UID +
+GLIBTOP_SUID_PROC_MEM +
+GLIBTOP_SUID_PROC_TIME +
+GLIBTOP_SUID_PROC_SIGNAL +
+GLIBTOP_SUID_PROC_KERNEL +
+GLIBTOP_SUID_PROC_SEGMENT +
+GLIBTOP_SUID_PROC_ARGS +
+GLIBTOP_SUID_PROC_MAP +
+GLIBTOP_SUID_NETLOAD +
+GLIBTOP_SUID_PPP;
+
+#include <fcntl.h>
+#include <locale.h>
+
+int
+main(int argc, char *argv[])
+{
+ struct utsname uts;
+ int uid, euid, gid, egid;
+
+ /* !!! WE ARE ROOT HERE - CHANGE WITH CAUTION !!! */
+
+ uid = getuid (); euid = geteuid ();
+ gid = getgid (); egid = getegid ();
+
+ if (uname (&uts) < 0) _exit (1);
+
+#ifdef _AIX
+ /*
+ * [FIXME]: should be in sysdeps part ?
+ */
+
+ if ((strcmp (uts.sysname, LIBGTOP_COMPILE_SYSTEM) != 0) ||
+ ((atol(uts.version) < atol(LIBGTOP_COMPILE_VERSION)) &&
+ (atol(uts.release) < atol(LIBGTOP_COMPILE_RELEASE))) ) {
+ fprintf (stderr, "Can only run on %s %s.%s and upper\n",
+ LIBGTOP_COMPILE_SYSTEM,
+ LIBGTOP_COMPILE_VERSION,
+ LIBGTOP_COMPILE_RELEASE);
+ _exit (1);
+ }
+#else
+ if (strcmp (uts.sysname, LIBGTOP_COMPILE_SYSTEM) ||
+ strcmp (uts.release, LIBGTOP_COMPILE_RELEASE) ||
+ strcmp (uts.machine, LIBGTOP_COMPILE_MACHINE)) {
+ fprintf (stderr, "Can only run on %s %s %s\n",
+ LIBGTOP_COMPILE_SYSTEM,
+ LIBGTOP_COMPILE_RELEASE,
+ LIBGTOP_COMPILE_MACHINE);
+ _exit (1);
+ }
+#endif
+
+ glibtop_init_p (glibtop_global_server, 0, 0);
+
+ if (setreuid (euid, uid)) _exit (1);
+
+ if (setregid (egid, gid)) _exit (1);
+
+ /* !!! END OF SUID ROOT PART !!! */
+
+ handle_slave_connection (0, 0);
+
+ _exit (0);
+}
diff --git a/src/daemon/server_config.h b/src/daemon/server_config.h
new file mode 100644
index 00000000..09ae9ae8
--- /dev/null
+++ b/src/daemon/server_config.h
@@ -0,0 +1,11 @@
+#define SERVER_PORT 42800
+
+#define SERVER_UID 99
+#define SERVER_GID 99
+
+#define HOST_TABLE_ENTRIES 1
+
+const char *permitted_host_names [HOST_TABLE_ENTRIES] =
+{ NULL };
+
+unsigned long permitted_hosts [HOST_TABLE_ENTRIES];
diff --git a/src/daemon/server_config.h.in b/src/daemon/server_config.h.in
new file mode 100644
index 00000000..f7884c8d
--- /dev/null
+++ b/src/daemon/server_config.h.in
@@ -0,0 +1,44 @@
+/* -*-c-*- */
+
+/* This is a sample config file.
+ *
+ * Copy this file to 'server_config.h' and edit it to fix your needs !
+ *
+ * You can also use the 'server_config.pl' script to create 'server_config.h'.
+ *
+ */
+
+#define SERVER_PORT 42800 /* Port the server should listen on. */
+
+/* NOTE: On RedHat 5.1 nobody is UID 99 and GID 99.
+ *
+ * The 'server_config.pl' script will use the real UID and GID of 'nobody'
+ * on your system as default.
+ *
+ * NOTE: This only works if the server is started as root or SUID to root.
+ */
+
+#define SERVER_UID 99 /* User ID the server should run as. */
+#define SERVER_GID 99 /* Group ID the server should run as. */
+
+#define HOST_TABLE_ENTRIES 1 /* Number of entries in the host table. */
+
+/* List of hosts that should be authorized to connect to the server.
+ *
+ * SECURITY WARNING:
+ * Enabling access for a particular hosts means the ALL USERS on this host
+ * will be allowed to connect to the server !
+ *
+ * If you want security, let this table empty and use the 'xauth' method
+ * instead.
+ *
+ * Look at the manpage of gnuserv (1) as shipped with GNU Emacs for more
+ * details about security. The server uses the same security mechanisms
+ * like gnuserv from XEmacs 20.3.
+ */
+
+const char *permitted_host_names [HOST_TABLE_ENTRIES] =
+{ NULL };
+
+unsigned long permitted_hosts [HOST_TABLE_ENTRIES];
+
diff --git a/src/daemon/server_config.pl b/src/daemon/server_config.pl
new file mode 100755
index 00000000..3e78ca8f
--- /dev/null
+++ b/src/daemon/server_config.pl
@@ -0,0 +1,111 @@
+#!/usr/bin/perl -w
+
+require 5.004;
+use strict;
+
+print "Enter port the server should listen on [42800]: ";
+
+my $port = <stdin>; chop $port;
+$port = 42800 unless $port =~ /^\d+$/;
+
+print "\nUser name or UID to run as [nobody]: ";
+
+my $user = <stdin>; chop $user; $user = 'nobody' if $user eq '';
+
+my ($login, $pass, $uid, $gid);
+
+unless ($user =~ /^\d+$/) {
+ ($login, $pass, $uid, $gid) = getpwnam ($user) or
+ die "User '$user' not in passwd file.";
+}
+
+my $g_default = (defined $gid) ? $gid : 'nogroup';
+
+print "Group name or GID to run as [$g_default]: ";
+
+my $group = <stdin>; chop $group; $group = $g_default if $group eq '';
+
+unless ($group =~ /^\d+$/) {
+ $gid = getgrnam ($group) or
+ die "Group '$group' not in group file.";
+}
+
+print "\nEnter list of hosts which should be authorized to";
+print "\nconnect to the server (terminate with a blank line):\n\n";
+
+print "SECURITY WARNING:\n";
+print " Enabling access for a particular hosts means the ALL USERS on this host will\n";
+print " be allowed to connect to the server !\n\n";
+
+print " If you want security, let this table empty and use the 'xauth' method instead.\n";
+print " Look at the manpage of gnuserv (1) as shipped with GNU Emacs for more details\n";
+print " about security. The server uses the same security mechanisms like gnuserv from\n";
+print " XEmacs 20.3\n\n";
+
+my @hosts = ();
+my @host_addrs = ();
+my @host_names = ();
+
+while (1) {
+ print "Host: ";
+
+ my $host = <stdin>; chop $host;
+ last if $host eq '';
+
+ my ($name,$aliases,$addrtype,$length,@addrs) = gethostbyname ($host) or
+ die "gethostbyname (): Can't resolve '$host'";
+
+ my ($a,$b,$c,$d) = unpack('C4',$addrs[0]);
+
+ push @hosts, sprintf ("0x%02X%02X%02X%02X", $d, $c, $b, $a);
+ push @host_addrs, sprintf ("%d.%d.%d.%d", $a, $b, $c, $d);
+ push @host_names, $name;
+};
+
+print "\n";
+print "This is your config:\n";
+print "====================\n\n";
+
+printf qq[%-30s: %d\n\n], 'Port', $port;
+printf qq[%-30s: %d\n], 'UID', $uid;
+printf qq[%-30s: %d\n\n], 'GID', $gid;
+
+foreach (0..$#hosts) {
+ printf qq[%-30s (%s - %s)\n], $host_names[$_], $hosts[$_], $host_addrs [$_];
+}
+
+print "\n";
+
+print "Accept? (yes/no) ";
+
+my $accept = <stdin>; chop $accept;
+
+exit unless $accept eq 'yes';
+
+print "\n";
+
+open CONFIG, "> server_config.h" or
+ die "open (server_config.h): $!";
+select CONFIG;
+
+printf qq[\#define SERVER_PORT\t\t%d\n\n], $port;
+
+printf qq[\#define SERVER_UID\t\t%d\n], $uid;
+printf qq[\#define SERVER_GID\t\t%d\n\n], $gid;
+
+printf qq[\#define HOST_TABLE_ENTRIES\t%d\n\n], $#hosts + 1;
+
+foreach (@host_names) {
+ $_ = qq["$_"];
+}
+
+printf qq[const char *permitted_host_names [HOST_TABLE_ENTRIES] = \n];
+printf qq[{ %s };\n\n], join (', ', @host_names);
+
+printf qq[unsigned long permitted_hosts [HOST_TABLE_ENTRIES];\n];
+
+close CONFIG;
+
+select STDOUT;
+
+print "Your config has successfully been written to 'server_config.h'.\n";
diff --git a/src/daemon/slave.c b/src/daemon/slave.c
new file mode 100644
index 00000000..f8d5a492
--- /dev/null
+++ b/src/daemon/slave.c
@@ -0,0 +1,256 @@
+/* $Id$ */
+
+/* Copyright (C) 1998-99 Martin Baulig
+ This file is part of LibGTop 1.0.
+
+ Contributed by Martin Baulig <martin@home-of-linux.org>, April 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 "daemon.h"
+
+void
+handle_slave_connection (int input, int output)
+{
+ glibtop *server G_GNUC_UNUSED = glibtop_global_server;
+ int64_t *param_ptr G_GNUC_UNUSED;
+ const void *ptr G_GNUC_UNUSED;
+
+ unsigned short max_len G_GNUC_UNUSED;
+ pid_t pid G_GNUC_UNUSED;
+
+ glibtop_response _resp, *resp = &_resp;
+ glibtop_command _cmnd, *cmnd = &_cmnd;
+ char parameter [BUFSIZ];
+
+ glibtop_send_version (glibtop_global_server, output);
+
+ while (do_read (input, cmnd, sizeof (glibtop_command))) {
+#ifdef SLAVE_DEBUG
+ fprintf (stderr, "Slave %d received command "
+ "%d from client.\n", getpid (), cmnd->command);
+#endif
+
+ if (cmnd->data_size >= BUFSIZ)
+ glibtop_error ("Client sent %d bytes, "
+ "but buffer is %d",
+ cmnd->size, BUFSIZ);
+
+ memset (resp, 0, sizeof (glibtop_response));
+
+ memset (parameter, 0, sizeof (parameter));
+
+ if (cmnd->data_size) {
+#ifdef SLAVE_DEBUG
+ fprintf (stderr, "Client has %d bytes of data.\n",
+ cmnd->data_size);
+#endif
+
+ do_read (input, parameter, cmnd->data_size);
+
+ } else if (cmnd->size) {
+ memcpy (parameter, cmnd->parameter, cmnd->size);
+ }
+
+ switch (cmnd->command) {
+ case GLIBTOP_CMND_QUIT:
+ do_output (output, resp, 0, 0, NULL);
+ return;
+#if GLIBTOP_SUID_PROCLIST
+ case GLIBTOP_CMND_PROCLIST:
+ param_ptr = (int64_t *) parameter;
+ ptr = glibtop_get_proclist_p
+ (server, &resp->u.data.proclist,
+ param_ptr [0], param_ptr [1]);
+ do_output (output, resp, _offset_data (proclist),
+ resp->u.data.proclist.total, ptr);
+ glibtop_free_r (server, ptr);
+ break;
+#endif
+#if GLIBTOP_SUID_PROC_ARGS
+ case GLIBTOP_CMND_PROC_ARGS:
+ memcpy (&pid, parameter, sizeof (pid_t));
+ memcpy (&max_len, parameter + sizeof (pid_t),
+ sizeof (max_len));
+ ptr = glibtop_get_proc_args_p (server,
+ &resp->u.data.proc_args,
+ pid, max_len);
+ do_output (output, resp, _offset_data (proc_args),
+ ptr ? resp->u.data.proc_args.size+1 : 0,
+ ptr);
+ glibtop_free_r (server, ptr);
+ break;
+#endif
+#if GLIBTOP_SUID_PROC_MAP
+ case GLIBTOP_CMND_PROC_MAP:
+ memcpy (&pid, parameter, sizeof (pid_t));
+ ptr = glibtop_get_proc_map_p (server,
+ &resp->u.data.proc_map,
+ pid);
+ do_output (output, resp, _offset_data (proc_map),
+ resp->u.data.proc_map.total, ptr);
+ glibtop_free_r (server, ptr);
+ break;
+#endif
+ default:
+ handle_slave_command (cmnd, resp, parameter);
+ do_output (output, resp, resp->offset, 0, NULL);
+ break;
+ }
+ }
+}
+
+void
+handle_slave_command (glibtop_command *cmnd, glibtop_response *resp,
+ const void *parameter)
+{
+ glibtop *server = glibtop_global_server;
+ unsigned device G_GNUC_UNUSED;
+ pid_t pid G_GNUC_UNUSED;
+
+ switch (cmnd->command) {
+ case GLIBTOP_CMND_SYSDEPS:
+ memcpy (&resp->u.sysdeps, &server->sysdeps,
+ sizeof (glibtop_sysdeps));
+ resp->u.sysdeps.features = glibtop_server_features;
+ resp->u.sysdeps.flags = glibtop_server_features |
+ (1L << GLIBTOP_SYSDEPS_FEATURES);
+ resp->offset = _offset_union (sysdeps);
+ break;
+#if GLIBTOP_SUID_CPU
+ case GLIBTOP_CMND_CPU:
+ glibtop_get_cpu_p (server, &resp->u.data.cpu);
+ resp->offset = _offset_data (cpu);
+ break;
+#endif
+#if GLIBTOP_SUID_MEM
+ case GLIBTOP_CMND_MEM:
+ glibtop_get_mem_p (server, &resp->u.data.mem);
+ resp->offset = _offset_data (mem);
+ break;
+#endif
+#if GLIBTOP_SUID_SWAP
+ case GLIBTOP_CMND_SWAP:
+ glibtop_get_swap_p (server, &resp->u.data.swap);
+ resp->offset = _offset_data (swap);
+ break;
+#endif
+#if GLIBTOP_SUID_UPTIME
+ case GLIBTOP_CMND_UPTIME:
+ glibtop_get_uptime_p (server, &resp->u.data.uptime);
+ resp->offset = _offset_data (uptime);
+ break;
+#endif
+#if GLIBTOP_SUID_LOADAVG
+ case GLIBTOP_CMND_LOADAVG:
+ glibtop_get_loadavg_p (server, &resp->u.data.loadavg);
+ resp->offset = _offset_data (loadavg);
+ break;
+#endif
+#if GLIBTOP_SUID_SHM_LIMITS
+ case GLIBTOP_CMND_SHM_LIMITS:
+ glibtop_get_shm_limits_p (server, &resp->u.data.shm_limits);
+ resp->offset = _offset_data (shm_limits);
+ break;
+#endif
+#if GLIBTOP_SUID_MSG_LIMITS
+ case GLIBTOP_CMND_MSG_LIMITS:
+ glibtop_get_msg_limits_p (server, &resp->u.data.msg_limits);
+ resp->offset = _offset_data (msg_limits);
+ break;
+#endif
+#if GLIBTOP_SUID_SEM_LIMITS
+ case GLIBTOP_CMND_SEM_LIMITS:
+ glibtop_get_sem_limits_p (server, &resp->u.data.sem_limits);
+ resp->offset = _offset_data (sem_limits);
+ break;
+#endif
+#if GLIBTOP_SUID_PROC_STATE
+ case GLIBTOP_CMND_PROC_STATE:
+ memcpy (&pid, parameter, sizeof (pid_t));
+ glibtop_get_proc_state_p
+ (server, &resp->u.data.proc_state, pid);
+ resp->offset = _offset_data (proc_state);
+ break;
+#endif
+#if GLIBTOP_SUID_PROC_UID
+ case GLIBTOP_CMND_PROC_UID:
+ memcpy (&pid, parameter, sizeof (pid_t));
+ glibtop_get_proc_uid_p
+ (server, &resp->u.data.proc_uid, pid);
+ resp->offset = _offset_data (proc_uid);
+ break;
+#endif
+#if GLIBTOP_SUID_PROC_MEM
+ case GLIBTOP_CMND_PROC_MEM:
+ memcpy (&pid, parameter, sizeof (pid_t));
+ glibtop_get_proc_mem_p
+ (server, &resp->u.data.proc_mem, pid);
+ resp->offset = _offset_data (proc_mem);
+ break;
+#endif
+#if GLIBTOP_SUID_PROC_TIME
+ case GLIBTOP_CMND_PROC_TIME:
+ memcpy (&pid, parameter, sizeof (pid_t));
+ glibtop_get_proc_time_p
+ (server, &resp->u.data.proc_time, pid);
+ resp->offset = _offset_data (proc_time);
+ break;
+#endif
+#if GLIBTOP_SUID_PROC_SIGNAL
+ case GLIBTOP_CMND_PROC_SIGNAL:
+ memcpy (&pid, parameter, sizeof (pid_t));
+ glibtop_get_proc_signal_p
+ (server, &resp->u.data.proc_signal, pid);
+ resp->offset = _offset_data (proc_signal);
+ break;
+#endif
+#if GLIBTOP_SUID_PROC_KERNEL
+ case GLIBTOP_CMND_PROC_KERNEL:
+ memcpy (&pid, parameter, sizeof (pid_t));
+ glibtop_get_proc_kernel_p
+ (server, &resp->u.data.proc_kernel, pid);
+ resp->offset = _offset_data (proc_kernel);
+ break;
+#endif
+#if GLIBTOP_SUID_PROC_SEGMENT
+ case GLIBTOP_CMND_PROC_SEGMENT:
+ memcpy (&pid, parameter, sizeof (pid_t));
+ glibtop_get_proc_segment_p
+ (server, &resp->u.data.proc_segment, pid);
+ resp->offset = _offset_data (proc_segment);
+ break;
+#endif
+#if GLIBTOP_SUID_NETLOAD
+ case GLIBTOP_CMND_NETLOAD:
+ glibtop_get_netload_p (server, &resp->u.data.netload, parameter);
+ resp->offset = _offset_data (netload);
+ break;
+#endif
+#if GLIBTOP_SUID_PPP
+ case GLIBTOP_CMND_PPP:
+ memcpy (&device, parameter, sizeof (unsigned short));
+ glibtop_get_ppp_p (server, &resp->u.data.ppp, device);
+ resp->offset = _offset_data (ppp);
+ break;
+#endif
+ default:
+ glibtop_error ("Child received unknown command %u",
+ cmnd->command);
+ break;
+ }
+}
diff --git a/src/daemon/version.c b/src/daemon/version.c
new file mode 100644
index 00000000..d80d6412
--- /dev/null
+++ b/src/daemon/version.c
@@ -0,0 +1,62 @@
+/* $Id$ */
+
+/* Copyright (C) 1998-99 Martin Baulig
+ This file is part of LibGTop 1.0.
+
+ Contributed by Martin Baulig <martin@home-of-linux.org>, April 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 <glibtop.h>
+#include <glibtop/error.h>
+#include <glibtop/version.h>
+
+void
+glibtop_send_version (glibtop *server, int fd)
+{
+ char buffer [BUFSIZ];
+ size_t size;
+
+ sprintf (buffer, LIBGTOP_VERSION_STRING,
+ LIBGTOP_VERSION, LIBGTOP_SERVER_VERSION,
+ sizeof (glibtop_command),
+ sizeof (glibtop_response),
+ sizeof (glibtop_union),
+ sizeof (glibtop_sysdeps));
+
+ size = strlen (buffer) + 1;
+
+#ifdef DEBUG
+ fprintf (stderr, "SERVER ID: |%s|\n", buffer);
+#endif
+
+ if (fd == 0) {
+ if (write (1, (const void *) &size, sizeof (size)) < 0)
+ glibtop_warn_io_r (server, "write");
+ } else {
+ if (send (fd, (const void *) &size, sizeof (size), 0) < 0)
+ glibtop_warn_io_r (server, "send");
+ }
+
+ if (fd == 0) {
+ if (write (1, (const void *) buffer, size) < 0)
+ glibtop_warn_io_r (server, "write");
+ } else {
+ if (send (fd, (const void *) buffer, size, 0) < 0)
+ glibtop_warn_io_r (server, "send");
+ }
+}
diff --git a/src/inodedb/file_by_inode.c b/src/inodedb/file_by_inode2.c
index 5d87c7b1..8e4370fe 100644
--- a/src/inodedb/file_by_inode.c
+++ b/src/inodedb/file_by_inode2.c
@@ -1,5 +1,3 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-
/* $Id$ */
/* Copyright (C) 1998-99 Martin Baulig
@@ -35,33 +33,33 @@
int
main (int argc, const char *argv [])
{
- glibtop_inodedb *inodedb;
- const char *filename;
- unsigned device, inode;
+ glibtop_inodedb *inodedb;
+ const char *filename;
+ unsigned device, inode;
- if (argc != 3) {
- fprintf (stderr, "Usage: %s device inode\n", argv [0]);
- exit (1);
- }
+ if (argc != 3) {
+ fprintf (stderr, "Usage: %s device inode\n", argv [0]);
+ exit (1);
+ }
- if (sscanf (argv [1], "%d", &device) != 1) {
- fprintf (stderr, "Usage: %s device inode\n", argv [0]);
- exit (1);
- }
+ if (sscanf (argv [1], "%d", &device) != 1) {
+ fprintf (stderr, "Usage: %s device inode\n", argv [0]);
+ exit (1);
+ }
- if (sscanf (argv [2], "%d", &inode) != 1) {
- fprintf (stderr, "Usage: %s device inode\n", argv [0]);
- exit (1);
- }
+ if (sscanf (argv [2], "%d", &inode) != 1) {
+ fprintf (stderr, "Usage: %s device inode\n", argv [0]);
+ exit (1);
+ }
- inodedb = glibtop_inodedb_open (0, 0);
- if (!inodedb) exit (1);
+ inodedb = glibtop_inodedb_open (0, 0);
+ if (!inodedb) exit (1);
- filename = glibtop_inodedb_lookup (inodedb, device, inode);
- if (!filename) exit (2);
+ filename = glibtop_inodedb_lookup (inodedb, device, inode);
+ if (!filename) exit (2);
- fprintf (stderr, "FILENAME: %d - %d - '%s'\n",
- (int) device, (int) inode, filename);
+ fprintf (stderr, "FILENAME: %d - %d - '%s'\n",
+ (int) device, (int) inode, filename);
- exit (0);
+ exit (0);
}
diff --git a/src/inodedb/mkinodedb.c b/src/inodedb/mkinodedb.c
deleted file mode 100644
index 678b5ce7..00000000
--- a/src/inodedb/mkinodedb.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-
-/* $Id$ */
-
-/* Copyright (C) 1998-99 Martin Baulig
- This file is part of LibGTop 1.0.
-
- Contributed by Martin Baulig <martin@home-of-linux.org>, April 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 <glibtop.h>
-#include <glibtop/error.h>
-#include <glibtop/inodedb.h>
-
-#include <pwd.h>
-#include <dirent.h>
-
-#include <sys/stat.h>
-
-int
-main (int argc, char *argv [])
-{
- GDBM_FILE dbf;
- char dirname [BUFSIZ];
- FILE *f;
-
- if (argc != 3) {
- fprintf (stderr, "Usage: %s database filename\n", argv [0]);
- exit (1);
- }
-
- f = fopen (argv [2], "rt");
- if (!f)
- glibtop_error_io ("fopen (%s)", argv [2]);
-
- dbf = gdbm_open (argv [1], 512, GDBM_WRCREAT, 0600, 0);
- if (!dbf)
- glibtop_error_io ("gdbm_open (%s)", argv [1]);
-
- while (fgets (dirname, BUFSIZ-1, f)) {
- struct dirent *entry;
- struct stat statb;
- DIR *directory;
- size_t len;
-
- len = strlen (dirname);
- if (!len) continue;
-
- if (dirname [len-1] == '\n')
- dirname [len-1] = 0;
-
- if (stat (dirname, &statb))
- continue;
-
- if (S_ISREG (statb.st_mode)) {
- glibtop_inodedb_key key;
- datum d_key, d_content;
-
- d_key.dptr = (void *) &key;
- d_key.dsize = sizeof (key);
-
- d_content.dptr = dirname;
- d_content.dsize = strlen (dirname) + 1;
-
- key.device = (u_int64_t) statb.st_dev;
- key.inode = (u_int64_t) statb.st_ino;
-
- if (gdbm_store (dbf, d_key, d_content, GDBM_REPLACE))
- glibtop_error_io ("gdbm_store (%s)", dirname);
-
- printf ("%-52s - %8lu - %8lu\n",
- dirname, (unsigned long) statb.st_dev,
- (unsigned long) statb.st_ino);
-
- continue;
- }
-
- if (!S_ISDIR (statb.st_mode))
- continue;
-
- directory = opendir (dirname);
- if (!directory) continue;
-
- while ((entry = readdir (directory))) {
- glibtop_inodedb_key key;
- char filename [BUFSIZ];
- datum d_key, d_content;
-
- sprintf (filename, "%s/%s", dirname, entry->d_name);
-
- if (stat (filename, &statb))
- continue;
-
- if (!S_ISREG (statb.st_mode))
- continue;
-
- d_key.dptr = (void *) &key;
- d_key.dsize = sizeof (key);
-
- d_content.dptr = filename;
- d_content.dsize = strlen (filename) + 1;
-
- key.device = (u_int64_t) statb.st_dev;
- key.inode = (u_int64_t) statb.st_ino;
-
- if (gdbm_store (dbf, d_key, d_content, GDBM_REPLACE))
- glibtop_error_io ("gdbm_store (%s)", filename);
-
- printf ("%-52s - %8lu - %8lu\n",
- filename, (unsigned long) statb.st_dev,
- (unsigned long) statb.st_ino);
- }
-
- closedir (directory);
- }
-
- gdbm_close (dbf);
-
- fclose (f);
-
- exit (0);
-}
diff --git a/src/inodedb/mkinodedb2.c b/src/inodedb/mkinodedb2.c
new file mode 100644
index 00000000..a338d322
--- /dev/null
+++ b/src/inodedb/mkinodedb2.c
@@ -0,0 +1,135 @@
+/* $Id$ */
+
+/* Copyright (C) 1998-99 Martin Baulig
+ This file is part of LibGTop 1.0.
+
+ Contributed by Martin Baulig <martin@home-of-linux.org>, April 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 <glibtop.h>
+#include <glibtop/error.h>
+#include <glibtop/inodedb.h>
+
+#include <pwd.h>
+#include <dirent.h>
+
+#include <sys/stat.h>
+
+int
+main (int argc, char *argv [])
+{
+ GDBM_FILE dbf;
+ char dirname [BUFSIZ];
+ FILE *f;
+
+ if (argc != 3) {
+ fprintf (stderr, "Usage: %s database filename\n", argv [0]);
+ exit (1);
+ }
+
+ f = fopen (argv [2], "rt");
+ if (!f)
+ glibtop_error_io ("fopen (%s)", argv [2]);
+
+ dbf = gdbm_open (argv [1], 512, GDBM_WRCREAT, 0600, 0);
+ if (!dbf)
+ glibtop_error_io ("gdbm_open (%s)", argv [1]);
+
+ while (fgets (dirname, BUFSIZ-1, f)) {
+ struct dirent *entry;
+ struct stat statb;
+ DIR *directory;
+ size_t len;
+
+ len = strlen (dirname);
+ if (!len) continue;
+
+ if (dirname [len-1] == '\n')
+ dirname [len-1] = 0;
+
+ if (stat (dirname, &statb))
+ continue;
+
+ if (S_ISREG (statb.st_mode)) {
+ glibtop_inodedb_key key;
+ datum d_key, d_content;
+
+ d_key.dptr = (void *) &key;
+ d_key.dsize = sizeof (key);
+
+ d_content.dptr = dirname;
+ d_content.dsize = strlen (dirname) + 1;
+
+ key.device = (u_int64_t) statb.st_dev;
+ key.inode = (u_int64_t) statb.st_ino;
+
+ if (gdbm_store (dbf, d_key, d_content, GDBM_REPLACE))
+ glibtop_error_io ("gdbm_store (%s)", dirname);
+
+ printf ("%-52s - %8lu - %8lu\n",
+ dirname, (unsigned long) statb.st_dev,
+ (unsigned long) statb.st_ino);
+
+ continue;
+ }
+
+ if (!S_ISDIR (statb.st_mode))
+ continue;
+
+ directory = opendir (dirname);
+ if (!directory) continue;
+
+ while ((entry = readdir (directory))) {
+ glibtop_inodedb_key key;
+ char filename [BUFSIZ];
+ datum d_key, d_content;
+
+ sprintf (filename, "%s/%s", dirname, entry->d_name);
+
+ if (stat (filename, &statb))
+ continue;
+
+ if (!S_ISREG (statb.st_mode))
+ continue;
+
+ d_key.dptr = (void *) &key;
+ d_key.dsize = sizeof (key);
+
+ d_content.dptr = filename;
+ d_content.dsize = strlen (filename) + 1;
+
+ key.device = (u_int64_t) statb.st_dev;
+ key.inode = (u_int64_t) statb.st_ino;
+
+ if (gdbm_store (dbf, d_key, d_content, GDBM_REPLACE))
+ glibtop_error_io ("gdbm_store (%s)", filename);
+
+ printf ("%-52s - %8lu - %8lu\n",
+ filename, (unsigned long) statb.st_dev,
+ (unsigned long) statb.st_ino);
+ }
+
+ closedir (directory);
+ }
+
+ gdbm_close (dbf);
+
+ fclose (f);
+
+ exit (0);
+}