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.
This commit is contained in:
Carlos Perelló Marín
2003-10-19 16:55:56 +00:00
committed by Carlos Perelló Marín
parent bae16b467f
commit 4c8ae9e25c
380 changed files with 49862 additions and 8205 deletions

7
src/daemon/.cvsignore Normal file
View File

@@ -0,0 +1,7 @@
Makefile.in
Makefile
libgtop_daemon2
libgtop_server2
server.conf
.libs
.deps

104
src/daemon/ChangeLog Normal file
View File

@@ -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.

53
src/daemon/Makefile.am Normal file
View File

@@ -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@

81
src/daemon/daemon.h Normal file
View File

@@ -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

643
src/daemon/gnuserv.c Normal file
View File

@@ -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;
}

98
src/daemon/io.c Normal file
View File

@@ -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;
}

237
src/daemon/main.c Normal file
View File

@@ -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;
}
}
}

110
src/daemon/server.c Normal file
View File

@@ -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);
}

View File

@@ -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];

View File

@@ -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];

111
src/daemon/server_config.pl Executable file
View File

@@ -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";

256
src/daemon/slave.c Normal file
View File

@@ -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;
}
}

62
src/daemon/version.c Normal file
View File

@@ -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");
}
}

View File

@@ -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);
}

View File

@@ -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);
}

135
src/inodedb/mkinodedb2.c Normal file
View File

@@ -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);
}