From 3477d30dc5cbefcaa5a717c6f9aaffe6c3f46ef9 Mon Sep 17 00:00:00 2001 From: Martin Baulig Date: Mon, 13 Jul 1998 00:39:46 +0000 Subject: [PATCH] Basically did some work on the new daemon. Things are still unstable. 1998-07-13 Martin Baulig * glibtop.h: Fixed invocation of `glibtop_close_r'. * sysdeps/linux/procstate.c: Added missing `fclose'. * include/glibtop/gnuserv.h (UNIX_DOMAIN_SOCKETS): Defining. * include/glibtop/open.h (GLIBTOP_METHOD_UNIX): Added. * lib/init.c: Added new method `GLIBTOP_METHOD_UNIX'. * lib/open.c: Added support for Unix Domain Sockets. * lib/close.c: Now closing inet and unix connections. * lib/parameter.c (glibtop_set_parameter_l): You can now set the `method' and `features' fields. * src/daemon/server_config.h: New file. * src/daemon/{gnuserv.c, main.c}: More work on the server. --- ChangeLog | 23 ++ examples/first.c | 62 +++--- glibtop.h | 2 +- include/glibtop/gnuserv.h | 3 +- include/glibtop/open.h | 1 + lib/Makefile.am | 2 +- lib/close.c | 24 ++- lib/init.c | 31 +-- lib/open.c | 29 ++- lib/parameter.c | 18 ++ src/daemon/gnuserv.c | 415 +++++++++++++++++++------------------ src/daemon/main.c | 219 +++++++++++++++++-- src/daemon/server_config.h | 14 ++ sysdeps/linux/procstate.c | 4 +- 14 files changed, 572 insertions(+), 275 deletions(-) create mode 100644 src/daemon/server_config.h diff --git a/ChangeLog b/ChangeLog index 9f4354b6..0ed291db 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +1998-07-13 Martin Baulig + + * glibtop.h: Fixed invocation of `glibtop_close_r'. + + * sysdeps/linux/procstate.c: Added missing `fclose'. + + * include/glibtop/gnuserv.h (UNIX_DOMAIN_SOCKETS): Defining. + + * include/glibtop/open.h (GLIBTOP_METHOD_UNIX): Added. + + * lib/init.c: Added new method `GLIBTOP_METHOD_UNIX'. + + * lib/open.c: Added support for Unix Domain Sockets. + + * lib/close.c: Now closing inet and unix connections. + + * lib/parameter.c (glibtop_set_parameter_l): You can now + set the `method' and `features' fields. + + * src/daemon/server_config.h: New file. + + * src/daemon/{gnuserv.c, main.c}: More work on the server. + 1998-07-10 Martin Baulig * src/Makefile.am (SUBDIRS): Removed `proxy'. This directory diff --git a/examples/first.c b/examples/first.c index 79180446..115a8be2 100644 --- a/examples/first.c +++ b/examples/first.c @@ -32,7 +32,7 @@ #include #ifndef PROFILE_COUNT -#define PROFILE_COUNT 1 +#define PROFILE_COUNT 1000 #endif int @@ -68,14 +68,14 @@ main (int argc, char *argv []) printf ("Host = '%s' - %u\n\n", buffer, port); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_cpu (&data.cpu); printf ("CPU (0x%08lx): %lu, %lu, %lu, %lu, %lu, %lu\n", data.cpu.flags, data.cpu.total, data.cpu.user, data.cpu.nice, data.cpu.sys, data.cpu.idle, data.cpu.frequency); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_mem (&data.mem); printf ("Memory (0x%08lx): %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu\n", @@ -83,26 +83,26 @@ main (int argc, char *argv []) data.mem.shared, data.mem.buffer, data.mem.cached, data.mem.user, data.mem.locked); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_swap (&data.swap); printf ("Swap (0x%08lx): %lu, %lu, %lu\n", data.swap.flags, data.swap.total, data.swap.used, data.swap.free); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_uptime (&data.uptime); printf ("Uptime (0x%08lx): %f, %f\n", data.uptime.flags, data.uptime.uptime, data.uptime.idletime); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_loadavg (&data.loadavg); printf ("Loadavg (0x%08lx): %f, %f, %f\n", data.loadavg.flags, data.loadavg.loadavg [0], data.loadavg.loadavg [1], data.loadavg.loadavg [2]); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_shm_limits (&data.shm_limits); printf ("Shm Limits (0x%08lx): %ld, %ld, %ld, %ld, %ld\n", @@ -110,7 +110,7 @@ main (int argc, char *argv []) data.shm_limits.shmmin, data.shm_limits.shmmni, data.shm_limits.shmseg, data.shm_limits.shmall); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_msg_limits (&data.msg_limits); printf ("Msg Limits (0x%08lx): %ld, %ld, %ld, %ld, %ld, %ld, %ld\n", @@ -119,7 +119,7 @@ main (int argc, char *argv []) data.msg_limits.msgmnb, data.msg_limits.msgmni, data.msg_limits.msgssz, data.msg_limits.msgtql); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_sem_limits (&data.sem_limits); printf ("Sem Limits (0x%08lx): " @@ -167,7 +167,7 @@ main (int argc, char *argv []) printf ("\n"); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_state (&data.proc_state, pid); printf ("Proc_State PID %5u (0x%08lx): '%s', %c, %u, %u\n", @@ -175,7 +175,7 @@ main (int argc, char *argv []) data.proc_state.state, data.proc_state.uid, data.proc_state.gid); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_uid (&data.proc_uid, pid); printf ("Proc_Uid PID %5u (0x%08lx): " @@ -188,7 +188,7 @@ main (int argc, char *argv []) data.proc_uid.tpgid, data.proc_uid.priority, data.proc_uid.nice); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_mem (&data.proc_mem, pid); printf ("Proc_Mem PID %5u (0x%08lx): " @@ -197,7 +197,7 @@ main (int argc, char *argv []) data.proc_mem.resident, data.proc_mem.share, data.proc_mem.rss, data.proc_mem.rss_rlim); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_time (&data.proc_time, pid); printf ("Proc_Time PID %5u (0x%08lx): " @@ -207,7 +207,7 @@ main (int argc, char *argv []) data.proc_time.cstime, data.proc_time.timeout, data.proc_time.it_real_value); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_signal (&data.proc_signal, pid); printf ("Proc_Signal PID %5u (0x%08lx): " @@ -215,7 +215,7 @@ main (int argc, char *argv []) data.proc_signal.signal, data.proc_signal.blocked, data.proc_signal.sigignore, data.proc_signal.sigcatch); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_kernel (&data.proc_kernel, pid); printf ("Proc_Kernel PID %5u (0x%08lx): " @@ -226,7 +226,7 @@ main (int argc, char *argv []) data.proc_kernel.kstk_esp, data.proc_kernel.kstk_eip, data.proc_kernel.wchan); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_segment (&data.proc_segment, pid); printf ("Proc_Segment PID %5u (0x%08lx): " @@ -238,7 +238,7 @@ main (int argc, char *argv []) printf ("\n"); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_state (&data.proc_state, ppid); printf ("Proc_State PPID %5u (0x%08lx): '%s', %c, %u, %u\n", @@ -246,7 +246,7 @@ main (int argc, char *argv []) data.proc_state.state, data.proc_state.uid, data.proc_state.gid); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_uid (&data.proc_uid, ppid); printf ("Proc_Uid PPID %5u (0x%08lx): " @@ -259,7 +259,7 @@ main (int argc, char *argv []) data.proc_uid.tpgid, data.proc_uid.priority, data.proc_uid.nice); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_mem (&data.proc_mem, ppid); printf ("Proc_Mem PPID %5u (0x%08lx): " @@ -268,7 +268,7 @@ main (int argc, char *argv []) data.proc_mem.resident, data.proc_mem.share, data.proc_mem.rss, data.proc_mem.rss_rlim); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_time (&data.proc_time, ppid); printf ("Proc_Time PPID %5u (0x%08lx): " @@ -278,7 +278,7 @@ main (int argc, char *argv []) data.proc_time.cstime, data.proc_time.timeout, data.proc_time.it_real_value); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_signal (&data.proc_signal, ppid); printf ("Proc_Signal PPID %5u (0x%08lx): " @@ -286,7 +286,7 @@ main (int argc, char *argv []) data.proc_signal.signal, data.proc_signal.blocked, data.proc_signal.sigignore, data.proc_signal.sigcatch); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_kernel (&data.proc_kernel, ppid); printf ("Proc_Kernel PPID %5u (0x%08lx): " @@ -297,7 +297,7 @@ main (int argc, char *argv []) data.proc_kernel.kstk_esp, data.proc_kernel.kstk_eip, data.proc_kernel.wchan); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_segment (&data.proc_segment, ppid); printf ("Proc_Segment PPID %5u (0x%08lx): " @@ -309,7 +309,7 @@ main (int argc, char *argv []) printf ("\n"); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_state (&data.proc_state, 1); printf ("Proc_State INIT %5u (0x%08lx): '%s', %c, %u, %u\n", @@ -317,7 +317,7 @@ main (int argc, char *argv []) data.proc_state.state, data.proc_state.uid, data.proc_state.gid); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_uid (&data.proc_uid, 1); printf ("Proc_Uid INIT %5u (0x%08lx): " @@ -330,7 +330,7 @@ main (int argc, char *argv []) data.proc_uid.tpgid, data.proc_uid.priority, data.proc_uid.nice); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_mem (&data.proc_mem, 1); printf ("Proc_Mem INIT %5u (0x%08lx): " @@ -339,7 +339,7 @@ main (int argc, char *argv []) data.proc_mem.resident, data.proc_mem.share, data.proc_mem.rss, data.proc_mem.rss_rlim); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_time (&data.proc_time, 1); printf ("Proc_Time INIT %5u (0x%08lx): " @@ -349,7 +349,7 @@ main (int argc, char *argv []) data.proc_time.cstime, data.proc_time.timeout, data.proc_time.it_real_value); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_signal (&data.proc_signal, 1); printf ("Proc_Signal INIT %5u (0x%08lx): " @@ -357,7 +357,7 @@ main (int argc, char *argv []) data.proc_signal.signal, data.proc_signal.blocked, data.proc_signal.sigignore, data.proc_signal.sigcatch); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_kernel (&data.proc_kernel, 1); printf ("Proc_Kernel INIT %5u (0x%08lx): " @@ -368,7 +368,7 @@ main (int argc, char *argv []) data.proc_kernel.kstk_esp, data.proc_kernel.kstk_eip, data.proc_kernel.wchan); - for (c = 0; c < count; c++) + for (c = 0; c < PROFILE_COUNT; c++) glibtop_get_proc_segment (&data.proc_segment, 1); printf ("Proc_Segment INIT %5u (0x%08lx): " @@ -378,5 +378,7 @@ main (int argc, char *argv []) data.proc_segment.start_code, data.proc_segment.end_code, data.proc_segment.start_stack); + glibtop_close (); + exit (0); } diff --git a/glibtop.h b/glibtop.h index 9db6c74c..aa8e99b5 100644 --- a/glibtop.h +++ b/glibtop.h @@ -60,7 +60,7 @@ extern const unsigned long glibtop_server_features; #define glibtop_init() glibtop_init_r(&glibtop_global_server, 0, 0); -#define glibtop_close() glibtop_close_r(&glibtop_global_server); +#define glibtop_close() glibtop_close_r(glibtop_global_server); extern glibtop *glibtop_init_r __P((glibtop **, const unsigned long, const unsigned)); diff --git a/include/glibtop/gnuserv.h b/include/glibtop/gnuserv.h index 082637e4..6d1df518 100644 --- a/include/glibtop/gnuserv.h +++ b/include/glibtop/gnuserv.h @@ -54,9 +54,8 @@ static char header_rcsid [] = "!Header: gnuserv.h,v 2.4 95/02/16 11:58:11 arup a * sockets with sysv ipc */ - #define INTERNET_DOMAIN_SOCKETS -// #define UNIX_DOMAIN_SOCKETS +#define UNIX_DOMAIN_SOCKETS // #define SYSV_IPC /* diff --git a/include/glibtop/open.h b/include/glibtop/open.h index a891727d..0da35985 100644 --- a/include/glibtop/open.h +++ b/include/glibtop/open.h @@ -38,6 +38,7 @@ __BEGIN_DECLS #define GLIBTOP_METHOD_DIRECT 1 #define GLIBTOP_METHOD_PIPE 2 #define GLIBTOP_METHOD_INET 3 +#define GLIBTOP_METHOD_UNIX 4 extern void glibtop_open_l __P((glibtop *, const char *, const unsigned long, const unsigned)); diff --git a/lib/Makefile.am b/lib/Makefile.am index 87d16c29..32a555a9 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -4,7 +4,7 @@ INCLUDES = -I$(top_builddir) -I$(top_srcdir) @machine_incs@ \ -I$(top_srcdir)/include -I$(top_srcdir)/intl @GUILE_INCS@ \ -DGTOPLOCALEDIR=\"$(datadir)/locale\" -D_GNU_SOURCE -CFLAGS = -Wall -W @CFLAGS@ -DGTOP_SERVER=\""@LIBGTOP_SERVER@"\" -DDEBUG +CFLAGS = -Wall -W @CFLAGS@ -DGTOP_SERVER=\""@LIBGTOP_SERVER@"\" lib_LTLIBRARIES = libgtop.la diff --git a/lib/close.c b/lib/close.c index f4f0ba00..b5f60a51 100644 --- a/lib/close.c +++ b/lib/close.c @@ -19,14 +19,30 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include +#include #include +#include -/* Closes pipe to gtop server. */ +/* Closes server. */ void glibtop_close_r (glibtop *server) { - kill (server->pid, SIGKILL); - close (server->input [0]); - close (server->output [1]); + switch (server->method) { + case GLIBTOP_METHOD_UNIX: + case GLIBTOP_METHOD_INET: + glibtop_call_l (server, GLIBTOP_CMND_QUIT, + 0, NULL, 0, NULL); + + if (close (server->socket)) + glibtop_warn_io ("close"); + + break; + case GLIBTOP_METHOD_PIPE: + kill (server->pid, SIGKILL); + close (server->input [0]); + close (server->output [1]); + break; + } } diff --git a/lib/init.c b/lib/init.c index bc202c62..367d5e14 100644 --- a/lib/init.c +++ b/lib/init.c @@ -63,16 +63,11 @@ _init_server (glibtop *server, const unsigned features) if (server->server_command [0] != ':') { if (features & glibtop_server_features) { - /* We really need the server. */ - server->method = GLIBTOP_METHOD_PIPE; - } else { - /* Fine. No server is needed, so we call the * sysdeps functions directly. */ - server->method = GLIBTOP_METHOD_DIRECT; } @@ -92,21 +87,19 @@ _init_server (glibtop *server, const unsigned features) /* Dispatch method. */ if (!strcmp (command, "direct")) { - - /* Use sysdeps dir instead of connecting to server - * even if using the server would be required on - * the current system. */ - + /* Use sysdeps dir instead of connecting to server + * even if using the server would be required on + * the current system. */ server->method = GLIBTOP_METHOD_DIRECT; - + } else if (!strcmp (command, "inet")) { server->method = GLIBTOP_METHOD_INET; - /* Connect to internet server. */ + /* Connect to internet server. */ if (temp == NULL) { - /* If no value was set, we use 'localhost'. */ + /* If no value was set, we use 'localhost'. */ if (server->server_host == NULL) server->server_host = glibtop_strdup_r (server, "localhost"); @@ -114,7 +107,7 @@ _init_server (glibtop *server, const unsigned features) char *temp2 = strstr (temp+1, ":"); if (temp2) *temp2 = 0; - /* Override default. */ + /* Override default. */ if (server->server_host) glibtop_free_r (server, (char *) server->server_host); @@ -125,7 +118,7 @@ _init_server (glibtop *server, const unsigned features) } if (temp == NULL) { - /* If no value was set, we use DEFAULT_PORT. */ + /* If no value was set, we use DEFAULT_PORT. */ if (server->server_port == 0) server->server_port = DEFAULT_PORT; } else { @@ -137,9 +130,17 @@ _init_server (glibtop *server, const unsigned features) temp = temp2 ? temp2 + 1 : temp2; } + + } else if (!strcmp (command, "unix")) { + + /* Connect to unix domain socket. */ + server->method = GLIBTOP_METHOD_UNIX; + } else { + glibtop_error_r (server, "Unknown server method '%s'", server->server_command+1); + } glibtop_free_r (server, command); diff --git a/lib/open.c b/lib/open.c index 1bf95032..783744ab 100644 --- a/lib/open.c +++ b/lib/open.c @@ -33,6 +33,8 @@ void glibtop_open_l (glibtop *server, const char *program_name, const unsigned long features, const unsigned flags) { + int connect_type; + server->name = program_name; /* It is important to set _GLIBTOP_INIT_STATE_OPEN here when we @@ -40,19 +42,33 @@ glibtop_open_l (glibtop *server, const char *program_name, server->flags |= _GLIBTOP_INIT_STATE_OPEN; - if (server->method == GLIBTOP_METHOD_INET) { - int connect_type; - - fprintf (stderr, "Connecting to '%s' port %d.\n", + switch (server->method) { + case GLIBTOP_METHOD_INET: + fprintf (stderr, "Connecting to '%s' port %ld.\n", server->server_host, server->server_port); connect_type = glibtop_make_connection (server->server_host, server->server_port, &server->socket); + + fprintf (stderr, "Connect Type is %d.\n", connect_type); + + server->flags |= _GLIBTOP_INIT_STATE_SERVER; server->features = -1; + break; + case GLIBTOP_METHOD_UNIX: + fprintf (stderr, "Connecting to Unix Domain Socket.\n"); - return; + connect_type = glibtop_make_connection + ("unix", 0, &server->socket); + + fprintf (stderr, "Connect Type is %d.\n", connect_type); + + server->flags |= _GLIBTOP_INIT_STATE_SERVER; + + server->features = -1; + break; } /* If the server has been started, ask it for its features. */ @@ -64,5 +80,8 @@ glibtop_open_l (glibtop *server, const char *program_name, sizeof (glibtop_sysdeps), &sysdeps); server->features = sysdeps.features; + + fprintf (stderr, "Server features are %lu.\n", + server->features); } } diff --git a/lib/parameter.c b/lib/parameter.c index ca3c5d0c..8d6403e3 100644 --- a/lib/parameter.c +++ b/lib/parameter.c @@ -28,6 +28,14 @@ memcpy (data_ptr, ptr, size); \ return size; +#define _check_data(size) \ + if ((data_ptr == NULL) || (data_size != size)) { \ + glibtop_error_r (server, "glibtop_set_parameter (%d): " \ + "Expected %lu bytes but got %lu.", \ + parameter, size, data_size); \ + return; \ + } + #define _strlen(ptr) (ptr ? strlen (ptr) : 0) size_t @@ -59,4 +67,14 @@ void glibtop_set_parameter_l (glibtop *server, const unsigned parameter, const void *data_ptr, size_t data_size) { + switch (parameter) { + case GLIBTOP_PARAM_METHOD: + _check_data (sizeof (server->method)); + memcpy (&server->method, data_ptr, data_size); + break; + case GLIBTOP_PARAM_FEATURES: + _check_data (sizeof (server->features)); + memcpy (&server->features, data_ptr, data_size); + break; + } } diff --git a/src/daemon/gnuserv.c b/src/daemon/gnuserv.c index c84bb87f..4e40e4d2 100644 --- a/src/daemon/gnuserv.c +++ b/src/daemon/gnuserv.c @@ -29,21 +29,25 @@ * ../etc/gnuserv.README relative to the directory containing this file) */ -#if 0 static char rcsid[] = "!Header: gnuserv.c,v 2.1 95/02/16 11:58:27 arup alpha !"; -#endif +#include +#include +#include -#define DEBUG +#include "server_config.h" #include -#include + +#include +#include #ifdef AIX #include #endif -extern void handle_socket_connection __P ((glibtop *, int)); +extern void handle_parent_connection __P ((glibtop *, int)); +extern void handle_child_connection __P ((glibtop *, int)); #if !defined(SYSV_IPC) && !defined(UNIX_DOMAIN_SOCKETS) && !defined(INTERNET_DOMAIN_SOCKETS) main () @@ -148,6 +152,7 @@ ipc_init (struct msgbuf **msgpp) void handle_ipc_request (struct msgbuf *msgp) { +#if 0 struct msqid_ds msg_st; /* message status */ char buf[GSERV_BUFSZ]; int len; /* length of message / read */ @@ -224,106 +229,14 @@ handle_ipc_request (struct msgbuf *msgp) msgp->mtype = msg_st.msg_lspid; if (msgsnd (ipc_qid, msgp, strlen (msgp->mtext) + 1, 0) < 0) glibtop_warn_io ("msgsend(gnuserv)"); - +#else + glibtop_error ("handle_ipc_request (): Function not implemented"); +#endif } /* handle_ipc_request */ #endif /* SYSV_IPC */ -#if defined(INTERNET_DOMAIN_SOCKETS) || defined(UNIX_DOMAIN_SOCKETS) -/* - * echo_request -- read request from a given socket descriptor, and send the information - * to stdout (the gnu process). - */ -static void -echo_request (int s) -{ - char buf[GSERV_BUFSZ]; - int len; - - printf ("%d ", s); - - /* read until we get a newline or no characters */ - while ((len = recv (s, buf, GSERV_BUFSZ - 1, 0)) > 0) { - buf[len] = '\0'; - printf ("%s", buf); - - if (buf[len - 1] == EOT_CHR) { - fflush (stdout); - break; /* end of message */ - } - } /* while */ - - if (len < 0) - glibtop_error_io ("recv"); - -} /* echo_request */ - - -/* - * handle_response -- accept a response from stdin (the gnu process) and pass the - * information on to the relevant client. - */ -static void -handle_response (void) -{ -#if 0 - char buf[GSERV_BUFSZ + 1]; - int offset = 0; - int s; - int len; - int result_len; - - /* read in "n/m:" (n=client fd, m=message length) */ - while (offset < GSERV_BUFSZ && - ((len = read (0, buf + offset, 1)) > 0) && - buf[offset] != ':') { - offset += len; - } - - if (len < 0) - glibtop_error_io ("read"); - - /* parse the response from emacs, getting client fd & result length */ - buf[offset] = '\0'; - sscanf (buf, "%d/%d", &s, &result_len); - - while (result_len > 0) { - if ((len = read (0, buf, min2 (result_len, GSERV_BUFSZ))) < 0) - glibtop_error_io ("read"); - - buf[len] = '\0'; - send_string (s, buf); - result_len -= len; - } - - /* eat the newline */ - while ((len = read (0, buf, 1)) == 0); - if (len < 0) - glibtop_error_io ("read"); - - if (buf[0] != '\n') - glibtop_error ("garbage after result"); - - /* send the newline */ - buf[1] = '\0'; - send_string (s, buf); - close (s); -#else - glibtop_error ("handle_response (): Function not implemented"); -#endif - -} /* handle_response */ - -#endif /* INTERNET_DOMAIN_SOCKETS || UNIX_DOMAIN_SOCKETS */ - - #ifdef INTERNET_DOMAIN_SOCKETS -struct entry { - u_long host_addr; - struct entry *next; -}; - -struct entry *permitted_hosts[TABLE_SIZE]; #ifdef AUTH_MAGIC_COOKIE #include @@ -383,8 +296,7 @@ timed_read (int fd, char *buf, int max, int timeout, int one_line) static int permitted (u_long host_addr, int fd) { - int key; - struct entry *entry; + int i; char auth_protocol[128]; char buf[1024]; @@ -445,49 +357,24 @@ permitted (u_long host_addr, int fd) } /* Now, try the old GNU_SECURE stuff... */ - /* First find the hash key */ - key = HASH (host_addr) % TABLE_SIZE; - #ifdef DEBUG fprintf (stderr, "Doing GNU_SECURE auth ...\n"); #endif /* Now check the chain for that hash key */ - for (entry = permitted_hosts[key]; entry != NULL; entry = entry->next) { + for (i = 0; i < HOST_TABLE_ENTRIES; i++) { #ifdef DEBUG - fprintf (stderr, "Trying %ld\n", entry->host_addr); + fprintf (stderr, "Trying %lx - %lx\n", + host_addr, permitted_hosts [i]); #endif - if (host_addr == entry->host_addr) + if (host_addr == permitted_hosts [i]) return (TRUE); } return (FALSE); - } /* permitted */ -/* - * add_host -- add the given host to the list of permitted hosts, provided it isn't - * already there. - */ -static void -add_host (u_long host_addr) -{ - int key; - struct entry *new_entry; - - if (!permitted (host_addr, -1)) { - if ((new_entry = (struct entry *) malloc (sizeof (struct entry))) == NULL) - glibtop_error_io ("unable to malloc space for permitted host entry"); - - new_entry->host_addr = host_addr; - key = HASH (host_addr) % TABLE_SIZE; - new_entry->next = permitted_hosts[key]; - permitted_hosts[key] = new_entry; - } /* if */ -} /* add_host */ - - /* * setup_table -- initialise the table of hosts allowed to contact the server, * by reading from the file specified by the GNU_SECURE @@ -499,54 +386,53 @@ add_host (u_long host_addr) static int setup_table (void) { - FILE *host_file; - char *file_name; - char hostname[HOSTNAMSZ]; + char hostname [HOSTNAMSZ]; u_int host_addr; int i, hosts = 0; /* Make sure every entry is null */ - for (i = 0; i < TABLE_SIZE; i++) - permitted_hosts[i] = NULL; + for (i = 0; i < HOST_TABLE_ENTRIES; i++) + permitted_hosts [i] = 0; gethostname (hostname, HOSTNAMSZ); if (((long) host_addr = glibtop_internet_addr (hostname)) == -1) - glibtop_error ("unable to find %s in /etc/hosts or from YP", hostname); + glibtop_error ("Can't resolve '%s'", hostname); #ifdef AUTH_MAGIC_COOKIE - server_xauth = XauGetAuthByAddr (FamilyInternet, - sizeof (host_addr), (char *) &host_addr, - strlen (MCOOKIE_SCREEN), MCOOKIE_SCREEN, - strlen (MCOOKIE_X_NAME), MCOOKIE_X_NAME); + server_xauth = XauGetAuthByAddr + (FamilyInternet, + sizeof (host_addr), (char *) &host_addr, + strlen (MCOOKIE_SCREEN), MCOOKIE_SCREEN, + strlen (MCOOKIE_X_NAME), MCOOKIE_X_NAME); hosts++; #endif /* AUTH_MAGIC_COOKIE */ + /* Resolv host names from permitted_host_names []. */ -#if 0 /* Don't even want to allow access from the - * local host by default */ - add_host (host_addr); /* add local host */ - hosts++; + for (i = 0; i < HOST_TABLE_ENTRIES; i++) { +#ifdef DEBUG + fprintf (stderr, "Resolving %s ...\n", + permitted_host_names [i]); +#endif + permitted_hosts [i] = + glibtop_internet_addr (permitted_host_names [i]); + if ((long) permitted_hosts [i] == -1) + glibtop_error ("Can't resolve '%s'", + permitted_host_names [i]); + } + +#ifdef DEBUG + for (i = 0; i < HOST_TABLE_ENTRIES; i++) + fprintf (stderr, "Host %s - %lx\n", + permitted_host_names [i], + permitted_hosts [i]); #endif - if (((file_name = getenv ("GNU_SECURE")) != NULL && /* security - * file */ - (host_file = fopen (file_name, "r")) != NULL)) { /* opened ok */ - while ((fscanf (host_file, "%s", hostname) != EOF)) /* find - * a - * host - */ - if (((long) host_addr = glibtop_internet_addr (hostname)) != -1) { /* get - * its - * addr - */ - add_host (host_addr); /* add the addr */ - hosts++; - } - fclose (host_file); - } /* if */ + hosts += HOST_TABLE_ENTRIES; + return hosts; } /* setup_table */ @@ -559,9 +445,7 @@ static int internet_init (void) { int ls; /* socket descriptor */ - struct servent *sp; /* pointer to service information */ struct sockaddr_in server; /* for local socket address */ - char *ptr; /* ptr to return from getenv */ if (setup_table () == 0) return -1; @@ -573,19 +457,15 @@ internet_init (void) server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; - /* Find the information for the gnu server * in order to get the - * needed port number. */ - if ((ptr = getenv ("GNU_PORT")) != NULL) - server.sin_port = htons (atoi (ptr)); - else if ((sp = getservbyname ("gnuserv", "tcp")) == NULL) - server.sin_port = htons (DEFAULT_PORT + getuid ()); - else - server.sin_port = sp->s_port; + /* We use a fixed port given in the config file. */ + server.sin_port = htons (SERVER_PORT); + + fprintf (stderr, "Using port %u.\n", server.sin_port); /* Create the listen socket. */ if ((ls = socket (AF_INET, SOCK_STREAM, 0)) == -1) glibtop_error_io ("unable to create socket"); - + /* Bind the listen address to the socket. */ if (bind (ls, (struct sockaddr *) &server, sizeof (struct sockaddr_in)) == -1) glibtop_error_io ("bind"); @@ -595,7 +475,6 @@ internet_init (void) glibtop_error_io ("listen"); return (ls); - } /* internet_init */ @@ -609,6 +488,7 @@ 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)); @@ -625,18 +505,30 @@ handle_internet_request (int ls) glibtop_warn ("Refused connection from %s.", inet_ntoa (peer.sin_addr)); return; } /* if */ + #ifdef DEBUG - fprintf (stderr, "Accepted connection from %s.\n", inet_ntoa (peer.sin_addr)); + fprintf (stderr, "Accepted connection from %s (%u) on socket %d.\n", + inet_ntoa (peer.sin_addr), ntohs (peer.sin_port), s); #endif - handle_socket_connection (&glibtop_global_server, s); + pid = fork (); + + if (pid == -1) + glibtop_error_io ("fork failed"); + + if (pid) + return; + + handle_parent_connection (glibtop_global_server, s); close (s); - + #ifdef DEBUG - fprintf (stderr, "Closed connection to %s.\n", inet_ntoa (peer.sin_addr)); + fprintf (stderr, "Closed connection to %s (%d).\n", + inet_ntoa (peer.sin_addr), ntohs (peer.sin_port)); #endif + _exit (0); } /* handle_internet_request */ #endif /* INTERNET_DOMAIN_SOCKETS */ @@ -657,12 +549,14 @@ unix_init (void) glibtop_error_io ("unable to create socket"); /* Set up address structure for the listen socket. */ + #ifdef HIDE_UNIX_SOCKET sprintf (server.sun_path, "/tmp/lgtddir%d", (int) geteuid ()); if (mkdir (server.sun_path, 0700) < 0) { /* assume it already exists, and try to set perms */ if (chmod (server.sun_path, 0700) < 0) - glibtop_error_io ("Can't set permissions on %s", server.sun_path); + glibtop_error_io ("Can't set permissions on %s", + server.sun_path); } strcat (server.sun_path, "/lgtd"); unlink (server.sun_path); /* remove old file if it exists */ @@ -705,7 +599,6 @@ unix_init (void) #endif return (ls); - } /* unix_init */ @@ -719,27 +612,52 @@ handle_unix_request (int ls) int s; size_t len = sizeof (struct sockaddr_un); struct sockaddr_un server; /* for unix socket address */ + pid_t pid; server.sun_family = AF_UNIX; if ((s = accept (ls, (struct sockaddr *) &server, (void *) &len)) < 0) glibtop_error_io ("accept"); - echo_request (s); +#ifdef DEBUG + fprintf (stderr, "Accepted connection on socket %d.\n", s); +#endif + pid = fork (); + + if (pid == -1) + glibtop_error_io ("fork failed"); + + if (pid) + return; + + handle_child_connection (glibtop_global_server, s); + + close (s); + +#ifdef DEBUG + fprintf (stderr, "Closed connection on socket %d.\n", s); +#endif + + glibtop_close_r (glibtop_global_server); + + exit (0); } /* handle_unix_request */ #endif /* UNIX_DOMAIN_SOCKETS */ +void +handle_signal (int sig) +{ + fprintf (stderr, "Catched signal %d.\n", sig); +} int -main (argc, argv) - int argc; - char *argv[]; +main (int argc, char *argv []) { - int chan; /* temporary channel number */ int ils = -1; /* internet domain listen socket */ int uls = -1; /* unix domain listen socket */ + pid_t pid; #ifdef SYSV_IPC struct msgbuf *msgp; /* message buffer */ @@ -748,31 +666,127 @@ main (argc, argv) glibtop_init_r (&glibtop_global_server, 0, GLIBTOP_OPEN_NO_OVERRIDE); - for (chan = 3; chan < _NFILE; close (chan++)) /* close unwanted - * channels */ - ; + /* Fork a child. + * + * The parent will listen for incoming internet connections + * and the child will listen for connections from the local + * host using unix domain name sockets or SysV IPC. + */ + + signal (SIGCHLD, handle_signal); + + pid = fork (); + + if (pid == -1) + glibtop_error_io ("fork failed"); + else if (pid == 0) { + /* We are the child. */ + + /* Temporarily drop our priviledges. */ + + fprintf (stderr, "Child ID: (%d, %d) - (%d, %d)\n", + getuid (), geteuid (), getgid (), getegid ()); + + if (setreuid (geteuid (), getuid ())) + glibtop_error_io ("setreuid (euid <-> uid)"); + + if (setregid (getegid (), getgid ())) + glibtop_error_io ("setregid (egid <-> gid)"); + + fprintf (stderr, "Child ID: (%d, %d) - (%d, %d)\n", + getuid (), geteuid (), getgid (), getegid ()); #ifdef SYSV_IPC - ipc_init (&msgp); /* get a msqid to listen on, and a message - * buffer */ + /* get a msqid to listen on, and a message buffer. */ + ipc_init (&msgp); #endif /* SYSV_IPC */ -#ifdef INTERNET_DOMAIN_SOCKETS - ils = internet_init (); /* get a internet domain socket to listen on */ -#endif /* INTERNET_DOMAIN_SOCKETS */ - #ifdef UNIX_DOMAIN_SOCKETS - uls = unix_init (); /* get a unix domain socket to listen on */ + /* get a unix domain socket to listen on. */ + uls = unix_init (); #endif /* UNIX_DOMAIN_SOCKETS */ + } else { + /* We are the parent. */ + + /* If we are root, completely switch to SERVER_UID and + * SERVER_GID. Otherwise we completely drop any priviledges. + */ + +#ifdef DEBUG + fprintf (stderr, "Parent ID: (%d, %d) - (%d, %d)\n", + getuid (), geteuid (), getgid (), getegid ()); +#endif + + if (setreuid (geteuid (), getuid ())) + glibtop_error_io ("setreuid (euid <-> uid)"); + + if (setregid (getegid (), getgid ())) + glibtop_error_io ("setregid (egid <-> gid)"); + +#ifdef DEBUG + fprintf (stderr, "Parent ID: (%d, %d) - (%d, %d)\n", + getuid (), geteuid (), getgid (), getegid ()); +#endif + + if ((geteuid () == 0) || (getuid () == 0)) { + if (setreuid (0, 0)) + glibtop_error_io ("setreuid (root)"); + } + +#ifdef DEBUG + fprintf (stderr, "Parent ID: (%d, %d) - (%d, %d)\n", + getuid (), geteuid (), getgid (), getegid ()); +#endif + + if (geteuid () == 0) { + if (setregid (SERVER_GID, SERVER_GID)) + glibtop_error_io ("setregid (SERVER_GID)"); + if (setreuid (SERVER_UID, SERVER_UID)) + glibtop_error_io ("setreuid (SERVER_UID)"); + } else { + if (setreuid (geteuid (), geteuid ())) + glibtop_error_io ("setreuid (euid)"); + } + +#ifdef DEBUG + fprintf (stderr, "Parent ID: (%d, %d) - (%d, %d)\n", + getuid (), geteuid (), getgid (), getegid ()); +#endif + +#ifdef INTERNET_DOMAIN_SOCKETS + /* get a internet domain socket to listen on. */ + ils = internet_init (); +#endif /* INTERNET_DOMAIN_SOCKETS */ + } while (1) { #ifdef SYSV_IPC handle_ipc_request (msgp); #else /* NOT SYSV_IPC */ fd_set rmask; + int ret; + while ((ret = wait3 (NULL, WNOHANG, NULL)) != 0) { + if ((ret == -1) && (errno == ECHILD)) + break; + + if ((ret == -1) && ((errno == EAGAIN) || + (errno == ERESTART))) + continue; + if (ret > 0) + fprintf (stderr, "Child %d exited.\n", ret); + else + glibtop_warn_io ("wait3: %d", ret); + } + FD_ZERO (&rmask); - FD_SET (fileno (stdin), &rmask); + + /* Only the child accepts connections from standard + * input made by its parent. */ + + if (pid == 0) + FD_SET (fileno (stdin), &rmask); + if (uls >= 0) FD_SET (uls, &rmask); if (ils >= 0) @@ -783,8 +797,12 @@ main (argc, argv) #endif if (select (max2 (fileno (stdin), max2 (uls, ils)) + 1, &rmask, - (fd_set *) NULL, (fd_set *) NULL, (struct timeval *) NULL) < 0) + (fd_set *) NULL, (fd_set *) NULL, + (struct timeval *) NULL) < 0) { + if (errno == EINTR) + continue; glibtop_error_io ("select"); + } #ifdef UNIX_DOMAIN_SOCKETS if (uls > 0 && FD_ISSET (uls, &rmask)) @@ -796,9 +814,8 @@ main (argc, argv) handle_internet_request (ils); #endif /* INTERNET_DOMAIN_SOCKETS */ - if (FD_ISSET (fileno (stdin), &rmask)) /* from stdin (gnu - * process) */ - handle_response (); + if (FD_ISSET (fileno (stdin), &rmask)) + handle_child_connection (glibtop_global_server, fileno (stdin)); #endif /* NOT SYSV_IPC */ } /* while */ diff --git a/src/daemon/main.c b/src/daemon/main.c index 54cfe444..3537ee92 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -21,15 +21,19 @@ #include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include #include #include +#undef REAL_DEBUG +#define PARENT_DEBUG + #if defined(HAVE_GETDTABLESIZE) #define GET_MAX_FDS() getdtablesize() #else @@ -46,7 +50,7 @@ do_output (int s, glibtop_response *response, off_t offset, size_t data_size, const void *data) { #ifdef REAL_DEBUG - fprintf (stderr, "Really writing %d bytes at offset %d.\n", + fprintf (stderr, "Really writing %d bytes at offset %lu.\n", sizeof (glibtop_response), offset); #endif @@ -66,31 +70,201 @@ do_output (int s, glibtop_response *response, off_t offset, } } -static void +static int do_read (int s, void *ptr, size_t total_size) { int nread; size_t already_read = 0, remaining = total_size; while (already_read < total_size) { - nread = recv (s, ptr, remaining, 0); + 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_error_io ("recv"); - return; + glibtop_warn_io ("recv"); + return 0; } already_read += nread; remaining -= nread; (char *) ptr += nread; +#ifdef REAL_DEBUG fprintf (stderr, "READ (%d): %d - %d - %d\n", nread, already_read, remaining, total_size); +#endif + } + + return already_read; +} + +void +handle_parent_connection (glibtop *server, int s) +{ + pid_t pid; + char parameter [BUFSIZ]; + struct timeval tv; + glibtop_response response; + glibtop_command cmnd; + unsigned method; + int null = 0; + void *ptr; + + tv.tv_sec = 5; + tv.tv_usec = 0; + + method = GLIBTOP_METHOD_UNIX; + + glibtop_set_parameter_l (server, GLIBTOP_PARAM_METHOD, + &method, sizeof (method)); + + glibtop_set_parameter_l (server, GLIBTOP_PARAM_FEATURES, + &glibtop_server_features, + sizeof (glibtop_server_features)); + + fprintf (stderr, "Parent features = %lu\n", glibtop_server_features); + + while (do_read (s, &cmnd, sizeof (glibtop_command))) { +#ifdef PARENT_DEBUG + fprintf (stderr, "Parent (%d) received command %d from client.\n", + getpid (), cmnd.command); +#endif + + if (cmnd.data_size >= BUFSIZ) { + glibtop_warn ("Client sent %d bytes, but buffer is %d", cmnd.size, BUFSIZ); + return; + } + + memset (parameter, 0, sizeof (parameter)); + + if (cmnd.data_size) { +#ifdef PARENT_DEBUG + fprintf (stderr, "Client has %d bytes of data.\n", cmnd.data_size); +#endif + + 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, &response, 0, 0, NULL); + + fprintf (stderr, "Sending QUIT command (%d).\n", + server->socket); + + glibtop_call_l (server, GLIBTOP_CMND_QUIT, + 0, NULL, 0, NULL); + + fprintf (stderr, "Done sending QUIT command (%d).\n", + server->socket); + + close (server->socket); + return; + case GLIBTOP_CMND_SYSDEPS: + response.u.sysdeps.features = GLIBTOP_SYSDEPS_ALL; + do_output (s, &response, _offset_union (sysdeps), 0, NULL); + break; + case GLIBTOP_CMND_CPU: + glibtop_get_cpu_l (server, &response.u.data.cpu); + do_output (s, &response, _offset_data (cpu), 0, NULL); + break; + case GLIBTOP_CMND_MEM: + glibtop_get_mem_l (server, &response.u.data.mem); + do_output (s, &response, _offset_data (mem), 0, NULL); + break; + case GLIBTOP_CMND_SWAP: + glibtop_get_swap_l (server, &response.u.data.swap); + do_output (s, &response, _offset_data (swap), 0, NULL); + break; + case GLIBTOP_CMND_UPTIME: + glibtop_get_uptime_l (server, &response.u.data.uptime); + do_output (s, &response, _offset_data (uptime), 0, NULL); + break; + case GLIBTOP_CMND_LOADAVG: + glibtop_get_loadavg_l (server, &response.u.data.loadavg); + do_output (s, &response, _offset_data (loadavg), 0, NULL); + break; + case GLIBTOP_CMND_SHM_LIMITS: + glibtop_get_shm_limits_l (server, &response.u.data.shm_limits); + do_output (s, &response, _offset_data (shm_limits), 0, NULL); + break; + case GLIBTOP_CMND_MSG_LIMITS: + glibtop_get_msg_limits_l (server, &response.u.data.msg_limits); + do_output (s, &response, _offset_data (msg_limits), 0, NULL); + break; + case GLIBTOP_CMND_SEM_LIMITS: + glibtop_get_sem_limits_l (server, &response.u.data.sem_limits); + do_output (s, &response, _offset_data (sem_limits), 0, NULL); + break; + case GLIBTOP_CMND_PROCLIST: + ptr = glibtop_get_proclist_l (server, &response.u.data.proclist); + do_output (s, &response, _offset_data (proclist), + response.u.data.proclist.total, ptr); + glibtop_free_r (server, ptr); + break; + case GLIBTOP_CMND_PROC_STATE: + memcpy (&pid, parameter, sizeof (pid_t)); + glibtop_get_proc_state_l + (server, &response.u.data.proc_state, pid); + do_output (s, &response, _offset_data (proc_state), 0, NULL); + break; + case GLIBTOP_CMND_PROC_UID: + memcpy (&pid, parameter, sizeof (pid_t)); + glibtop_get_proc_uid_l + (server, &response.u.data.proc_uid, pid); + do_output (s, &response, _offset_data (proc_uid), 0, NULL); + break; + case GLIBTOP_CMND_PROC_MEM: + memcpy (&pid, parameter, sizeof (pid_t)); + glibtop_get_proc_mem_l + (server, &response.u.data.proc_mem, pid); + do_output (s, &response, _offset_data (proc_mem), 0, NULL); + break; + case GLIBTOP_CMND_PROC_TIME: + memcpy (&pid, parameter, sizeof (pid_t)); + glibtop_get_proc_time_l + (server, &response.u.data.proc_time, pid); + do_output (s, &response, _offset_data (proc_time), 0, NULL); + break; + case GLIBTOP_CMND_PROC_SIGNAL: + memcpy (&pid, parameter, sizeof (pid_t)); + glibtop_get_proc_signal_l + (server, &response.u.data.proc_signal, pid); + do_output (s, &response, _offset_data (proc_signal), 0, NULL); + break; + case GLIBTOP_CMND_PROC_KERNEL: + memcpy (&pid, parameter, sizeof (pid_t)); + glibtop_get_proc_kernel_l + (server, &response.u.data.proc_kernel, pid); + do_output (s, &response, _offset_data (proc_kernel), 0, NULL); + break; + case GLIBTOP_CMND_PROC_SEGMENT: + memcpy (&pid, parameter, sizeof (pid_t)); + glibtop_get_proc_segment_l + (server, &response.u.data.proc_segment, pid); + do_output (s, &response, _offset_data (proc_segment), 0, NULL); + break; + default: + glibtop_warn_r (server, + "Parent received unknown command %u", + cmnd.command); + break; + } } } void -handle_socket_connection (glibtop *server, int s) +handle_child_connection (glibtop *server, int s) { pid_t pid; char parameter [BUFSIZ]; @@ -102,11 +276,10 @@ handle_socket_connection (glibtop *server, int s) tv.tv_sec = 5; tv.tv_usec = 0; - while(1) { - do_read (s, &cmnd, sizeof (glibtop_command)); - -#ifdef REAL_DEBUG - fprintf (stderr, "Received command %d from client.\n", cmnd.command); + while (do_read (s, &cmnd, sizeof (glibtop_command))) { +#ifdef CHILD_DEBUG + fprintf (stderr, "Child (%d - %d) received command " + "%d from client.\n", getpid (), s, cmnd.command); #endif if (cmnd.data_size >= BUFSIZ) { @@ -117,7 +290,7 @@ handle_socket_connection (glibtop *server, int s) memset (parameter, 0, sizeof (parameter)); if (cmnd.data_size) { -#ifdef REAL_DEBUG +#ifdef CHILD_DEBUG fprintf (stderr, "Client has %d bytes of data.\n", cmnd.data_size); #endif @@ -128,8 +301,14 @@ handle_socket_connection (glibtop *server, int s) } switch (cmnd.command) { + case GLIBTOP_CMND_QUIT: + do_output (s, &response, 0, 0, NULL); + + fprintf (stderr, "Child received QUIT command.\n"); + + return; case GLIBTOP_CMND_SYSDEPS: - response.u.sysdeps.features = GLIBTOP_SYSDEPS_ALL; + response.u.sysdeps.features = glibtop_server_features; do_output (s, &response, _offset_union (sysdeps), 0, NULL); break; case GLIBTOP_CMND_CPU: @@ -213,6 +392,12 @@ handle_socket_connection (glibtop *server, int s) (server, &response.u.data.proc_segment, pid); do_output (s, &response, _offset_data (proc_segment), 0, NULL); break; + default: + glibtop_warn_r (server, + "Child received unknown command %u", + cmnd.command); + break; + } } } diff --git a/src/daemon/server_config.h b/src/daemon/server_config.h new file mode 100644 index 00000000..9a563865 --- /dev/null +++ b/src/daemon/server_config.h @@ -0,0 +1,14 @@ +#define SERVER_PORT 42800 + +#define SERVER_UID 99 +#define SERVER_GID 99 + +#define HOST_TABLE_ENTRIES 3 + +const char *permitted_host_names [HOST_TABLE_ENTRIES] = +{ "localhost", + "voyager.home-of-linux.com", + "einstein.home-of-linux.com", +}; + +unsigned long permitted_hosts [HOST_TABLE_ENTRIES]; diff --git a/sysdeps/linux/procstate.c b/sysdeps/linux/procstate.c index bcf55662..7b843aa5 100644 --- a/sysdeps/linux/procstate.c +++ b/sysdeps/linux/procstate.c @@ -73,8 +73,10 @@ glibtop_get_proc_state_s (glibtop *server, glibtop_proc_state *buf, pid_t pid) return; } - input [nread] = 0; + fclose (f); + input [nread] = 0; + /* This is from guile-utils/gtop/proc/readproc.c */ /* split into "PID (cmd" and "" */