summaryrefslogtreecommitdiffstats
path: root/ksysguard/ksysguardd
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit4aed2c8219774f5d797760606b8489a92ddc5163 (patch)
tree3f8c130f7d269626bf6a9447407ef6c35954426a /ksysguard/ksysguardd
downloadtdebase-4aed2c8219774f5d797760606b8489a92ddc5163.tar.gz
tdebase-4aed2c8219774f5d797760606b8489a92ddc5163.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'ksysguard/ksysguardd')
-rw-r--r--ksysguard/ksysguardd/Command.c261
-rw-r--r--ksysguard/ksysguardd/Command.h103
-rw-r--r--ksysguard/ksysguardd/FreeBSD/CPU.c263
-rw-r--r--ksysguard/ksysguardd/FreeBSD/CPU.h49
-rw-r--r--ksysguard/ksysguardd/FreeBSD/Makefile.am8
-rw-r--r--ksysguard/ksysguardd/FreeBSD/Memory.c209
-rw-r--r--ksysguard/ksysguardd/FreeBSD/Memory.h45
-rw-r--r--ksysguard/ksysguardd/FreeBSD/ProcessList.c556
-rw-r--r--ksysguard/ksysguardd/FreeBSD/ProcessList.h38
-rw-r--r--ksysguard/ksysguardd/FreeBSD/apm.c102
-rw-r--r--ksysguard/ksysguardd/FreeBSD/apm.h34
-rw-r--r--ksysguard/ksysguardd/FreeBSD/diskstat.c256
-rw-r--r--ksysguard/ksysguardd/FreeBSD/diskstat.h40
-rw-r--r--ksysguard/ksysguardd/FreeBSD/loadavg.c96
-rw-r--r--ksysguard/ksysguardd/FreeBSD/loadavg.h36
-rw-r--r--ksysguard/ksysguardd/FreeBSD/logfile.c175
-rw-r--r--ksysguard/ksysguardd/FreeBSD/logfile.h36
-rw-r--r--ksysguard/ksysguardd/FreeBSD/netdev.c353
-rw-r--r--ksysguard/ksysguardd/FreeBSD/netdev.h35
-rw-r--r--ksysguard/ksysguardd/Irix/LoadAvg.c78
-rw-r--r--ksysguard/ksysguardd/Irix/LoadAvg.h41
-rw-r--r--ksysguard/ksysguardd/Irix/Makefile.am4
-rw-r--r--ksysguard/ksysguardd/Irix/Memory.c128
-rw-r--r--ksysguard/ksysguardd/Irix/Memory.h46
-rw-r--r--ksysguard/ksysguardd/Irix/NetDev.c343
-rw-r--r--ksysguard/ksysguardd/Irix/NetDev.h35
-rw-r--r--ksysguard/ksysguardd/Irix/ProcessList.c462
-rw-r--r--ksysguard/ksysguardd/Irix/ProcessList.h43
-rw-r--r--ksysguard/ksysguardd/Irix/cpu.c262
-rw-r--r--ksysguard/ksysguardd/Irix/cpu.h43
-rw-r--r--ksysguard/ksysguardd/Linux/Makefile.am14
-rw-r--r--ksysguard/ksysguardd/Linux/Memory.c293
-rw-r--r--ksysguard/ksysguardd/Linux/Memory.h45
-rw-r--r--ksysguard/ksysguardd/Linux/ProcessList.c554
-rw-r--r--ksysguard/ksysguardd/Linux/ProcessList.h38
-rw-r--r--ksysguard/ksysguardd/Linux/acpi.c418
-rw-r--r--ksysguard/ksysguardd/Linux/acpi.h45
-rw-r--r--ksysguard/ksysguardd/Linux/apm.c126
-rw-r--r--ksysguard/ksysguardd/Linux/apm.h34
-rw-r--r--ksysguard/ksysguardd/Linux/cpuinfo.c179
-rw-r--r--ksysguard/ksysguardd/Linux/cpuinfo.h32
-rw-r--r--ksysguard/ksysguardd/Linux/diskstat.c265
-rw-r--r--ksysguard/ksysguardd/Linux/diskstat.h40
-rw-r--r--ksysguard/ksysguardd/Linux/i8k.c150
-rw-r--r--ksysguard/ksysguardd/Linux/i8k.h36
-rw-r--r--ksysguard/ksysguardd/Linux/lmsensors.c309
-rw-r--r--ksysguard/ksysguardd/Linux/lmsensors.h30
-rw-r--r--ksysguard/ksysguardd/Linux/loadavg.c143
-rw-r--r--ksysguard/ksysguardd/Linux/loadavg.h36
-rw-r--r--ksysguard/ksysguardd/Linux/logfile.c172
-rw-r--r--ksysguard/ksysguardd/Linux/logfile.h36
-rw-r--r--ksysguard/ksysguardd/Linux/netdev.c367
-rw-r--r--ksysguard/ksysguardd/Linux/netdev.h35
-rw-r--r--ksysguard/ksysguardd/Linux/netstat.c495
-rw-r--r--ksysguard/ksysguardd/Linux/netstat.h39
-rw-r--r--ksysguard/ksysguardd/Linux/stat.c1184
-rw-r--r--ksysguard/ksysguardd/Linux/stat.h66
-rw-r--r--ksysguard/ksysguardd/Makefile.am35
-rw-r--r--ksysguard/ksysguardd/NetBSD/CPU.c206
-rw-r--r--ksysguard/ksysguardd/NetBSD/CPU.h49
-rw-r--r--ksysguard/ksysguardd/NetBSD/Makefile.am8
-rw-r--r--ksysguard/ksysguardd/NetBSD/Memory.c202
-rw-r--r--ksysguard/ksysguardd/NetBSD/Memory.h43
-rw-r--r--ksysguard/ksysguardd/NetBSD/ProcessList.c457
-rw-r--r--ksysguard/ksysguardd/NetBSD/ProcessList.h38
-rw-r--r--ksysguard/ksysguardd/NetBSD/apm.c100
-rw-r--r--ksysguard/ksysguardd/NetBSD/apm.h34
-rw-r--r--ksysguard/ksysguardd/NetBSD/diskstat.c249
-rw-r--r--ksysguard/ksysguardd/NetBSD/diskstat.h40
-rw-r--r--ksysguard/ksysguardd/NetBSD/loadavg.c96
-rw-r--r--ksysguard/ksysguardd/NetBSD/loadavg.h36
-rw-r--r--ksysguard/ksysguardd/NetBSD/logfile.c175
-rw-r--r--ksysguard/ksysguardd/NetBSD/logfile.h36
-rw-r--r--ksysguard/ksysguardd/NetBSD/netdev.c304
-rw-r--r--ksysguard/ksysguardd/NetBSD/netdev.h35
-rw-r--r--ksysguard/ksysguardd/OpenBSD/Makefile.am6
-rw-r--r--ksysguard/ksysguardd/OpenBSD/cpu.c209
-rw-r--r--ksysguard/ksysguardd/OpenBSD/cpu.h51
-rw-r--r--ksysguard/ksysguardd/OpenBSD/memory.c207
-rw-r--r--ksysguard/ksysguardd/OpenBSD/memory.h43
-rw-r--r--ksysguard/ksysguardd/PWUIDCache.c114
-rw-r--r--ksysguard/ksysguardd/PWUIDCache.h36
-rw-r--r--ksysguard/ksysguardd/Porting-HOWTO133
-rw-r--r--ksysguard/ksysguardd/Solaris/LoadAvg.c120
-rw-r--r--ksysguard/ksysguardd/Solaris/LoadAvg.h41
-rw-r--r--ksysguard/ksysguardd/Solaris/Makefile.am10
-rw-r--r--ksysguard/ksysguardd/Solaris/Memory.c223
-rw-r--r--ksysguard/ksysguardd/Solaris/Memory.h46
-rw-r--r--ksysguard/ksysguardd/Solaris/NetDev.c679
-rw-r--r--ksysguard/ksysguardd/Solaris/NetDev.h59
-rw-r--r--ksysguard/ksysguardd/Solaris/ProcessList.c436
-rw-r--r--ksysguard/ksysguardd/Solaris/ProcessList.h43
-rw-r--r--ksysguard/ksysguardd/Tru64/LoadAvg.c121
-rw-r--r--ksysguard/ksysguardd/Tru64/LoadAvg.h41
-rw-r--r--ksysguard/ksysguardd/Tru64/Makefile.am8
-rw-r--r--ksysguard/ksysguardd/Tru64/Memory.c237
-rw-r--r--ksysguard/ksysguardd/Tru64/Memory.h46
-rw-r--r--ksysguard/ksysguardd/Tru64/NetDev.c678
-rw-r--r--ksysguard/ksysguardd/Tru64/NetDev.h59
-rw-r--r--ksysguard/ksysguardd/conf.c137
-rw-r--r--ksysguard/ksysguardd/conf.h38
-rw-r--r--ksysguard/ksysguardd/configure.in.in45
-rw-r--r--ksysguard/ksysguardd/ksysguardd.c633
-rw-r--r--ksysguard/ksysguardd/ksysguardd.h52
-rw-r--r--ksysguard/ksysguardd/modules.h151
105 files changed, 16206 insertions, 0 deletions
diff --git a/ksysguard/ksysguardd/Command.c b/ksysguard/ksysguardd/Command.c
new file mode 100644
index 000000000..17abffb92
--- /dev/null
+++ b/ksysguard/ksysguardd/Command.c
@@ -0,0 +1,261 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 - 2001 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+
+#include "ccont.h"
+#include "ksysguardd.h"
+
+#include "Command.h"
+
+typedef struct {
+ char* command;
+ cmdExecutor ex;
+ char* type;
+ int isMonitor;
+ struct SensorModul* sm;
+} Command;
+
+static CONTAINER CommandList;
+static sigset_t SignalSet;
+
+void command_cleanup( void* v );
+
+void command_cleanup( void* v )
+{
+ if ( v ) {
+ Command* c = v;
+ if ( c->command )
+ free ( c->command );
+ if ( c->type )
+ free ( c->type );
+ free ( v );
+ }
+}
+
+/*
+================================ public part =================================
+*/
+
+int ReconfigureFlag = 0;
+int CheckSetupFlag = 0;
+
+void print_error( const char *fmt, ... )
+{
+ char errmsg[ 1024 ];
+ va_list az;
+
+ va_start( az, fmt );
+ vsnprintf( errmsg, sizeof( errmsg ) - 1, fmt, az );
+ errmsg[ sizeof( errmsg ) - 1 ] = '\0';
+ va_end( az );
+
+ if ( CurrentClient )
+ fprintf( CurrentClient, "\033%s\033", errmsg );
+}
+
+void log_error( const char *fmt, ... )
+{
+ char errmsg[ 1024 ];
+ va_list az;
+
+ va_start( az, fmt );
+ vsnprintf( errmsg, sizeof( errmsg ) - 1, fmt, az );
+ errmsg[ sizeof( errmsg ) - 1 ] = '\0';
+ va_end( az );
+
+ openlog( "ksysguardd", LOG_PID, LOG_DAEMON );
+ syslog( LOG_ERR, "%s", errmsg );
+ closelog();
+}
+
+void initCommand( void )
+{
+ CommandList = new_ctnr();
+ sigemptyset( &SignalSet );
+ sigaddset( &SignalSet, SIGALRM );
+
+ registerCommand( "monitors", printMonitors );
+ registerCommand( "test", printTest );
+
+ if ( RunAsDaemon == 0 )
+ registerCommand( "quit", exQuit );
+}
+
+void exitCommand( void )
+{
+ destr_ctnr( CommandList, command_cleanup );
+}
+
+void registerCommand( const char* command, cmdExecutor ex )
+{
+ Command* cmd = (Command*)malloc( sizeof( Command ) );
+ cmd->command = (char*)malloc( strlen( command ) + 1 );
+ strcpy( cmd->command, command );
+ cmd->type = 0;
+ cmd->ex = ex;
+ cmd->isMonitor = 0;
+ push_ctnr( CommandList, cmd );
+ ReconfigureFlag = 1;
+}
+
+void removeCommand( const char* command )
+{
+ Command* cmd;
+
+ for ( cmd = first_ctnr( CommandList ); cmd; cmd = next_ctnr( CommandList ) ) {
+ if ( strcmp( cmd->command, command ) == 0 ) {
+ remove_ctnr( CommandList );
+ if ( cmd->command )
+ free( cmd->command );
+ if ( cmd->type )
+ free( cmd->type );
+ free( cmd );
+ }
+ }
+
+ ReconfigureFlag = 1;
+}
+
+void registerMonitor( const char* command, const char* type, cmdExecutor ex,
+ cmdExecutor iq, struct SensorModul* sm )
+{
+ /* Monitors are similar to regular commands except that every monitor
+ * registers two commands. The first is the value request command and
+ * the second is the info request command. The info request command is
+ * identical to the value request but with an '?' appended. The value
+ * command prints a single value. The info request command prints
+ * a description of the monitor, the mininum value, the maximum value
+ * and the unit. */
+ Command* cmd = (Command*)malloc( sizeof( Command ) );
+ cmd->command = (char*)malloc( strlen( command ) + 1 );
+ strcpy( cmd->command, command );
+ cmd->ex = ex;
+ cmd->type = (char*)malloc( strlen( type ) + 1 );
+ strcpy( cmd->type, type );
+ cmd->isMonitor = 1;
+ cmd->sm = sm;
+ push_ctnr( CommandList, cmd );
+
+ cmd = (Command*)malloc( sizeof( Command ) );
+ cmd->command = (char*)malloc( strlen( command ) + 2 );
+ strcpy( cmd->command, command );
+ cmd->command[ strlen( command ) ] = '?';
+ cmd->command[ strlen( command ) + 1 ] = '\0';
+ cmd->ex = iq;
+ cmd->isMonitor = 0;
+ cmd->sm = sm;
+ cmd->type = 0;
+ push_ctnr( CommandList, cmd );
+}
+
+void removeMonitor( const char* command )
+{
+ char* buf;
+
+ removeCommand( command );
+ buf = (char*)malloc( strlen( command ) + 2 );
+ strcpy( buf, command );
+ strcat( buf, "?" );
+ removeCommand( buf );
+ free( buf );
+}
+
+void executeCommand( const char* command )
+{
+ Command* cmd;
+ char tokenFormat[ 64 ];
+ char token[ 64 ];
+
+ sprintf( tokenFormat, "%%%ds", (int)sizeof( token ) - 1 );
+ sscanf( command, tokenFormat, token );
+
+ for ( cmd = first_ctnr( CommandList ); cmd; cmd = next_ctnr( CommandList ) ) {
+ if ( strcmp( cmd->command, token ) == 0 ) {
+ if ( cmd->isMonitor ) {
+ if ( ( time( NULL ) - cmd->sm->time ) >= UPDATEINTERVAL ) {
+ cmd->sm->time = time( NULL );
+
+ if ( cmd->sm->updateCommand != NULL )
+ cmd->sm->updateCommand();
+ }
+ }
+
+ (*(cmd->ex))( command );
+
+ if ( ReconfigureFlag ) {
+ ReconfigureFlag = 0;
+ print_error( "RECONFIGURE\n" );
+ }
+
+ fflush( CurrentClient );
+ return;
+ }
+ }
+
+ if ( CurrentClient ) {
+ fprintf( CurrentClient, "UNKNOWN COMMAND\n" );
+ fflush( CurrentClient );
+ }
+}
+
+void printMonitors( const char *c )
+{
+ Command* cmd;
+ ReconfigureFlag = 0;
+
+ (void)c;
+
+ for ( cmd = first_ctnr( CommandList ); cmd; cmd = next_ctnr( CommandList ) ) {
+ if ( cmd->isMonitor )
+ fprintf(CurrentClient, "%s\t%s\n", cmd->command, cmd->type);
+ }
+
+ fflush( CurrentClient );
+}
+
+void printTest( const char* c )
+{
+ Command* cmd;
+
+ for ( cmd = first_ctnr( CommandList ); cmd; cmd = next_ctnr( CommandList ) ) {
+ if ( strcmp( cmd->command, c + strlen( "test " ) ) == 0 ) {
+ fprintf( CurrentClient, "1\n" );
+ fflush( CurrentClient );
+ return;
+ }
+ }
+
+ fprintf( CurrentClient, "0\n" );
+ fflush( CurrentClient );
+}
+
+void exQuit( const char* cmd )
+{
+ (void)cmd;
+
+ QuitApp = 1;
+}
diff --git a/ksysguard/ksysguardd/Command.h b/ksysguard/ksysguardd/Command.h
new file mode 100644
index 000000000..d3645d905
--- /dev/null
+++ b/ksysguard/ksysguardd/Command.h
@@ -0,0 +1,103 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 - 2001 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include "ksysguardd.h"
+
+#ifndef KSG_COMMAND_H
+#define KSG_COMMAND_H
+
+typedef void (*cmdExecutor)(const char*);
+
+/**
+ Set this flag to '1' to request a rescan of the available sensors
+ in the front end.
+ */
+extern int ReconfigureFlag;
+
+/**
+ Has nearly the same meaning like the above flag ;)
+ */
+extern int CheckSetupFlag;
+
+/**
+ Delivers the error message to the front end.
+ */
+void print_error( const char*, ... )
+#ifdef __GNUC__
+ __attribute__ ( ( format ( printf, 1, 2 ) ) )
+#endif
+ ;
+
+/**
+ Writes the error message to the syslog daemon.
+ */
+void log_error( const char*, ... )
+ #ifdef __GNUC__
+ __attribute__ ( ( format ( printf, 1, 2 ) ) )
+#endif
+ ;
+
+
+
+/**
+ Use this function to register a command with the name
+ @ref command and the function pointer @ref ex.
+ */
+void registerCommand( const char* command, cmdExecutor ex );
+
+/**
+ Use this function to remove a command with the name
+ @ref command.
+ */
+void removeCommand( const char* command );
+
+/**
+ Use this function to add a new montior with the name @ref monitor
+ from the type @ref type.
+ @ref ex is a pointer to the function that is called to get a value
+ and @ref iq is a pointer to the function that returns informations
+ about this monitor.
+ @ref sm is a parameter to the sensor modul object that is passed by
+ the initXXX method.
+ */
+void registerMonitor( const char* monitor, const char* type, cmdExecutor ex,
+ cmdExecutor iq, struct SensorModul* sm );
+
+/**
+ Use this function to add the montior with the name @ref monitor.
+ */
+void removeMonitor( const char* monitor );
+
+
+/**
+ Internal usage.
+ */
+void executeCommand( const char* command );
+
+void initCommand( void );
+void exitCommand( void );
+
+void printMonitors( const char* cmd );
+void printTest( const char* cmd );
+
+void exQuit( const char* cmd );
+
+#endif
diff --git a/ksysguard/ksysguardd/FreeBSD/CPU.c b/ksysguard/ksysguardd/FreeBSD/CPU.c
new file mode 100644
index 000000000..90d0c4721
--- /dev/null
+++ b/ksysguard/ksysguardd/FreeBSD/CPU.c
@@ -0,0 +1,263 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <osreldate.h>
+
+#include <sys/types.h>
+#if defined(__DragonFly__)
+#include <sys/param.h>
+#include <kinfo.h>
+#elif __FreeBSD_version < 500101
+ #include <sys/dkstat.h>
+#else
+ #include <sys/resource.h>
+#endif
+#include <sys/sysctl.h>
+
+#include <devstat.h>
+#include <fcntl.h>
+#include <nlist.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "CPU.h"
+#include "Command.h"
+#include "ksysguardd.h"
+
+#if defined(__DragonFly__)
+static void cputime_percentages(int[4], struct kinfo_cputime *,
+ struct kinfo_cputime *);
+static struct kinfo_cputime cp_time, cp_old;
+
+#define CPUSTATES 4
+#define CP_USER 0
+#define CP_NICE 1
+#define CP_SYS 2
+#define CP_IDLE 3
+
+#else
+long percentages(int cnt, int *out, long *new, long *old, long *diffs);
+
+unsigned long cp_time_offset;
+
+long cp_time[CPUSTATES];
+long cp_old[CPUSTATES];
+long cp_diff[CPUSTATES];
+#endif
+
+int cpu_states[CPUSTATES];
+
+void
+initCpuInfo(struct SensorModul* sm)
+{
+ /* Total CPU load */
+ registerMonitor("cpu/user", "integer", printCPUUser,
+ printCPUUserInfo, sm);
+ registerMonitor("cpu/nice", "integer", printCPUNice,
+ printCPUNiceInfo, sm);
+ registerMonitor("cpu/sys", "integer", printCPUSys,
+ printCPUSysInfo, sm);
+ registerMonitor("cpu/idle", "integer", printCPUIdle,
+ printCPUIdleInfo, sm);
+
+ updateCpuInfo();
+}
+
+void
+exitCpuInfo(void)
+{
+}
+
+int
+updateCpuInfo(void)
+{
+#if defined(__DragonFly__)
+ kinfo_get_sched_cputime(&cp_time);
+ cputime_percentages(cpu_states, &cp_time, &cp_old);
+#else
+ size_t len = sizeof(cp_time);
+ sysctlbyname("kern.cp_time", &cp_time, &len, NULL, 0);
+ percentages(CPUSTATES, cpu_states, cp_time, cp_old, cp_diff);
+#endif
+ return (0);
+}
+
+void
+printCPUUser(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", cpu_states[CP_USER]/10);
+}
+
+void
+printCPUUserInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "CPU User Load\t0\t100\t%%\n");
+}
+
+void
+printCPUNice(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", cpu_states[CP_NICE]/10);
+}
+
+void
+printCPUNiceInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "CPU Nice Load\t0\t100\t%%\n");
+}
+
+void
+printCPUSys(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", cpu_states[CP_SYS]/10);
+}
+
+void
+printCPUSysInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "CPU System Load\t0\t100\t%%\n");
+}
+
+void
+printCPUIdle(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", cpu_states[CP_IDLE]/10);
+}
+
+void
+printCPUIdleInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "CPU Idle Load\t0\t100\t%%\n");
+}
+
+
+/* The part ripped from top... */
+/*
+ * Top users/processes display for Unix
+ * Version 3
+ *
+ * This program may be freely redistributed,
+ * but this entire comment MUST remain intact.
+ *
+ * Copyright (c) 1984, 1989, William LeFebvre, Rice University
+ * Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University
+ */
+
+/*
+ * percentages(cnt, out, new, old, diffs) - calculate percentage change
+ * between array "old" and "new", putting the percentages i "out".
+ * "cnt" is size of each array and "diffs" is used for scratch space.
+ * The array "old" is updated on each call.
+ * The routine assumes modulo arithmetic. This function is especially
+ * useful on BSD mchines for calculating cpu state percentages.
+ */
+#if defined(__DragonFly__)
+static void
+cputime_percentages(int out[4], struct kinfo_cputime *new, struct kinfo_cputime * old)
+{
+ struct kinfo_cputime diffs;
+ int i;
+ uint64_t total_change, half_total;
+
+ /* initialization */
+ total_change = 0;
+
+ diffs.cp_user = new->cp_user - old->cp_user;
+ diffs.cp_nice = new->cp_nice - old->cp_nice;
+ diffs.cp_sys = new->cp_sys - old->cp_sys;
+ diffs.cp_intr = new->cp_intr - old->cp_intr;
+ diffs.cp_idle = new->cp_idle - old->cp_idle;
+ total_change = diffs.cp_user + diffs.cp_nice + diffs.cp_sys +
+ diffs.cp_intr + diffs.cp_idle;
+ old->cp_user = new->cp_user;
+ old->cp_nice = new->cp_nice;
+ old->cp_sys = new->cp_sys;
+ old->cp_intr = new->cp_intr;
+ old->cp_idle = new->cp_idle;
+
+ /* avoid divide by zero potential */
+ if (total_change == 0)
+ total_change = 1;
+
+ /* calculate percentages based on overall change, rounding up */
+ half_total = total_change >> 1;
+
+ out[0] = ((diffs.cp_user * 1000LL + half_total) / total_change);
+ out[1] = ((diffs.cp_nice * 1000LL + half_total) / total_change);
+ out[2] = (((diffs.cp_sys + diffs.cp_intr) * 1000LL + half_total) / total_change);
+ out[4] = ((diffs.cp_idle * 1000LL + half_total) / total_change);
+}
+
+#else
+long percentages(cnt, out, new, old, diffs)
+
+int cnt;
+int *out;
+register long *new;
+register long *old;
+long *diffs;
+
+{
+ register int i;
+ register long change;
+ register long total_change;
+ register long *dp;
+ long half_total;
+
+ /* initialization */
+ total_change = 0;
+ dp = diffs;
+
+ /* calculate changes for each state and the overall change */
+ for (i = 0; i < cnt; i++)
+ {
+ if ((change = *new - *old) < 0)
+ {
+ /* this only happens when the counter wraps */
+ change = (int)
+ ((unsigned long)*new-(unsigned long)*old);
+ }
+ total_change += (*dp++ = change);
+ *old++ = *new++;
+ }
+
+ /* avoid divide by zero potential */
+ if (total_change == 0)
+ {
+ total_change = 1;
+ }
+
+ /* calculate percentages based on overall change, rounding up */
+ half_total = total_change / 2l;
+
+ /* Do not divide by 0. Causes Floating point exception */
+ if(total_change) {
+ for (i = 0; i < cnt; i++)
+ {
+ *out++ = (int)((*diffs++ * 1000 + half_total) / total_change);
+ }
+ }
+
+ /* return the total in case the caller wants to use it */
+ return(total_change);
+}
+#endif
diff --git a/ksysguard/ksysguardd/FreeBSD/CPU.h b/ksysguard/ksysguardd/FreeBSD/CPU.h
new file mode 100644
index 000000000..c35932ac8
--- /dev/null
+++ b/ksysguard/ksysguardd/FreeBSD/CPU.h
@@ -0,0 +1,49 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _cpuinfo_h_
+#define _cpuinfo_h_
+
+struct SensorModul;
+
+void initCpuInfo(struct SensorModul* sm);
+void exitCpuInfo(void);
+
+int updateCpuInfo(void);
+
+void printCPUUser(const char* cmd);
+void printCPUUserInfo(const char* cmd);
+void printCPUNice(const char* cmd);
+void printCPUNiceInfo(const char* cmd);
+void printCPUSys(const char* cmd);
+void printCPUSysInfo(const char* cmd);
+void printCPUIdle(const char* cmd);
+void printCPUIdleInfo(const char* cmd);
+void printCPUxUser(const char* cmd);
+void printCPUxUserInfo(const char* cmd);
+void printCPUxNice(const char* cmd);
+void printCPUxNiceInfo(const char* cmd);
+void printCPUxSys(const char* cmd);
+void printCPUxSysInfo(const char* cmd);
+void printCPUxIdle(const char* cmd);
+void printCPUxIdleInfo(const char* cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/FreeBSD/Makefile.am b/ksysguard/ksysguardd/FreeBSD/Makefile.am
new file mode 100644
index 000000000..29860a407
--- /dev/null
+++ b/ksysguard/ksysguardd/FreeBSD/Makefile.am
@@ -0,0 +1,8 @@
+#
+#
+
+INCLUDES = -I$(srcdir)/../../CContLib -I$(srcdir)/..
+
+noinst_LIBRARIES = libksysguardd.a
+libksysguardd_a_SOURCES = CPU.c Memory.c ProcessList.c apm.c diskstat.c \
+ loadavg.c logfile.c netdev.c
diff --git a/ksysguard/ksysguardd/FreeBSD/Memory.c b/ksysguard/ksysguardd/FreeBSD/Memory.c
new file mode 100644
index 000000000..9e3db646c
--- /dev/null
+++ b/ksysguard/ksysguardd/FreeBSD/Memory.c
@@ -0,0 +1,209 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999-2000 Hans Petter Bieker <bieker@kde.org>
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/vmmeter.h>
+
+#include <vm/vm_param.h>
+
+#include <fcntl.h>
+#include <kvm.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "Command.h"
+#include "Memory.h"
+#include "ksysguardd.h"
+
+static size_t Total = 0;
+static size_t MFree = 0;
+static size_t Used = 0;
+static size_t Buffers = 0;
+static size_t Cached = 0;
+static size_t Application = 0;
+static size_t STotal = 0;
+static size_t SFree = 0;
+static size_t SUsed = 0;
+static kvm_t *kd;
+
+void
+initMemory(struct SensorModul* sm)
+{
+ char *nlistf = NULL;
+ char *memf = NULL;
+ char buf[_POSIX2_LINE_MAX];
+
+ if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf)) == NULL) {
+ log_error("kvm_openfiles()");
+ return;
+ }
+
+ registerMonitor("mem/physical/free", "integer", printMFree, printMFreeInfo, sm);
+ registerMonitor("mem/physical/used", "integer", printUsed, printUsedInfo, sm);
+ registerMonitor("mem/physical/buf", "integer", printBuffers, printBuffersInfo, sm);
+ registerMonitor("mem/physical/cached", "integer", printCached, printCachedInfo, sm);
+ registerMonitor("mem/physical/application", "integer", printApplication, printApplicationInfo, sm);
+ registerMonitor("mem/swap/free", "integer", printSwapFree, printSwapFreeInfo, sm);
+ registerMonitor("mem/swap/used", "integer", printSwapUsed, printSwapUsedInfo, sm);
+}
+
+void
+exitMemory(void)
+{
+ kvm_close(kd);
+}
+
+int
+updateMemory(void)
+{
+ size_t len;
+ FILE *file;
+ char buf[256];
+ struct kvm_swap kswap[16];
+ int i, swap_count, hlen, pagesize = getpagesize();
+ long blocksize;
+
+ len = sizeof (Total);
+ sysctlbyname("hw.physmem", &Total, &len, NULL, 0);
+ Total /= 1024;
+
+ /* Borrowed from pstat */
+ swap_count = kvm_getswapinfo(kd, kswap, 16, SWIF_DEV_PREFIX);
+ getbsize(&hlen, &blocksize);
+
+#define CONVERT(v) ((int)((quad_t)(v) * pagesize / blocksize))
+
+ if (swap_count > 0) {
+ STotal = CONVERT(kswap[0].ksw_total);
+ SUsed = CONVERT(kswap[0].ksw_used);
+ SFree = CONVERT(kswap[0].ksw_total - kswap[0].ksw_used);
+ }
+
+ len = sizeof (Buffers);
+ if ((sysctlbyname("vfs.bufspace", &Buffers, &len, NULL, 0) == -1) || !len)
+ Buffers = 0; /* Doesn't work under FreeBSD v2.2.x */
+ Buffers /= 1024;
+
+ len = sizeof (Cached);
+ if ((sysctlbyname("vm.stats.vm.v_cache_count", &Cached, &len, NULL, 0) == -1) || !len)
+ Cached = 0; /* Doesn't work under FreeBSD v2.2.x */
+ Cached *= pagesize / 1024;
+
+ len = sizeof (MFree);
+ if ((sysctlbyname("vm.stats.vm.v_free_count", &MFree, &len, NULL, 0) == -1) || !len)
+ MFree = 0; /* Doesn't work under FreeBSD v2.2.x */
+ MFree *= pagesize / 1024;
+
+ Used = Total - MFree;
+ Application = Used - Buffers - Cached;
+
+ return 0;
+}
+
+void
+printMFree(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", MFree);
+}
+
+void
+printMFreeInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Free Memory\t0\t%d\tKB\n", Total);
+}
+
+void
+printUsed(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", Used);
+}
+
+void
+printUsedInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Used Memory\t0\t%d\tKB\n", Total);
+}
+
+void
+printBuffers(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", Buffers);
+}
+
+void
+printBuffersInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Buffer Memory\t0\t%d\tKB\n", Total);
+}
+
+void
+printCached(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", Cached);
+}
+
+void
+printCachedInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Cached Memory\t0\t%d\tKB\n", Total);
+}
+
+void
+printApplication(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", Application);
+}
+
+void
+printApplicationInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Application Memory\t0\t%ld\tKB\n", Total);
+}
+
+void
+printSwapUsed(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", SUsed);
+}
+
+void
+printSwapUsedInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Used Swap Memory\t0\t%d\tKB\n", STotal);
+}
+
+void
+printSwapFree(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", SFree);
+}
+
+void
+printSwapFreeInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Free Swap Memory\t0\t%d\tKB\n", STotal);
+}
diff --git a/ksysguard/ksysguardd/FreeBSD/Memory.h b/ksysguard/ksysguardd/FreeBSD/Memory.h
new file mode 100644
index 000000000..66b521617
--- /dev/null
+++ b/ksysguard/ksysguardd/FreeBSD/Memory.h
@@ -0,0 +1,45 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _memory_h_
+#define _memory_h_
+
+void initMemory(struct SensorModul* sm);
+void exitMemory(void);
+
+int updateMemory(void);
+
+void printMFree(const char* cmd);
+void printMFreeInfo(const char* cmd);
+void printUsed(const char* cmd);
+void printUsedInfo(const char* cmd);
+void printBuffers(const char* cmd);
+void printBuffersInfo(const char* cmd);
+void printCached(const char* cmd);
+void printCachedInfo(const char* cmd);
+void printApplication(const char* cmd);
+void printApplicationInfo(const char* cmd);
+void printSwapUsed(const char* cmd);
+void printSwapUsedInfo(const char* cmd);
+void printSwapFree(const char* cmd);
+void printSwapFreeInfo(const char* cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/FreeBSD/ProcessList.c b/ksysguard/ksysguardd/FreeBSD/ProcessList.c
new file mode 100644
index 000000000..f8d2c3ba6
--- /dev/null
+++ b/ksysguard/ksysguardd/FreeBSD/ProcessList.c
@@ -0,0 +1,556 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999-2000 Hans Petter Bieker<bieker@kde.org>
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <config.h>
+
+#include <ctype.h>
+#include <dirent.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+
+#if defined(__DragonFly__)
+#include <sys/user.h>
+#include <sys/resourcevar.h>
+#endif
+
+#if __FreeBSD_version > 500015
+#include <sys/priority.h>
+#endif
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include "../../gui/SignalIDs.h"
+#include "Command.h"
+#include "ProcessList.h"
+#include "ccont.h"
+#include "ksysguardd.h"
+
+CONTAINER ProcessList = 0;
+
+int fscale;
+
+#define BUFSIZE 1024
+
+typedef struct
+{
+ /* This flag is set for all found processes at the beginning of the
+ * process list update. Processes that do not have this flag set will
+ * be assumed dead and removed from the list. The flag is cleared after
+ * each list update. */
+ int alive;
+
+ /* the process ID */
+ pid_t pid;
+
+ /* the parent process ID */
+ pid_t ppid;
+
+ /* the real user ID */
+ uid_t uid;
+
+ /* the real group ID */
+ gid_t gid;
+
+ /* a character description of the process status */
+ char status[16];
+
+ /* the number of the tty the process owns */
+ int ttyNo;
+
+ /*
+ * The nice level. The range should be -20 to 20. I'm not sure
+ * whether this is true for all platforms.
+ */
+ int niceLevel;
+
+ /*
+ * The scheduling priority.
+ */
+ int priority;
+
+ /*
+ * The total amount of memory the process uses. This includes shared and
+ * swapped memory.
+ */
+ unsigned int vmSize;
+
+ /*
+ * The amount of physical memory the process currently uses.
+ */
+ unsigned int vmRss;
+
+ /*
+ * The amount of memory (shared/swapped/etc) the process shares with
+ * other processes.
+ */
+ unsigned int vmLib;
+
+ /*
+ * The number of 1/100 of a second the process has spend in user space.
+ * If a machine has an uptime of 1 1/2 years or longer this is not a
+ * good idea. I never thought that the stability of UNIX could get me
+ * into trouble! ;)
+ */
+#if !defined(__DragonFly__)
+ unsigned int userTime;
+#else
+ long userTime;
+#endif
+
+ /*
+ * The number of 1/100 of a second the process has spend in system space.
+ * If a machine has an uptime of 1 1/2 years or longer this is not a
+ * good idea. I never thought that the stability of UNIX could get me
+ * into trouble! ;)
+ */
+ unsigned int sysTime;
+
+ /* system time as multime of 100ms */
+ int centStamp;
+
+ /* the current CPU load (in %) from user space */
+ double userLoad;
+
+ /* the current CPU load (in %) from system space */
+ double sysLoad;
+
+ /* the name of the process */
+ char name[64];
+
+ /* the command used to start the process */
+ char cmdline[256];
+
+ /* the login name of the user that owns this process */
+ char userName[32];
+} ProcessInfo;
+
+static unsigned ProcessCount;
+
+static int
+processCmp(void* p1, void* p2)
+{
+ return (((ProcessInfo*) p1)->pid - ((ProcessInfo*) p2)->pid);
+}
+
+static ProcessInfo*
+findProcessInList(int pid)
+{
+ ProcessInfo key;
+ long index;
+
+ key.pid = pid;
+ if ((index = search_ctnr(ProcessList, processCmp, &key)) < 0)
+ return (0);
+
+ return (get_ctnr(ProcessList, index));
+}
+
+static int
+updateProcess(int pid)
+{
+ static char *statuses[] = { "idle","run","sleep","stop","zombie" };
+
+ ProcessInfo* ps;
+ struct passwd* pwent;
+ int mib[4];
+ struct kinfo_proc p;
+ struct rusage pru;
+ size_t len;
+ size_t buflen = 256;
+ char buf[256];
+
+ if ((ps = findProcessInList(pid)) == 0)
+ {
+ ps = (ProcessInfo*) malloc(sizeof(ProcessInfo));
+ ps->pid = pid;
+ ps->centStamp = 0;
+ push_ctnr(ProcessList, ps);
+ bsort_ctnr(ProcessList, processCmp);
+ }
+
+ ps->alive = 1;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = pid;
+
+ len = sizeof (p);
+ if (sysctl(mib, 4, &p, &len, NULL, 0) == -1 || !len)
+ return -1;
+
+#if __FreeBSD_version >= 500015
+ ps->pid = p.ki_pid;
+ ps->ppid = p.ki_ppid;
+ ps->uid = p.ki_uid;
+ ps->gid = p.ki_pgid;
+ ps->priority = p.ki_pri.pri_user;
+ ps->niceLevel = p.ki_nice;
+#elif defined(__DragonFly__) && __DragonFly_version >= 190000
+ ps->pid = p.kp_pid;
+ ps->ppid = p.kp_ppid;
+ ps->uid = p.kp_uid;
+ ps->gid = p.kp_pgid;
+ ps->priority = p.kp_lwp.kl_tdprio;
+#else
+ ps->pid = p.kp_proc.p_pid;
+ ps->ppid = p.kp_eproc.e_ppid;
+ ps->uid = p.kp_eproc.e_ucred.cr_uid;
+ ps->gid = p.kp_eproc.e_pgid;
+#if defined(__DragonFly__)
+ ps->priority = p.kp_thread.td_pri;
+#else
+ ps->priority = p.kp_proc.p_priority;
+#endif
+ ps->niceLevel = p.kp_proc.p_nice;
+#endif
+
+ /* this isn't usertime -- it's total time (??) */
+#if __FreeBSD_version >= 500015
+ ps->userTime = p.ki_runtime / 10000;
+#elif defined(__DragonFly__)
+#if __DragonFly_version >= 190000
+ if (!getrusage(p.kp_pid, &pru))
+#else
+ if (!getrusage(p.kp_proc.p_pid, &pru))
+#endif
+ {
+ errx(1, "failed to get rusage info");
+ }
+ ps->userTime = pru.ru_utime.tv_usec / 1000; /*p_runtime / 1000*/
+#elif __FreeBSD_version >= 300000
+ ps->userTime = p.kp_proc.p_runtime / 10000;
+#else
+ ps->userTime = p.kp_proc.p_rtime.tv_sec*100+p.kp_proc.p_rtime.tv_usec/100;
+#endif
+ ps->sysTime = 0;
+ ps->sysLoad = 0;
+
+ /* memory, process name, process uid */
+ /* find out user name with process uid */
+ pwent = getpwuid(ps->uid);
+ strncpy(ps->userName,pwent&&pwent->pw_name? pwent->pw_name:"????",sizeof(ps->userName));
+ ps->userName[sizeof(ps->userName)-1]='\0';
+
+ if (fscale == 0)
+ ps->userLoad = 0;
+ else
+#if __FreeBSD_version >= 500015
+ ps->userLoad = 100.0 * (double) p.ki_pctcpu / fscale;
+ ps->vmSize = p.ki_size;
+ ps->vmRss = p.ki_rssize * getpagesize();
+ strlcpy(ps->name,p.ki_comm? p.ki_comm:"????",sizeof(ps->name));
+ strcpy(ps->status,(p.ki_stat>=1)&&(p.ki_stat<=5)? statuses[p.ki_stat-1]:"????");
+#elif defined (__DragonFly__) && __DragonFly_version >= 190000
+ ps->userLoad = 100.0 * (double) p.kp_lwp.kl_pctcpu / fscale;
+ ps->vmSize = p.kp_vm_map_size;
+ ps->vmRss = p.kp_vm_rssize * getpagesize();
+ strlcpy(ps->name,p.kp_comm ? p.kp_comm : "????",
+ sizeof(ps->name));
+ strcpy(ps->status,(p.kp_stat>=1)&&(p.kp_stat<=5)? statuses[p.kp_stat-1]:"????");
+#else
+ ps->userLoad = 100.0 * (double) p.kp_proc.p_pctcpu / fscale;
+ ps->vmSize = p.kp_eproc.e_vm.vm_map.size;
+ ps->vmRss = p.kp_eproc.e_vm.vm_rssize * getpagesize();
+#if defined (__DragonFly__)
+ strlcpy(ps->name,p.kp_thread.td_comm ? p.kp_thread.td_comm : "????",
+ sizeof(ps->name));
+#else
+ strlcpy(ps->name,p.kp_proc.p_comm ? p.kp_proc.p_comm : "????", sizeof(ps->name));
+ strcpy(ps->status,(p.kp_proc.p_stat>=1)&&(p.kp_proc.p_stat<=5)? statuses[p.kp_proc.p_stat-1]:"????");
+#endif
+#endif
+
+ /* process command line */
+ /* do a sysctl to get the command line args. */
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_ARGS;
+ mib[3] = pid;
+
+ if ((sysctl(mib, 4, buf, &buflen, 0, 0) == -1) || !buflen)
+ strcpy(ps->cmdline, "????");
+ else
+ strncpy(ps->cmdline, buf, buflen);
+
+ return (0);
+}
+
+static void
+cleanupProcessList(void)
+{
+ ProcessInfo* ps;
+
+ ProcessCount = 0;
+ /* All processes that do not have the active flag set are assumed dead
+ * and will be removed from the list. The alive flag is cleared. */
+ for (ps = first_ctnr(ProcessList); ps; ps = next_ctnr(ProcessList))
+ {
+ if (ps->alive)
+ {
+ /* Process is still alive. Just clear flag. */
+ ps->alive = 0;
+ ProcessCount++;
+ }
+ else
+ {
+ /* Process has probably died. We remove it from the list and
+ * destruct the data structure. i needs to be decremented so
+ * that after i++ the next list element will be inspected. */
+ free(remove_ctnr(ProcessList));
+ }
+ }
+}
+
+/*
+================================ public part ==================================
+*/
+
+void
+initProcessList(struct SensorModul* sm)
+{
+ size_t fscalelen;
+ ProcessList = new_ctnr();
+
+ registerMonitor("ps", "table", printProcessList, printProcessListInfo, sm);
+ registerMonitor("pscount", "integer", printProcessCount, printProcessCountInfo, sm);
+
+ if (!RunAsDaemon)
+ {
+ registerCommand("kill", killProcess);
+ registerCommand("setpriority", setPriority);
+ }
+
+ fscalelen = sizeof(fscale);
+ if (sysctlbyname("kern.fscale", &fscale, &fscalelen, NULL, 0) == -1)
+ fscale = 0;
+
+ updateProcessList();
+}
+
+void
+exitProcessList(void)
+{
+ removeMonitor("ps");
+ removeMonitor("pscount");
+
+ if (ProcessList)
+ free (ProcessList);
+}
+
+int
+updateProcessList(void)
+{
+ int mib[3];
+ size_t len;
+ size_t num;
+ struct kinfo_proc *p;
+
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_ALL;
+ sysctl(mib, 3, NULL, &len, NULL, 0);
+ p = malloc(len);
+ sysctl(mib, 3, p, &len, NULL, 0);
+
+ for (num = 0; num < len / sizeof(struct kinfo_proc); num++)
+#if __FreeBSD_version >= 500015
+ updateProcess(p[num].ki_pid);
+#elif __DragonFly_version >= 190000
+ /* Skip kernel threads with pid -1. Swapper with pid 0 also
+ * causing problems is skipped in printProcessList() as 'kernel'
+ * entry. */
+ if (p[num].kp_pid >= 0)
+ updateProcess(p[num].kp_pid);
+#elif defined(__DragonFly__)
+ if (p[num].kp_proc.p_pid >= 0)
+ updateProcess(p[num].kp_proc.p_pid);
+#else
+ updateProcess(p[num].kp_proc.p_pid);
+#endif
+ free(p);
+ cleanupProcessList();
+
+ return (0);
+}
+
+void
+printProcessListInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Name\tPID\tPPID\tUID\tGID\tStatus\tUser%%\tSystem%%\tNice\tVmSize\tVmRss\tLogin\tCommand\n");
+ fprintf(CurrentClient, "s\td\td\td\td\tS\tf\tf\td\tD\tD\ts\ts\n");
+}
+
+void
+printProcessList(const char* cmd)
+{
+ ProcessInfo* ps;
+
+ ps = first_ctnr(ProcessList); /* skip 'kernel' entry */
+ for (ps = next_ctnr(ProcessList); ps; ps = next_ctnr(ProcessList))
+ {
+ fprintf(CurrentClient, "%s\t%ld\t%ld\t%ld\t%ld\t%s\t%.2f\t%.2f\t%d\t%d\t%d\t%s\t%s\n",
+ ps->name, (long)ps->pid, (long)ps->ppid,
+ (long)ps->uid, (long)ps->gid, ps->status,
+ ps->userLoad, ps->sysLoad, ps->niceLevel,
+ ps->vmSize / 1024, ps->vmRss / 1024, ps->userName, ps->cmdline);
+ }
+}
+
+void
+printProcessCount(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", ProcessCount);
+}
+
+void
+printProcessCountInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Number of Processes\t1\t65535\t\n");
+}
+
+void
+killProcess(const char* cmd)
+{
+ int sig, pid;
+
+ sscanf(cmd, "%*s %d %d", &pid, &sig);
+ switch(sig)
+ {
+ case MENU_ID_SIGABRT:
+ sig = SIGABRT;
+ break;
+ case MENU_ID_SIGALRM:
+ sig = SIGALRM;
+ break;
+ case MENU_ID_SIGCHLD:
+ sig = SIGCHLD;
+ break;
+ case MENU_ID_SIGCONT:
+ sig = SIGCONT;
+ break;
+ case MENU_ID_SIGFPE:
+ sig = SIGFPE;
+ break;
+ case MENU_ID_SIGHUP:
+ sig = SIGHUP;
+ break;
+ case MENU_ID_SIGILL:
+ sig = SIGILL;
+ break;
+ case MENU_ID_SIGINT:
+ sig = SIGINT;
+ break;
+ case MENU_ID_SIGKILL:
+ sig = SIGKILL;
+ break;
+ case MENU_ID_SIGPIPE:
+ sig = SIGPIPE;
+ break;
+ case MENU_ID_SIGQUIT:
+ sig = SIGQUIT;
+ break;
+ case MENU_ID_SIGSEGV:
+ sig = SIGSEGV;
+ break;
+ case MENU_ID_SIGSTOP:
+ sig = SIGSTOP;
+ break;
+ case MENU_ID_SIGTERM:
+ sig = SIGTERM;
+ break;
+ case MENU_ID_SIGTSTP:
+ sig = SIGTSTP;
+ break;
+ case MENU_ID_SIGTTIN:
+ sig = SIGTTIN;
+ break;
+ case MENU_ID_SIGTTOU:
+ sig = SIGTTOU;
+ break;
+ case MENU_ID_SIGUSR1:
+ sig = SIGUSR1;
+ break;
+ case MENU_ID_SIGUSR2:
+ sig = SIGUSR2;
+ break;
+ }
+ if (kill((pid_t) pid, sig))
+ {
+ switch(errno)
+ {
+ case EINVAL:
+ fprintf(CurrentClient, "4\t%d\n", pid);
+ break;
+ case ESRCH:
+ fprintf(CurrentClient, "3\t%d\n", pid);
+ break;
+ case EPERM:
+ fprintf(CurrentClient, "2\t%d\n", pid);
+ break;
+ default:
+ fprintf(CurrentClient, "1\t%d\n", pid); /* unknown error */
+ break;
+ }
+
+ }
+ else
+ fprintf(CurrentClient, "0\t%d\n", pid);
+}
+
+void
+setPriority(const char* cmd)
+{
+ int pid, prio;
+
+ sscanf(cmd, "%*s %d %d", &pid, &prio);
+ if (setpriority(PRIO_PROCESS, pid, prio))
+ {
+ switch(errno)
+ {
+ case EINVAL:
+ fprintf(CurrentClient, "4\n");
+ break;
+ case ESRCH:
+ fprintf(CurrentClient, "3\n");
+ break;
+ case EPERM:
+ case EACCES:
+ fprintf(CurrentClient, "2\n");
+ break;
+ default:
+ fprintf(CurrentClient, "1\n"); /* unknown error */
+ break;
+ }
+ }
+ else
+ fprintf(CurrentClient, "0\n");
+}
diff --git a/ksysguard/ksysguardd/FreeBSD/ProcessList.h b/ksysguard/ksysguardd/FreeBSD/ProcessList.h
new file mode 100644
index 000000000..925c55f5a
--- /dev/null
+++ b/ksysguard/ksysguardd/FreeBSD/ProcessList.h
@@ -0,0 +1,38 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _process_list_h_
+#define _process_list_h_
+
+void initProcessList(struct SensorModul* sm);
+void exitProcessList(void);
+
+int updateProcessList(void);
+
+void printProcessList(const char*);
+void printProcessListInfo(const char*);
+void printProcessCount(const char* cmd);
+void printProcessCountInfo(const char* cmd);
+
+void killProcess(const char* cmd);
+void setPriority(const char* cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/FreeBSD/apm.c b/ksysguard/ksysguardd/FreeBSD/apm.c
new file mode 100644
index 000000000..95efec792
--- /dev/null
+++ b/ksysguard/ksysguardd/FreeBSD/apm.c
@@ -0,0 +1,102 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifdef __i386__
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <machine/apm_bios.h>
+#include <stdio.h>
+
+#include "Command.h"
+#include "apm.h"
+#include "ksysguardd.h"
+
+static int ApmFD, BattFill, BattTime;
+
+#define APMDEV "/dev/apm"
+
+/*
+================================ public part =================================
+*/
+
+void
+initApm(struct SensorModul* sm)
+{
+ if ((ApmFD = open(APMDEV, O_RDONLY)) < 0)
+ return;
+
+ if (updateApm() < 0)
+ return;
+
+ registerMonitor("apm/batterycharge", "integer", printApmBatFill,
+ printApmBatFillInfo, sm);
+ registerMonitor("apm/remainingtime", "integer", printApmBatTime,
+ printApmBatTimeInfo, sm);
+}
+
+void
+exitApm(void)
+{
+ removeMonitor("apm/batterycharge");
+ removeMonitor("apm/remainingtime");
+
+ close(ApmFD);
+}
+
+int
+updateApm(void)
+{
+ struct apm_info info;
+ int retval;
+
+ retval = ioctl(ApmFD, APMIO_GETINFO, &info);
+
+ BattFill = info.ai_batt_life;
+ BattTime = info.ai_batt_time;
+
+ return retval;
+}
+
+void
+printApmBatFill(const char* c)
+{
+ fprintf(CurrentClient, "%d\n", BattFill);
+}
+
+void
+printApmBatFillInfo(const char* c)
+{
+ fprintf(CurrentClient, "Battery charge\t0\t100\t%%\n");
+}
+
+void
+printApmBatTime(const char* c)
+{
+ fprintf(CurrentClient, "%d\n", BattTime);
+}
+
+void
+printApmBatTimeInfo(const char* c)
+{
+ fprintf(CurrentClient, "Remaining battery time\t0\t0\tmin\n");
+}
+
+#endif
diff --git a/ksysguard/ksysguardd/FreeBSD/apm.h b/ksysguard/ksysguardd/FreeBSD/apm.h
new file mode 100644
index 000000000..4e3c0c0d3
--- /dev/null
+++ b/ksysguard/ksysguardd/FreeBSD/apm.h
@@ -0,0 +1,34 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _apm_h_
+#define _apm_h_
+
+void initApm(struct SensorModul* sm);
+void exitApm(void);
+
+int updateApm(void);
+
+void printApmBatFill(const char*);
+void printApmBatFillInfo(const char*);
+void printApmBatTime(const char*);
+void printApmBatTimeInfo(const char*);
+
+#endif
diff --git a/ksysguard/ksysguardd/FreeBSD/diskstat.c b/ksysguard/ksysguardd/FreeBSD/diskstat.c
new file mode 100644
index 000000000..04f64a706
--- /dev/null
+++ b/ksysguard/ksysguardd/FreeBSD/diskstat.c
@@ -0,0 +1,256 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/ucred.h>
+#include <sys/mount.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "Command.h"
+#include "ccont.h"
+#include "diskstat.h"
+#include "ksysguardd.h"
+
+typedef struct {
+ char device[256];
+ char mntpnt[256];
+ long blocks;
+ long bfree;
+ long bused;
+ int bused_percent;
+} DiskInfo;
+
+static CONTAINER DiskStatList = 0;
+static struct SensorModul* DiskStatSM;
+
+char *getMntPnt(const char *cmd)
+{
+ static char device[1025];
+ char *ptr;
+
+ memset(device, 0, sizeof(device));
+ sscanf(cmd, "partitions%1024s", device);
+
+ ptr = (char *)rindex(device, '/');
+ *ptr = '\0';
+
+ return (char *)device;
+}
+
+int numMntPnt(void)
+{
+ struct statfs *fs_info;
+ int i, n, counter = 0;
+
+ n = getmntinfo(&fs_info, MNT_WAIT);
+ for (i = 0; i < n; i++)
+ if (strcmp(fs_info[i].f_fstypename, "procfs") && strcmp(fs_info[i].f_fstypename, "swap") && strcmp(fs_info[i].f_fstypename, "devfs"))
+ counter++;
+
+ return counter;
+}
+
+/* ------------------------------ public part --------------------------- */
+
+void initDiskStat(struct SensorModul* sm)
+{
+ char monitor[1024];
+ DiskInfo* disk_info;
+
+ DiskStatList = new_ctnr();
+ DiskStatSM = sm;
+
+ updateDiskStat();
+
+ registerMonitor("partitions/list", "listview", printDiskStat, printDiskStatInfo, DiskStatSM);
+
+ for (disk_info = first_ctnr(DiskStatList); disk_info; disk_info = next_ctnr(DiskStatList)) {
+ snprintf(monitor, sizeof(monitor), "partitions%s/usedspace", disk_info->mntpnt);
+ registerMonitor(monitor, "integer", printDiskStatUsed, printDiskStatUsedInfo, DiskStatSM);
+ snprintf(monitor, sizeof(monitor), "partitions%s/freespace", disk_info->mntpnt);
+ registerMonitor(monitor, "integer", printDiskStatFree, printDiskStatFreeInfo, DiskStatSM);
+ snprintf(monitor, sizeof(monitor), "partitions%s/filllevel", disk_info->mntpnt);
+ registerMonitor(monitor, "integer", printDiskStatPercent, printDiskStatPercentInfo, DiskStatSM);
+ }
+}
+
+void checkDiskStat(void)
+{
+ if (numMntPnt() != level_ctnr(DiskStatList)) {
+ /* a filesystem was mounted or unmounted
+ so we do a reset */
+ exitDiskStat();
+ initDiskStat(DiskStatSM);
+ }
+}
+
+void exitDiskStat(void)
+{
+ DiskInfo *disk_info;
+ char monitor[1024];
+
+ removeMonitor("partitions/list");
+
+ for (disk_info = first_ctnr(DiskStatList); disk_info; disk_info = next_ctnr(DiskStatList)) {
+ snprintf(monitor, sizeof(monitor), "partitions%s/usedspace", disk_info->mntpnt);
+ removeMonitor(monitor);
+ snprintf(monitor, sizeof(monitor), "partitions%s/freespace", disk_info->mntpnt);
+ removeMonitor(monitor);
+ snprintf(monitor, sizeof(monitor), "partitions%s/filllevel", disk_info->mntpnt);
+ removeMonitor(monitor);
+ }
+
+ destr_ctnr(DiskStatList, free);
+}
+
+int updateDiskStat(void)
+{
+ struct statfs *fs_info;
+ struct statfs fs;
+ float percent;
+ int i, mntcount;
+ DiskInfo *disk_info;
+
+ /* let's hope there is no difference between the DiskStatList and
+ the number of mounted filesystems */
+ for (i = level_ctnr(DiskStatList); i >= 0; --i)
+ free(pop_ctnr(DiskStatList));
+
+ mntcount = getmntinfo(&fs_info, MNT_WAIT);
+
+ for (i = 0; i < mntcount; i++) {
+ fs = fs_info[i];
+ if (strcmp(fs.f_fstypename, "procfs") && strcmp(fs.f_fstypename, "devfs") && strcmp(fs.f_fstypename, "devfs")) {
+
+ if ( fs.f_blocks != 0 )
+ {
+ percent = (((float)fs.f_blocks - (float)fs.f_bfree)/(float)fs.f_blocks);
+ percent = percent * 100;
+ }
+ else
+ percent = 0;
+
+ if ((disk_info = (DiskInfo *)malloc(sizeof(DiskInfo))) == NULL) {
+ continue;
+ }
+ memset(disk_info, 0, sizeof(DiskInfo));
+ strlcpy(disk_info->device, fs.f_mntfromname, sizeof(disk_info->device));
+ if (!strcmp(fs.f_mntonname, "/")) {
+ strncpy(disk_info->mntpnt, "/root", 6);
+ } else {
+ strlcpy(disk_info->mntpnt, fs.f_mntonname, sizeof(disk_info->mntpnt));
+ }
+ disk_info->blocks = fs.f_blocks;
+ disk_info->bfree = fs.f_bfree;
+ disk_info->bused = (fs.f_blocks - fs.f_bfree);
+ disk_info->bused_percent = (int)percent;
+
+ push_ctnr(DiskStatList, disk_info);
+ }
+ }
+
+ return 0;
+}
+
+void printDiskStat(const char* cmd)
+{
+ DiskInfo* disk_info;
+
+ for (disk_info = first_ctnr(DiskStatList); disk_info; disk_info = next_ctnr(DiskStatList)) {
+ fprintf(CurrentClient, "%s\t%ld\t%ld\t%ld\t%d\t%s\n",
+ disk_info->device,
+ disk_info->blocks,
+ disk_info->bused,
+ disk_info->bfree,
+ disk_info->bused_percent,
+ disk_info->mntpnt);
+ }
+
+ fprintf(CurrentClient, "\n");
+}
+
+void printDiskStatInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Device\tBlocks\tUsed\tAvailable\tUsed %%\tMountPoint\nM\tD\tD\tD\td\ts\n");
+}
+
+void printDiskStatUsed(const char* cmd)
+{
+ DiskInfo* disk_info;
+ char *mntpnt = (char *)getMntPnt(cmd);
+
+ for (disk_info = first_ctnr(DiskStatList); disk_info; disk_info = next_ctnr(DiskStatList)) {
+ if (!strcmp(mntpnt, disk_info->mntpnt)) {
+ fprintf(CurrentClient, "%ld\n", disk_info->bused);
+ }
+ }
+
+ fprintf(CurrentClient, "\n");
+}
+
+void printDiskStatUsedInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Used Blocks\t0\t-\tBlocks\n");
+}
+
+void printDiskStatFree(const char* cmd)
+{
+ DiskInfo* disk_info;
+ char *mntpnt = (char *)getMntPnt(cmd);
+
+ for (disk_info = first_ctnr(DiskStatList); disk_info; disk_info = next_ctnr(DiskStatList)) {
+ if (!strcmp(mntpnt, disk_info->mntpnt)) {
+ fprintf(CurrentClient, "%ld\n", disk_info->bfree);
+ }
+ }
+
+ fprintf(CurrentClient, "\n");
+}
+
+void printDiskStatFreeInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Free Blocks\t0\t-\tBlocks\n");
+}
+
+void printDiskStatPercent(const char* cmd)
+{
+ DiskInfo* disk_info;
+ char *mntpnt = (char *)getMntPnt(cmd);
+
+ for (disk_info = first_ctnr(DiskStatList); disk_info; disk_info = next_ctnr(DiskStatList)) {
+ if (!strcmp(mntpnt, disk_info->mntpnt)) {
+ fprintf(CurrentClient, "%d\n", disk_info->bused_percent);
+ }
+ }
+
+ fprintf(CurrentClient, "\n");
+}
+
+void printDiskStatPercentInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Used Blocks\t0\t100\t%%\n");
+}
diff --git a/ksysguard/ksysguardd/FreeBSD/diskstat.h b/ksysguard/ksysguardd/FreeBSD/diskstat.h
new file mode 100644
index 000000000..06f247837
--- /dev/null
+++ b/ksysguard/ksysguardd/FreeBSD/diskstat.h
@@ -0,0 +1,40 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _diskstat_h_
+#define _diskstat_h_
+
+void initDiskStat(struct SensorModul* sm);
+void exitDiskStat(void);
+
+int updateDiskStat(void);
+void checkDiskStat(void);
+
+void printDiskStat(const char* cmd);
+void printDiskStatInfo(const char* cmd);
+
+void printDiskStatUsed(const char* cmd);
+void printDiskStatUsedInfo(const char* cmd);
+void printDiskStatFree(const char* cmd);
+void printDiskStatFreeInfo(const char* cmd);
+void printDiskStatPercent(const char* cmd);
+void printDiskStatPercentInfo(const char* cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/FreeBSD/loadavg.c b/ksysguard/ksysguardd/FreeBSD/loadavg.c
new file mode 100644
index 000000000..53eb9fc4e
--- /dev/null
+++ b/ksysguard/ksysguardd/FreeBSD/loadavg.c
@@ -0,0 +1,96 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "Command.h"
+#include "ksysguardd.h"
+#include "loadavg.h"
+
+static double LoadAvg[3];
+
+/*
+================================ public part =================================
+*/
+
+void
+initLoadAvg(struct SensorModul* sm)
+{
+ if (updateLoadAvg() < 0)
+ return;
+
+ registerMonitor("cpu/loadavg1", "float", printLoadAvg1,
+ printLoadAvg1Info, sm);
+ registerMonitor("cpu/loadavg5", "float", printLoadAvg5,
+ printLoadAvg5Info, sm);
+ registerMonitor("cpu/loadavg15", "float", printLoadAvg15,
+ printLoadAvg15Info, sm);
+}
+
+void
+exitLoadAvg(void)
+{
+ removeMonitor("cpu/loadavg1");
+ removeMonitor("cpu/loadavg5");
+ removeMonitor("cpu/loadavg15");
+}
+
+int
+updateLoadAvg(void)
+{
+ return getloadavg(LoadAvg, 3);
+}
+
+void
+printLoadAvg1(const char* c)
+{
+ fprintf(CurrentClient, "%f\n", LoadAvg[0]);
+}
+
+void
+printLoadAvg1Info(const char* c)
+{
+ fprintf(CurrentClient, "Load average 1 min\t0\t0\t\n");
+}
+
+void
+printLoadAvg5(const char* c)
+{
+ fprintf(CurrentClient, "%f\n", LoadAvg[1]);
+}
+
+void
+printLoadAvg5Info(const char* c)
+{
+ fprintf(CurrentClient, "Load average 5 min\t0\t0\t\n");
+}
+
+void
+printLoadAvg15(const char* c)
+{
+ fprintf(CurrentClient, "%f\n", LoadAvg[2]);
+}
+
+void
+printLoadAvg15Info(const char* c)
+{
+ fprintf(CurrentClient, "Load average 15 min\t0\t0\t\n");
+}
diff --git a/ksysguard/ksysguardd/FreeBSD/loadavg.h b/ksysguard/ksysguardd/FreeBSD/loadavg.h
new file mode 100644
index 000000000..801e4ef8d
--- /dev/null
+++ b/ksysguard/ksysguardd/FreeBSD/loadavg.h
@@ -0,0 +1,36 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _loadavg_h_
+#define _loadavg_h_
+
+void initLoadAvg(struct SensorModul* sm);
+void exitLoadAvg(void);
+
+int updateLoadAvg(void);
+
+void printLoadAvg1(const char*);
+void printLoadAvg1Info(const char*);
+void printLoadAvg5(const char*);
+void printLoadAvg5Info(const char*);
+void printLoadAvg15(const char*);
+void printLoadAvg15Info(const char*);
+
+#endif
diff --git a/ksysguard/ksysguardd/FreeBSD/logfile.c b/ksysguard/ksysguardd/FreeBSD/logfile.c
new file mode 100644
index 000000000..3b07ad8ac
--- /dev/null
+++ b/ksysguard/ksysguardd/FreeBSD/logfile.c
@@ -0,0 +1,175 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Command.h"
+#include "ccont.h"
+#include "conf.h"
+#include "ksysguardd.h"
+#include "logfile.h"
+
+static CONTAINER LogFiles = 0;
+static unsigned long counter = 1;
+
+typedef struct {
+ char name[256];
+ FILE* fh;
+ unsigned long id;
+} LogFileEntry;
+
+extern CONTAINER LogFileList;
+
+/*
+================================ public part =================================
+*/
+
+void initLogFile(struct SensorModul* sm)
+{
+ char monitor[1024];
+ ConfigLogFile *entry;
+
+ registerCommand("logfile_register", registerLogFile);
+ registerCommand("logfile_unregister", unregisterLogFile);
+ registerCommand("logfile_registered", printRegistered);
+
+ for (entry = first_ctnr(LogFileList); entry; entry = next_ctnr(LogFileList))
+ {
+ FILE* fp;
+
+ /* register the log file if we can actually read the file. */
+ if ((fp = fopen(entry->path, "r")) != NULL)
+ {
+ fclose(fp);
+ snprintf(monitor, 1024, "logfiles/%s", entry->name);
+ registerMonitor(monitor, "logfile", printLogFile,
+ printLogFileInfo, sm);
+ }
+ }
+
+ LogFiles = new_ctnr();
+}
+
+void exitLogFile(void)
+{
+ destr_ctnr(LogFiles, free);
+}
+
+void printLogFile(const char* cmd)
+{
+ char line[1024];
+ unsigned long id;
+ int i;
+ char ch;
+ LogFileEntry *entry;
+
+ sscanf(cmd, "%*s %lu", &id);
+
+ for (entry = first_ctnr(LogFiles); entry; entry = next_ctnr(LogFiles)) {
+ if (entry->id == id) {
+ while (fgets(line, sizeof(line), entry->fh) != NULL) {
+ fprintf(CurrentClient, "%s", line);
+ }
+ clearerr(entry->fh);
+ }
+ }
+
+ fprintf(CurrentClient, "\n");
+}
+
+void printLogFileInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "LogFile\n");
+}
+
+void registerLogFile(const char* cmd)
+{
+ char name[257];
+ FILE* file;
+ LogFileEntry *entry;
+ ConfigLogFile *conf;
+
+ memset(name, 0, sizeof(name));
+ sscanf(cmd, "%*s %256s", name);
+
+ for (conf = first_ctnr(LogFileList); conf; conf = next_ctnr(LogFileList)) {
+ if (!strcmp(conf->name, name)) {
+ if ((file = fopen(conf->path, "r")) == NULL) {
+ print_error("fopen()");
+ fprintf(CurrentClient, "0\n");
+ return;
+ }
+
+ fseek(file, 0, SEEK_END);
+
+ if ((entry = (LogFileEntry *)malloc(sizeof(LogFileEntry))) == NULL) {
+ print_error("malloc()");
+ fprintf(CurrentClient, "0\n");
+ return;
+ }
+
+ entry->fh = file;
+ strlcpy(entry->name, conf->name, sizeof(entry->name));
+ entry->id = counter;
+
+ push_ctnr(LogFiles, entry);
+
+ fprintf(CurrentClient, "%lu\n", counter);
+ counter++;
+
+ return;
+ }
+ }
+
+ fprintf(CurrentClient, "0\n");
+}
+
+void unregisterLogFile(const char* cmd)
+{
+ unsigned long id;
+ LogFileEntry *entry;
+
+ sscanf(cmd, "%*s %lu", &id);
+
+ for (entry = first_ctnr(LogFiles); entry; entry = next_ctnr(LogFiles)) {
+ if (entry->id == id) {
+ fclose(entry->fh);
+ free(remove_ctnr(LogFiles));
+ fprintf(CurrentClient, "\n");
+ return;
+ }
+ }
+
+ fprintf(CurrentClient, "\n");
+}
+
+void printRegistered(const char* cmd)
+{
+ LogFileEntry *entry;
+
+ for (entry = first_ctnr(LogFiles); entry; entry = next_ctnr(LogFiles))
+ fprintf(CurrentClient, "%s:%lu\n", entry->name, entry->id);
+
+ fprintf(CurrentClient, "\n");
+}
diff --git a/ksysguard/ksysguardd/FreeBSD/logfile.h b/ksysguard/ksysguardd/FreeBSD/logfile.h
new file mode 100644
index 000000000..45ade9013
--- /dev/null
+++ b/ksysguard/ksysguardd/FreeBSD/logfile.h
@@ -0,0 +1,36 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _logfile_h_
+#define _logfile_h_
+
+void initLogFile(struct SensorModul* sm);
+void exitLogFile(void);
+
+void printLogFile(const char* cmd);
+void printLogFileInfo(const char* cmd);
+
+void registerLogFile(const char* cmd);
+void unregisterLogFile(const char* cmd);
+
+/* debug command */
+void printRegistered(const char* cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/FreeBSD/netdev.c b/ksysguard/ksysguardd/FreeBSD/netdev.c
new file mode 100644
index 000000000..cec8be590
--- /dev/null
+++ b/ksysguard/ksysguardd/FreeBSD/netdev.c
@@ -0,0 +1,353 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+
+#include <net/if.h>
+#include <net/if_mib.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "Command.h"
+#include "ksysguardd.h"
+#include "netdev.h"
+
+
+typedef struct {
+ char name[32];
+ u_long recBytes;
+ u_long recPacks;
+ u_long recErrs;
+ u_long recDrop;
+ u_long recMulticast;
+ u_long sentBytes;
+ u_long sentPacks;
+ u_long sentErrs;
+ u_long sentMulticast;
+ u_long sentColls;
+} NetDevInfo;
+
+#define MAXNETDEVS 64
+static NetDevInfo NetDevs[MAXNETDEVS];
+static NetDevInfo NetDevsOld[MAXNETDEVS];
+static int NetDevCnt = 0;
+static struct SensorModul* NetDevSM;
+
+static float elapsed = 0.0;
+static struct timeval old_tv;
+
+char **parseCommand(const char *cmd)
+{
+ char *tmp_cmd = strdup(cmd);
+ char *begin;
+ char **retval = malloc(sizeof(char *)*2);
+
+ begin = rindex(tmp_cmd, '/');
+ *begin = '\0';
+ begin++;
+ retval[1] = strdup((const char *)begin); /* sensor */
+
+ begin = rindex(tmp_cmd, '/');
+ *begin = '\0';
+ begin = rindex(tmp_cmd, '/');
+ begin++;
+ retval[0] = strdup((const char *)begin); /* interface */
+ free(tmp_cmd);
+
+ return retval;
+}
+
+int numActivIfaces(void)
+{
+ int counter = 0;
+ int name[6];
+ int num_iface, i;
+ size_t len;
+ struct ifmibdata ifmd;
+
+ len = sizeof(num_iface);
+ sysctlbyname("net.link.generic.system.ifcount", &num_iface, &len, NULL, 0);
+
+ for (i = 1; i < num_iface + 1; i++) {
+ name[0] = CTL_NET;
+ name[1] = PF_LINK;
+ name[2] = NETLINK_GENERIC;
+ name[3] = IFMIB_IFDATA;
+ name[4] = i;
+ name[5] = IFDATA_GENERAL;
+
+ len = sizeof(ifmd);
+ sysctl(name, 6, &ifmd, &len, NULL, 0);
+ if (ifmd.ifmd_flags & IFF_UP)
+ counter++;
+ }
+
+ return counter;
+}
+
+/* ------------------------------ public part --------------------------- */
+
+void initNetDev(struct SensorModul* sm)
+{
+ int i;
+ char monitor[1024];
+ gettimeofday(&old_tv, (struct timezone *)0);
+
+ NetDevSM = sm;
+
+ updateNetDev();
+
+ for (i = 0; i < NetDevCnt; i++) {
+ /* init data */
+ NetDevsOld[i] = NetDevs[i];
+
+ /* register monitors */
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/receiver/data", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevRecBytes, printNetDevRecBytesInfo, NetDevSM);
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/receiver/packets", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevRecBytes, printNetDevRecBytesInfo, NetDevSM);
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/receiver/errors", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevRecBytes, printNetDevRecBytesInfo, NetDevSM);
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/receiver/drops", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevRecBytes, printNetDevRecBytesInfo, NetDevSM);
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/receiver/multicast", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevRecBytes, printNetDevRecBytesInfo, NetDevSM);
+
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/transmitter/data", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevSentBytes, printNetDevSentBytesInfo, NetDevSM);
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/transmitter/packets", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevSentBytes, printNetDevSentBytesInfo, NetDevSM);
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/transmitter/errors", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevSentBytes, printNetDevSentBytesInfo, NetDevSM);
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/transmitter/multicast", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevSentBytes, printNetDevSentBytesInfo, NetDevSM);
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/transmitter/collisions", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevSentBytes, printNetDevSentBytesInfo, NetDevSM);
+ }
+}
+
+void exitNetDev(void)
+{
+ int i;
+ char monitor[1024];
+
+ for (i = 0; i < NetDevCnt; i++) {
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/receiver/data", NetDevs[i].name);
+ removeMonitor(monitor);
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/receiver/packets", NetDevs[i].name);
+ removeMonitor(monitor);
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/receiver/errors", NetDevs[i].name);
+ removeMonitor(monitor);
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/receiver/drops", NetDevs[i].name);
+ removeMonitor(monitor);
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/receiver/multicast", NetDevs[i].name);
+ removeMonitor(monitor);
+
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/transmitter/data", NetDevs[i].name);
+ removeMonitor(monitor);
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/transmitter/packets", NetDevs[i].name);
+ removeMonitor(monitor);
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/transmitter/errors", NetDevs[i].name);
+ removeMonitor(monitor);
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/transmitter/multicast", NetDevs[i].name);
+ removeMonitor(monitor);
+ snprintf(monitor, sizeof(monitor), "network/interfaces/%s/transmitter/collisions", NetDevs[i].name);
+ removeMonitor(monitor);
+ }
+}
+
+int updateNetDev(void)
+{
+ int name[6];
+ int num_iface, i;
+ size_t len;
+ struct ifmibdata ifmd;
+ struct timeval new_tv, tv;
+
+ len = sizeof(num_iface);
+ sysctlbyname("net.link.generic.system.ifcount", &num_iface, &len, NULL, 0);
+
+ NetDevCnt = 0;
+ for (i = 1; i < num_iface + 1; i++) {
+ name[0] = CTL_NET;
+ name[1] = PF_LINK;
+ name[2] = NETLINK_GENERIC;
+ name[3] = IFMIB_IFDATA;
+ name[4] = i;
+ name[5] = IFDATA_GENERAL;
+
+ len = sizeof(ifmd);
+ sysctl(name, 6, &ifmd, &len, NULL, 0);
+ if (ifmd.ifmd_flags & IFF_UP) {
+ NetDevsOld[NetDevCnt] = NetDevs[NetDevCnt];
+
+ strlcpy(NetDevs[NetDevCnt].name, ifmd.ifmd_name, sizeof(NetDevs[NetDevCnt].name));
+ NetDevs[NetDevCnt].recBytes = ifmd.ifmd_data.ifi_ibytes;
+ NetDevs[NetDevCnt].recPacks = ifmd.ifmd_data.ifi_ipackets;
+ NetDevs[NetDevCnt].recErrs = ifmd.ifmd_data.ifi_ierrors;
+ NetDevs[NetDevCnt].recDrop = ifmd.ifmd_data.ifi_iqdrops;
+ NetDevs[NetDevCnt].recMulticast = ifmd.ifmd_data.ifi_imcasts;
+ NetDevs[NetDevCnt].sentBytes = ifmd.ifmd_data.ifi_obytes;
+ NetDevs[NetDevCnt].sentPacks = ifmd.ifmd_data.ifi_opackets;
+ NetDevs[NetDevCnt].sentErrs = ifmd.ifmd_data.ifi_oerrors;
+ NetDevs[NetDevCnt].sentMulticast = ifmd.ifmd_data.ifi_omcasts;
+ NetDevs[NetDevCnt].sentColls = ifmd.ifmd_data.ifi_collisions;
+ NetDevCnt++;
+ }
+ }
+
+ gettimeofday(&new_tv, (struct timezone *)0);
+ timersub(&new_tv, &old_tv, &tv);
+ elapsed = tv.tv_sec + (tv.tv_usec * 1e-6);
+ old_tv = new_tv;
+
+ return 0;
+}
+
+void checkNetDev(void)
+{
+ if (numActivIfaces() != NetDevCnt) {
+ /* interface has been added or removed
+ so we do a reset */
+ exitNetDev();
+ initNetDev(NetDevSM);
+ }
+}
+
+void printNetDevRecBytes(const char *cmd)
+{
+ int i;
+ char **retval;
+
+ retval = parseCommand(cmd);
+
+ if (retval == NULL)
+ return;
+
+ for (i = 0; i < NetDevCnt; i++) {
+ if (!strcmp(NetDevs[i].name, retval[0])) {
+ if (!strncmp(retval[1], "data", 4))
+ fprintf(CurrentClient, "%lu", (u_long)((NetDevs[i].recBytes - NetDevsOld[i].recBytes) / (1024 * elapsed)));
+ if (!strncmp(retval[1], "packets", 7))
+ fprintf(CurrentClient, "%lu", (u_long)((NetDevs[i].recPacks - NetDevsOld[i].recPacks) / elapsed));
+ if (!strncmp(retval[1], "errors", 6))
+ fprintf(CurrentClient, "%lu", (u_long)((NetDevs[i].recErrs - NetDevsOld[i].recErrs) / elapsed));
+ if (!strncmp(retval[1], "drops", 5))
+ fprintf(CurrentClient, "%lu", (u_long)((NetDevs[i].recDrop - NetDevsOld[i].recDrop) / elapsed));
+ if (!strncmp(retval[1], "multicast", 9))
+ fprintf(CurrentClient, "%lu", (u_long)((NetDevs[i].recMulticast - NetDevsOld[i].recMulticast) / elapsed));
+ }
+ }
+ free(retval[0]);
+ free(retval[1]);
+ free(retval);
+
+ fprintf(CurrentClient, "\n");
+}
+
+void printNetDevRecBytesInfo(const char *cmd)
+{
+ char **retval;
+
+ retval = parseCommand(cmd);
+
+ if (retval == NULL)
+ return;
+
+ if (!strncmp(retval[1], "data", 4))
+ fprintf(CurrentClient, "Received Data\t0\t0\tkBytes/s\n");
+ if (!strncmp(retval[1], "packets", 7))
+ fprintf(CurrentClient, "Received Packets\t0\t0\t1/s\n");
+ if (!strncmp(retval[1], "errors", 6))
+ fprintf(CurrentClient, "Receiver Errors\t0\t0\t1/s\n");
+ if (!strncmp(retval[1], "drops", 5))
+ fprintf(CurrentClient, "Receiver Drops\t0\t0\t1/s\n");
+ if (!strncmp(retval[1], "multicast", 9))
+ fprintf(CurrentClient, "Received Multicast Packets\t0\t0\t1/s\n");
+
+ free(retval[0]);
+ free(retval[1]);
+ free(retval);
+}
+
+void printNetDevSentBytes(const char *cmd)
+{
+ int i;
+ char **retval;
+
+ retval = parseCommand(cmd);
+
+ if (retval == NULL)
+ return;
+
+ for (i = 0; i < NetDevCnt; i++) {
+ if (!strcmp(NetDevs[i].name, retval[0])) {
+ if (!strncmp(retval[1], "data", 4))
+ fprintf(CurrentClient, "%lu", (u_long)((NetDevs[i].sentBytes - NetDevsOld[i].sentBytes) / (1024 * elapsed)));
+ if (!strncmp(retval[1], "packets", 7))
+ fprintf(CurrentClient, "%lu", (u_long)((NetDevs[i].sentPacks - NetDevsOld[i].sentPacks) / elapsed));
+ if (!strncmp(retval[1], "errors", 6))
+ fprintf(CurrentClient, "%lu", (u_long)((NetDevs[i].sentErrs - NetDevsOld[i].sentErrs) / elapsed));
+ if (!strncmp(retval[1], "multicast", 9))
+ fprintf(CurrentClient, "%lu", (u_long)((NetDevs[i].sentMulticast - NetDevsOld[i].sentMulticast) / elapsed));
+ if (!strncmp(retval[1], "collisions", 10))
+ fprintf(CurrentClient, "%lu", (u_long)((NetDevs[i].sentColls - NetDevsOld[i].sentColls) / elapsed));
+ }
+ }
+ free(retval[0]);
+ free(retval[1]);
+ free(retval);
+
+ fprintf(CurrentClient, "\n");
+}
+
+void printNetDevSentBytesInfo(const char *cmd)
+{
+ char **retval;
+
+ retval = parseCommand(cmd);
+
+ if (retval == NULL)
+ return;
+
+ if (!strncmp(retval[1], "data", 4))
+ fprintf(CurrentClient, "Sent Data\t0\t0\tkBytes/s\n");
+ if (!strncmp(retval[1], "packets", 7))
+ fprintf(CurrentClient, "Sent Packets\t0\t0\t1/s\n");
+ if (!strncmp(retval[1], "errors", 6))
+ fprintf(CurrentClient, "Transmitter Errors\t0\t0\t1/s\n");
+ if (!strncmp(retval[1], "multicast", 9))
+ fprintf(CurrentClient, "Sent Multicast Packets\t0\t0\t1/s\n");
+ if (!strncmp(retval[1], "collisions", 10))
+ fprintf(CurrentClient, "Transmitter Collisions\t0\t0\t1/s\n");
+
+ free(retval[0]);
+ free(retval[1]);
+ free(retval);
+}
diff --git a/ksysguard/ksysguardd/FreeBSD/netdev.h b/ksysguard/ksysguardd/FreeBSD/netdev.h
new file mode 100644
index 000000000..17d9c89e9
--- /dev/null
+++ b/ksysguard/ksysguardd/FreeBSD/netdev.h
@@ -0,0 +1,35 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _netdev_h_
+#define _netdev_h_
+
+void initNetDev(struct SensorModul* sm);
+void exitNetDev(void);
+
+int updateNetDev(void);
+void checkNetDev(void);
+
+void printNetDevRecBytes(const char* cmd);
+void printNetDevRecBytesInfo(const char* cmd);
+void printNetDevSentBytes(const char* cmd);
+void printNetDevSentBytesInfo(const char* cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/Irix/LoadAvg.c b/ksysguard/ksysguardd/Irix/LoadAvg.c
new file mode 100644
index 000000000..92d284756
--- /dev/null
+++ b/ksysguard/ksysguardd/Irix/LoadAvg.c
@@ -0,0 +1,78 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999, 2000 Chris Schlaeger <cs@kde.org>
+
+ Irix support by Carsten Kroll <CKroll@pinnaclesys.com>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/swap.h>
+
+#include "config.h"
+
+#include "ksysguardd.h"
+#include "Command.h"
+#include "LoadAvg.h"
+
+double loadavg1 = 0.0;
+double loadavg5 = 0.0;
+double loadavg15 = 0.0;
+
+void initLoadAvg(struct SensorModul* sm ) {
+ registerMonitor( "cpu/loadavg1", "float",
+ printLoadAvg1, printLoadAvg1Info, sm );
+ registerMonitor( "cpu/loadavg5", "float",
+ printLoadAvg5, printLoadAvg5Info, sm );
+ registerMonitor( "cpu/loadavg15", "float",
+ printLoadAvg15, printLoadAvg15Info, sm );
+}
+
+void exitLoadAvg( void ) {
+}
+
+int updateLoadAvg( void ) {
+
+ return( 0 );
+}
+
+void printLoadAvg1Info( const char *cmd ) {
+ fprintf(CurrentClient, "avnrun 1min\t0\t0\n" );
+}
+
+void printLoadAvg1( const char *cmd ) {
+ fprintf(CurrentClient, "%f\n", loadavg1 );
+}
+
+void printLoadAvg5Info( const char *cmd ) {
+ fprintf(CurrentClient, "avnrun 5min\t0\t0\n" );
+}
+
+void printLoadAvg5( const char *cmd ) {
+ fprintf(CurrentClient, "%f\n", loadavg5 );
+}
+
+void printLoadAvg15Info( const char *cmd ) {
+ fprintf(CurrentClient, "avnrun 15min\t0\t0\n" );
+}
+
+void printLoadAvg15( const char *cmd ) {
+ fprintf(CurrentClient, "%f\n", loadavg15 );
+}
diff --git a/ksysguard/ksysguardd/Irix/LoadAvg.h b/ksysguard/ksysguardd/Irix/LoadAvg.h
new file mode 100644
index 000000000..eea8ad82e
--- /dev/null
+++ b/ksysguard/ksysguardd/Irix/LoadAvg.h
@@ -0,0 +1,41 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ Solaris support by Torsten Kasch <tk@Genetik.Uni-Bielefeld.DE>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _LoadAvg_h_
+#define _LoadAvg_h_
+
+#define LOAD(a) ((double)(a) / (1 << 8 ))
+
+void initLoadAvg(struct SensorModul* sm);
+void exitLoadAvg(void);
+
+int updateLoadAvg(void);
+
+void printLoadAvg1( const char *cmd );
+void printLoadAvg1Info( const char *cmd );
+void printLoadAvg5( const char *cmd );
+void printLoadAvg5Info( const char *cmd );
+void printLoadAvg15( const char *cmd );
+void printLoadAvg15Info( const char *cmd );
+
+#endif /* _LoadAvg_h_ */
diff --git a/ksysguard/ksysguardd/Irix/Makefile.am b/ksysguard/ksysguardd/Irix/Makefile.am
new file mode 100644
index 000000000..3c1997924
--- /dev/null
+++ b/ksysguard/ksysguardd/Irix/Makefile.am
@@ -0,0 +1,4 @@
+INCLUDES = -I$(srcdir)/../../CContLib -I..
+
+noinst_LIBRARIES = libksysguardd.a
+libksysguardd_a_SOURCES = Memory.c LoadAvg.c ProcessList.c NetDev.c cpu.c
diff --git a/ksysguard/ksysguardd/Irix/Memory.c b/ksysguard/ksysguardd/Irix/Memory.c
new file mode 100644
index 000000000..e88123ddd
--- /dev/null
+++ b/ksysguard/ksysguardd/Irix/Memory.c
@@ -0,0 +1,128 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999, 2000 Chris Schlaeger <cs@kde.org>
+
+ Irix support by Carsten Kroll <ckroll@pinnaclesys.com>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/statfs.h>
+#include <sys/swap.h>
+#include <sys/sysmp.h>
+
+#include "config.h"
+
+#include "ksysguardd.h"
+#include "Command.h"
+#include "Memory.h"
+
+static int Dirty = 1;
+static t_memsize totalmem = (t_memsize) 0;
+static t_memsize freemem = (t_memsize) 0;
+static unsigned long totalswap = 0L,vswap = 0L;
+static unsigned long freeswap = 0L,bufmem = 0L ;
+
+void initMemory( struct SensorModul* sm ) {
+
+ registerMonitor( "mem/physical/free", "integer",
+ printMemFree, printMemFreeInfo, sm );
+ registerMonitor( "mem/physical/used", "integer",
+ printMemUsed, printMemUsedInfo, sm );
+ registerMonitor( "mem/swap/free", "integer",
+ printSwapFree, printSwapFreeInfo, sm );
+ registerMonitor( "mem/swap/used", "integer",
+ printSwapUsed, printSwapUsedInfo, sm );
+}
+
+void exitMemory( void ) {
+}
+
+int updateMemory( void ) {
+ struct statfs sf;
+ off_t val;
+ int pagesize = getpagesize();
+ struct rminfo rmi;
+ if( sysmp(MP_SAGET, MPSA_RMINFO, &rmi, sizeof(rmi)) == -1 )
+ return( -1 );
+ totalmem = rmi.physmem*pagesize/1024; // total physical memory (without swaps)
+ freemem = rmi.freemem*pagesize/1024; // total free physical memory (without swaps)
+ bufmem = rmi.bufmem *pagesize/1024;
+
+ statfs ("/proc", &sf,sizeof(sf),0);
+
+ swapctl(SC_GETSWAPVIRT,&val);
+ vswap = val >> 1;
+ swapctl(SC_GETSWAPTOT,&val);
+ totalswap = val >> 1;
+ swapctl(SC_GETFREESWAP,&val);
+ freeswap = val >> 1;
+
+ Dirty = 1;
+
+ return( 0 );
+}
+
+void printMemFreeInfo( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "Free Memory\t0\t%ld\tKB\n", freemem );
+}
+
+void printMemFree( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "%ld\n", freemem );
+}
+
+void printMemUsedInfo( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "Used Memory\t0\t%ld\tKB\n", totalmem - freemem );
+}
+
+void printMemUsed( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "%ld\n", totalmem - freemem );
+}
+
+void printSwapFreeInfo( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "Free Swap\t0\t%ld\tKB\n", freeswap );
+}
+
+void printSwapFree( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "%ld\n", freeswap );
+}
+void printSwapUsedInfo( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "Used Swap\t0\t%ld\tKB\n", totalswap - freeswap );
+}
+
+void printSwapUsed( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "%ld\n", totalswap - freeswap );
+}
diff --git a/ksysguard/ksysguardd/Irix/Memory.h b/ksysguard/ksysguardd/Irix/Memory.h
new file mode 100644
index 000000000..ac3677b13
--- /dev/null
+++ b/ksysguard/ksysguardd/Irix/Memory.h
@@ -0,0 +1,46 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ Irix support by Carsten Kroll <ckroll@pinnaclesys.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _Memory_h_
+#define _Memory_h_
+
+typedef unsigned long t_memsize;
+
+void initMemory(struct SensorModul* sm);
+void exitMemory(void);
+
+int updateMemory(void);
+
+void printMemFree( const char *cmd );
+void printMemFreeInfo( const char *cmd );
+void printMemUsed( const char *cmd );
+void printMemUsedInfo( const char *cmd );
+void printMemBuff( const char *cmd);
+void printMemBuffInfo( const char *cmd);
+
+void printSwapFree( const char *cmd );
+void printSwapFreeInfo( const char *cmd );
+void printSwapUsed( const char *cmd );
+void printSwapUsedInfo( const char *cmd );
+
+#endif /* _Memory_h */
diff --git a/ksysguard/ksysguardd/Irix/NetDev.c b/ksysguard/ksysguardd/Irix/NetDev.c
new file mode 100644
index 000000000..80bc2b310
--- /dev/null
+++ b/ksysguard/ksysguardd/Irix/NetDev.c
@@ -0,0 +1,343 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+ Irix Support by Carsten Kroll <ckroll@pinnaclesys.com>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/soioctl.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <invent.h>
+#include <strings.h>
+
+
+#include "Command.h"
+#include "ksysguardd.h"
+#include "NetDev.h"
+
+#ifdef __GNUC__
+#define LONGLONG long long
+#endif
+
+typedef struct {
+ char name[IFNAMSIZ];
+ u_long recBytes;
+ u_long recPacks;
+ u_long recErrs;
+ u_long recDrop;
+ u_long recMulticast;
+ u_long sentBytes;
+ u_long sentPacks;
+ u_long sentErrs;
+ u_long sentMulticast;
+ u_long sentColls;
+} NetDevInfo;
+
+#define MAXNETDEVS 32
+static NetDevInfo NetDevs[MAXNETDEVS];
+static NetDevInfo oNetDevs[MAXNETDEVS];
+static int NetDevCnt = 0;
+
+char **parseCommand(const char *cmd)
+{
+ char *tmp_cmd = strdup(cmd);
+ char *begin;
+ char *retval = malloc(sizeof(char *)*2);
+
+ begin = rindex(tmp_cmd, '/');
+ *begin = '\0';
+ begin++;
+ retval[1] = strdup(begin); // sensor
+
+ begin = rindex(tmp_cmd, '/');
+ *begin = '\0';
+ begin = rindex(tmp_cmd, '/');
+ begin++;
+ retval[0] = strdup(begin); // interface
+ free(tmp_cmd);
+
+ return retval;
+}
+
+/* ------------------------------ public part --------------------------- */
+
+void initNetDev(struct SensorModul* sm)
+{
+ int i;
+ char monitor[1024];
+
+ memset(NetDevs,0,sizeof(NetDevInfo)*MAXNETDEVS);
+ memset(oNetDevs,0,sizeof(NetDevInfo)*MAXNETDEVS);
+
+ updateNetDev();
+
+ for (i = 0; i < NetDevCnt; i++) {
+
+ sprintf(monitor,"network/interfaces/%s/receiver/packets", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevRecBytes, printNetDevRecBytesInfo, sm);
+ sprintf(monitor ,"network/interfaces/%s/receiver/errors", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevRecBytes, printNetDevRecBytesInfo, sm);
+ /*
+ [CK] I don't know how to get Bytes sent/received, if someone does please drop me a note.
+ sprintf(monitor,"network/interfaces/%s/receiver/data", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevRecBytes, printNetDevRecBytesInfo, sm);
+ sprintf(monitor,"network/interfaces/%s/receiver/drops", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevRecBytes, printNetDevRecBytesInfo, sm);
+ sprintf(monitor ,"network/interfaces/%s/receiver/multicast", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevRecBytes, printNetDevRecBytesInfo, sm);
+ */
+
+ sprintf(monitor,"network/interfaces/%s/transmitter/packets", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevSentBytes, printNetDevSentBytesInfo, sm);
+ sprintf(monitor,"network/interfaces/%s/transmitter/errors", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevSentBytes, printNetDevSentBytesInfo, sm);
+ /*
+ sprintf(monitor,"network/interfaces/%s/transmitter/data", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevSentBytes, printNetDevSentBytesInfo, sm);
+ sprintf(monitor,"network/interfaces/%s/transmitter/multicast", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevSentBytes, printNetDevSentBytesInfo, sm);
+ */
+ sprintf(monitor,"network/interfaces/%s/transmitter/collisions", NetDevs[i].name);
+ registerMonitor(monitor, "integer", printNetDevSentBytes, printNetDevSentBytesInfo, sm);
+ }
+}
+
+void exitNetDev(void)
+{
+ int i;
+ char monitor[1024];
+
+ for (i = 0; i < NetDevCnt; i++) {
+ sprintf(monitor,"network/interfaces/%s/receiver/packets", NetDevs[i].name);
+ removeMonitor(monitor);
+ sprintf(monitor,"network/interfaces/%s/receiver/errors", NetDevs[i].name);
+ removeMonitor(monitor);
+/*
+ sprintf(monitor,"network/interfaces/%s/receiver/drops", NetDevs[i].name);
+ removeMonitor(monitor);
+ sprintf(monitor,"network/interfaces/%s/receiver/multicast", NetDevs[i].name);
+ removeMonitor(monitor);
+ sprintf(monitor,"network/interfaces/%s/receiver/data", NetDevs[i].name);
+ removeMonitor(monitor);
+*/
+
+ sprintf(monitor,"network/interfaces/%s/transmitter/packets", NetDevs[i].name);
+ removeMonitor(monitor);
+ sprintf(monitor,"network/interfaces/%s/transmitter/errors", NetDevs[i].name);
+ removeMonitor(monitor);
+/*
+ sprintf(monitor,"network/interfaces/%s/transmitter/data", NetDevs[i].name);
+ removeMonitor(monitor);
+ sprintf(monitor,"network/interfaces/%s/transmitter/multicast", NetDevs[i].name);
+ removeMonitor(monitor);
+*/
+ sprintf(monitor,"network/interfaces/%s/transmitter/collisions", NetDevs[i].name);
+ removeMonitor(monitor);
+
+ }
+}
+
+int updateNetDev(void)
+{
+ int name[6];
+ int num_iface=0, i;
+ char buf[MAXNETDEVS*sizeof(struct ifreq)];
+ size_t len;
+ int s;
+ struct ifconf ifc;
+ struct ifstats *istat;
+ struct timeval tv;
+ static LONGLONG timestamp=0;
+ register LONGLONG cts,elapsed;
+ //struct ipstat ips;
+
+ if ((s=socket(PF_INET,SOCK_DGRAM,0)) < 0){
+ print_error("socket creation failed");
+ return(-1);
+ }
+
+ ifc.ifc_len = sizeof (buf);
+ ifc.ifc_buf = buf;
+ if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
+ print_error("cannot get interface configuration");
+ return(-1);
+ }
+
+ gettimeofday(&tv, 0);
+ cts = ((LONGLONG)tv.tv_sec * 100 + (LONGLONG) tv.tv_usec / 10000);/* in 10 ms unit*/
+ elapsed = cts - timestamp;
+ timestamp=cts;
+
+ NetDevCnt=0;
+
+ for (i = 0; i < MAXNETDEVS; i++) {
+ if ( *ifc.ifc_req[i].ifr_name == 0) break;
+ if (ioctl(s, SIOCGIFSTATS, &ifc.ifc_req[i]) < 0) {
+ print_error("cannot get interface statistics");
+ return (-1);
+ }
+ istat=&ifc.ifc_req[i].ifr_stats;
+ //if ( ifc.ifc_req[i].ifr_flags & IFF_UP) {
+ strncpy(NetDevs[i].name,ifc.ifc_req[i].ifr_name, IFNAMSIZ);
+ NetDevs[i].name[IFNAMSIZ-1]='\0';
+ NetDevs[i].recBytes = (istat->ifs_ipackets - oNetDevs[i].recBytes) * 100 / elapsed;
+ NetDevs[i].recPacks = (istat->ifs_ipackets - oNetDevs[i].recPacks) * 100 / elapsed;
+ NetDevs[i].recErrs = istat->ifs_ierrors - oNetDevs[i].recErrs;
+ //NetDevs[i].recDrop = istat - oNetDevs[i].recDrop;
+ //NetDevs[i].recMulticast = istat - oNetDevs[i].recMulticast;
+ NetDevs[i].sentBytes = istat->ifs_opackets - oNetDevs[i].sentBytes;
+ NetDevs[i].sentPacks = (istat->ifs_opackets - oNetDevs[i].sentPacks) * 100 / elapsed;
+ NetDevs[i].sentErrs = (istat->ifs_oerrors - oNetDevs[i].sentErrs) * 100 / elapsed;
+ //NetDevs[i].sentMulticast = istat - NetDevs[i].sentMulticast;
+ NetDevs[i].sentColls = (istat->ifs_collisions - oNetDevs[i].sentColls) *100/elapsed;
+ /* save it for the next round */
+ oNetDevs[i].recBytes = istat->ifs_ipackets;
+ oNetDevs[i].recPacks = istat->ifs_ipackets;
+ oNetDevs[i].recErrs = istat->ifs_ierrors;
+ //oNetDevs[i].recDrop =
+ //oNetDevs[i].recMulticast =
+ oNetDevs[i].sentBytes = istat->ifs_opackets;
+ oNetDevs[i].sentPacks = istat->ifs_opackets;
+ oNetDevs[i].sentErrs = istat->ifs_oerrors;
+ //oNetDevs[i].sentMulticast =
+ oNetDevs[i].sentColls = istat->ifs_collisions;
+ //}
+ NetDevCnt++;
+ }
+ close(s);
+ return (0);
+}
+
+void printNetDevRecBytes(const char *cmd)
+{
+ int i;
+ char **retval;
+
+ retval = parseCommand(cmd);
+
+ if (retval == NULL)
+ return;
+
+ for (i = 0; i < NetDevCnt; i++) {
+ if (!strcmp(NetDevs[i].name, retval[0])) {
+ if (!strncmp(retval[1], "data", 4))
+ fprintf(CurrentClient, "%lu", NetDevs[i].recBytes);
+ if (!strncmp(retval[1], "packets", 7))
+ fprintf(CurrentClient, "%lu", NetDevs[i].recPacks);
+ if (!strncmp(retval[1], "errors", 6))
+ fprintf(CurrentClient, "%lu", NetDevs[i].recErrs);
+ if (!strncmp(retval[1], "drops", 5))
+ fprintf(CurrentClient, "%lu", NetDevs[i].recDrop);
+ if (!strncmp(retval[1], "multicast", 9))
+ fprintf(CurrentClient, "%lu", NetDevs[i].recMulticast);
+ }
+ }
+ free(retval[0]);
+ free(retval[1]);
+ free(retval);
+
+ fprintf(CurrentClient, "\n");
+}
+
+void printNetDevRecBytesInfo(const char *cmd)
+{
+ char **retval;
+
+ retval = parseCommand(cmd);
+
+ if (retval == NULL)
+ return;
+
+ if (!strncmp(retval[1], "data", 4))
+ fprintf(CurrentClient, "Received Data\t0\t0\tkBytes/s\n");
+ if (!strncmp(retval[1], "packets", 7))
+ fprintf(CurrentClient, "Received Packets\t0\t0\t1/s\n");
+ if (!strncmp(retval[1], "errors", 6))
+ fprintf(CurrentClient, "Receiver Errors\t0\t0\t1/s\n");
+ if (!strncmp(retval[1], "drops", 5))
+ fprintf(CurrentClient, "Receiver Drops\t0\t0\t1/s\n");
+ if (!strncmp(retval[1], "multicast", 9))
+ fprintf(CurrentClient, "Received Multicast Packets\t0\t0\t1/s\n");
+
+ free(retval[0]);
+ free(retval[1]);
+ free(retval);
+}
+
+void printNetDevSentBytes(const char *cmd)
+{
+ int i;
+ char **retval;
+
+ retval = parseCommand(cmd);
+
+ if (retval == NULL)
+ return;
+
+ for (i = 0; i < NetDevCnt; i++) {
+ if (!strcmp(NetDevs[i].name, retval[0])) {
+ if (!strncmp(retval[1], "data", 4))
+ fprintf(CurrentClient, "%lu", NetDevs[i].sentBytes);
+ if (!strncmp(retval[1], "packets", 7))
+ fprintf(CurrentClient, "%lu", NetDevs[i].sentPacks);
+ if (!strncmp(retval[1], "errors", 6))
+ fprintf(CurrentClient, "%lu", NetDevs[i].sentErrs);
+ if (!strncmp(retval[1], "multicast", 9))
+ fprintf(CurrentClient, "%lu", NetDevs[i].sentMulticast);
+ if (!strncmp(retval[1], "collisions", 10))
+ fprintf(CurrentClient, "%lu", NetDevs[i].sentColls);
+ }
+ }
+ free(retval[0]);
+ free(retval[1]);
+ free(retval);
+
+ fprintf(CurrentClient, "\n");
+}
+
+void printNetDevSentBytesInfo(const char *cmd)
+{
+ char **retval;
+
+ retval = parseCommand(cmd);
+
+ if (retval == NULL)
+ return;
+
+ if (!strncmp(retval[1], "data", 4))
+ fprintf(CurrentClient, "Sent Data\t0\t0\tkBytes/s\n");
+ if (!strncmp(retval[1], "packets", 7))
+ fprintf(CurrentClient, "Sent Packets\t0\t0\t1/s\n");
+ if (!strncmp(retval[1], "errors", 6))
+ fprintf(CurrentClient, "Transmitter Errors\t0\t0\t1/s\n");
+ if (!strncmp(retval[1], "multicast", 9))
+ fprintf(CurrentClient, "Sent Multicast Packets\t0\t0\t1/s\n");
+ if (!strncmp(retval[1], "collisions", 10))
+ fprintf(CurrentClient, "Transmitter Collisions\t0\t0\t1/s\n");
+
+ free(retval[0]);
+ free(retval[1]);
+ free(retval);
+}
diff --git a/ksysguard/ksysguardd/Irix/NetDev.h b/ksysguard/ksysguardd/Irix/NetDev.h
new file mode 100644
index 000000000..aa30166e9
--- /dev/null
+++ b/ksysguard/ksysguardd/Irix/NetDev.h
@@ -0,0 +1,35 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+ Irix support by Carsten Kroll <ckroll@pinnaclesys.com>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _netdev_h_
+#define _netdev_h_
+
+void initNetDev(struct SensorModul* sm);
+void exitNetDev(void);
+
+int updateNetDev(void);
+
+void printNetDevRecBytes(const char* cmd);
+void printNetDevRecBytesInfo(const char* cmd);
+void printNetDevSentBytes(const char* cmd);
+void printNetDevSentBytesInfo(const char* cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/Irix/ProcessList.c b/ksysguard/ksysguardd/Irix/ProcessList.c
new file mode 100644
index 000000000..523d87d26
--- /dev/null
+++ b/ksysguard/ksysguardd/Irix/ProcessList.c
@@ -0,0 +1,462 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999, 2000 Chris Schlaeger <cs@kde.org>
+
+ Irix support by Carsten Kroll <ckroll@pinnaclesys.com>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <pwd.h>
+#include <sys/resource.h>
+#include <sys/procfs.h>
+#include <sys/statfs.h>
+#include <sys/sysmp.h>
+#include <sys/sysinfo.h>
+
+#include "ccont.h"
+#include "../../gui/SignalIDs.h"
+#include "ksysguardd.h"
+
+#include "Command.h"
+#include "ProcessList.h"
+
+#define BUFSIZE 1024
+#define KDEINITLEN strlen("kdeinit: ")
+
+typedef struct {
+ int alive; /* for "garbage collection" */
+ pid_t pid; /* process ID */
+ pid_t ppid; /* parent process ID */
+ uid_t uid; /* process owner (real UID) */
+ gid_t gid; /* process group (real GID) */
+ char *userName; /* process owner (name) */
+ int nThreads; /* # of threads in this process */
+ int Prio; /* scheduling priority */
+ size_t Size; /* total size of process image */
+ size_t RSSize; /* resident set size */
+ char State[8]; /* process state */
+ double Time; /* CPU time for the process in 100ms */
+ double Load; /* CPU load in % */
+ char Command[PRCOMSIZ];/* command name */
+ char CmdLine[PRARGSZ];/* command line */
+ double centStamp; /* timestamp for CPU load */
+} ProcessInfo;
+
+static CONTAINER ProcessList = 0;
+static unsigned ProcessCount = 0; /* # of processes */
+static DIR *procdir; /* handle for /proc */
+static int pagesz;
+
+#define KBYTES 1024
+
+/*
+ * lwpStateName() -- return string representation of process state
+ */
+char *lwpStateName( prpsinfo_t lwpinfo ) {
+
+ static char result[8];
+
+ switch( lwpinfo.pr_sname ) {
+ case 'S':
+ sprintf( result, "%s", "sleep" );
+ break;
+ case 'R':
+ sprintf( result, "%s", "run" );
+ break;
+ case 'Z':
+ sprintf( result, "%s", "zombie" );
+ break;
+ case 'T':
+ sprintf( result, "%s", "stop" );
+ break;
+ case 'I':
+ sprintf( result, "%s", "start" );
+ break;
+ case 'X':
+ sprintf( result, "%s", "wmem" );
+ case '0':
+ sprintf( result, "%s/%d", "cpu", (int) lwpinfo.pr_sonproc );
+ break;
+ default:
+ sprintf( result, "%s", "???" );
+ break;
+ }
+
+ return( result );
+}
+
+static void validateStr( char *string ) {
+
+ char *ptr = string;
+
+ /*
+ * remove all chars that might screw up communication
+ */
+ while( *ptr != '\0' ) {
+ if( *ptr == '\t' || *ptr == '\n' || *ptr == '\r' )
+ *ptr = ' ';
+ ptr++;
+ }
+ /*
+ * make sure there's at least one char
+ */
+ if( string[0] == '\0' )
+ strcpy( string, " " );
+}
+
+static int processCmp( void *p1, void *p2 ) {
+
+ return( ((ProcessInfo *) p1)->pid - ((ProcessInfo *) p2)->pid );
+}
+
+static ProcessInfo *findProcessInList( pid_t pid ) {
+
+ ProcessInfo key;
+ long index;
+
+ key.pid = pid;
+ if( (index = search_ctnr( ProcessList, processCmp, &key )) < 0 )
+ return( NULL );
+
+ return( get_ctnr( ProcessList, index ));
+}
+
+static int updateProcess( pid_t pid ) {
+ ProcessInfo *ps;
+ int fd;
+ char buf[BUFSIZE];
+ prpsinfo_t psinfo;
+ struct passwd *pw;
+ register double newCentStamp,timeDiff, usDiff,usTime;
+ struct timeval tv;
+
+ if( (ps = findProcessInList( pid )) == NULL ) {
+ if( (ps = (ProcessInfo *) malloc( sizeof( ProcessInfo )))
+ == NULL ) {
+ print_error( "cannot malloc()\n" );
+ return( -1 );
+ }
+ ps->pid = pid;
+ ps->userName = NULL;
+ ps->alive = 0;
+
+ gettimeofday(&tv, 0);
+ ps->centStamp = (double)tv.tv_sec * 100.0 + (double)tv.tv_usec / 10000.0;
+
+ push_ctnr( ProcessList, ps );
+ bsort_ctnr( ProcessList, processCmp );
+ }
+
+ sprintf( buf, "%s/pinfo/%ld", PROCDIR, pid );
+ if( (fd = open( buf, O_RDONLY )) < 0 ) {
+ /* process terminated */
+ return( -1 );
+ }
+
+
+
+ if( ioctl(fd,PIOCPSINFO,&psinfo) < 0) {
+ print_error( "cannot read psinfo from \"%s\"\n", buf );
+ close( fd );
+ return( -1 );
+ }
+ close( fd );
+
+ ps->ppid = psinfo.pr_ppid;
+ ps->uid = psinfo.pr_uid;
+ ps->gid = psinfo.pr_gid;
+
+ pw = getpwuid( psinfo.pr_uid );
+ if( ps->userName != NULL )
+ free( ps->userName );
+ ps->userName = strdup( pw->pw_name );
+
+ strncpy (ps->State,lwpStateName( psinfo ),8);
+ ps->State[7]='\0';
+
+
+ ps->Prio = psinfo.pr_pri;
+
+ gettimeofday(&tv, 0);
+ newCentStamp = (double)tv.tv_sec * 100.0 + (double) tv.tv_usec / 10000.0;
+ usTime = (double) psinfo.pr_time.tv_sec * 100.0 + (double)psinfo.pr_time.tv_nsec / 10000000.0;
+
+ timeDiff = newCentStamp - ps->centStamp;
+ usDiff = usTime - ps->Time;
+
+ if ((timeDiff > 0.0) && (usDiff >= 0.0))
+ {
+ ps->Load = (usDiff / timeDiff) * 100.0;
+ /* During startup we get bigger loads since the time diff
+ * cannot be correct. So we force it to 0. */
+ ps->Load = (ps->Load > 100.0) ? 0.0 : ps->Load;
+ }
+ else
+ ps->Load = 0.0;
+
+ ps->centStamp = newCentStamp;
+ ps->Time = usTime;
+
+ ps->Size = (psinfo.pr_size * pagesz)/KBYTES;
+ ps->RSSize = (psinfo.pr_rssize * pagesz)/KBYTES;
+
+ strncpy(ps->Command,psinfo.pr_fname,PRCOMSIZ);
+ ps->Command[PRCOMSIZ-1]='\0';
+
+ strncpy(ps->CmdLine,psinfo.pr_psargs,PRARGSZ);
+ ps->CmdLine[PRARGSZ-1]='\0';
+
+ validateStr( ps->Command );
+ validateStr( ps->CmdLine );
+
+ ps->alive = 1;
+ return( 0 );
+}
+
+static void cleanupProcessList( void ) {
+
+ ProcessInfo *ps;
+
+ ProcessCount = 0;
+ for( ps = first_ctnr( ProcessList ); ps; ps = next_ctnr( ProcessList )) {
+ if( ps->alive ) {
+ ps->alive = 0;
+ ProcessCount++;
+ } else {
+ free( remove_ctnr( ProcessList ));
+ }
+ }
+}
+
+void initProcessList( struct SensorModul* sm ) {
+
+ if( (procdir = opendir( PROCDIR )) == NULL ) {
+ print_error( "cannot open \"%s\" for reading\n", PROCDIR );
+ return;
+ }
+ pagesz=getpagesize();
+ ProcessList = new_ctnr();
+ updateProcessList();
+
+ /*
+ * register the supported monitors & commands
+ */
+ registerMonitor( "pscount", "integer",
+ printProcessCount, printProcessCountInfo, sm );
+ registerMonitor( "ps", "table",
+ printProcessList, printProcessListInfo, sm );
+
+ if (!RunAsDaemon)
+ {
+ registerCommand("kill", killProcess);
+ registerCommand("setpriority", setPriority);
+ }
+}
+
+void exitProcessList( void ) {
+
+ removeMonitor("ps");
+ removeMonitor("pscount");
+
+ if (!RunAsDaemon)
+ {
+ removeCommand("kill");
+ removeCommand("setpriority");
+ }
+
+ destr_ctnr( ProcessList, free );
+}
+
+int updateProcessList( void ) {
+
+ struct dirent *de;
+ struct statfs sf;
+
+ statfs("/proc/pinfo",&sf,sizeof(sf),0);
+ ProcessCount = sf.f_files;
+
+ rewinddir( procdir );
+ while( (de = readdir( procdir )) != NULL ) {
+ /*
+ * skip '.' and '..'
+ */
+ if( de->d_name[0] == '.' )
+ continue;
+
+ /*
+ * fetch the process info and insert it into the info table
+ */
+ updateProcess( (pid_t) atol( de->d_name ));
+ }
+ cleanupProcessList();
+
+ return( 0 );
+}
+
+void printProcessListInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Name\tPID\tPPID\tGID\tStatus\tUser"
+ "\tSize\tResident\t%% CPU\tPriority\tCommand\n" );
+ fprintf(CurrentClient, "s\td\td\td\ts\ts\tD\tD\tf\td\ts\n" );
+}
+
+void printProcessList( const char *cmd ) {
+
+ ProcessInfo *ps;
+
+ for( ps = first_ctnr( ProcessList ); ps; ps = next_ctnr( ProcessList )) {
+ fprintf(CurrentClient,
+ "%s\t%ld\t%ld\t%ld\t%s\t%s\t%d\t%d\t%.2f\t%d\t%s\n",
+ ps->Command,
+ (long) ps->pid,
+ (long) ps->ppid,
+ (long) ps->gid,
+ ps->State,
+ ps->userName,
+ ps->Size,
+ ps->RSSize,
+ ps->Load,
+ ps->Prio,
+ ps->CmdLine);
+ }
+
+ fprintf(CurrentClient, "\n");
+}
+
+void printProcessCount( const char *cmd ) {
+ fprintf(CurrentClient, "%d\n", ProcessCount );
+}
+
+void printProcessCountInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Number of Processes\t0\t0\t\n" );
+}
+
+void killProcess( const char *cmd ) {
+
+ int sig, pid;
+
+ sscanf( cmd, "%*s %d %d", &pid, &sig );
+
+ switch( sig ) {
+ case MENU_ID_SIGABRT:
+ sig = SIGABRT;
+ break;
+ case MENU_ID_SIGALRM:
+ sig = SIGALRM;
+ break;
+ case MENU_ID_SIGCHLD:
+ sig = SIGCHLD;
+ break;
+ case MENU_ID_SIGCONT:
+ sig = SIGCONT;
+ break;
+ case MENU_ID_SIGFPE:
+ sig = SIGFPE;
+ break;
+ case MENU_ID_SIGHUP:
+ sig = SIGHUP;
+ break;
+ case MENU_ID_SIGILL:
+ sig = SIGILL;
+ break;
+ case MENU_ID_SIGINT:
+ sig = SIGINT;
+ break;
+ case MENU_ID_SIGKILL:
+ sig = SIGKILL;
+ break;
+ case MENU_ID_SIGPIPE:
+ sig = SIGPIPE;
+ break;
+ case MENU_ID_SIGQUIT:
+ sig = SIGQUIT;
+ break;
+ case MENU_ID_SIGSEGV:
+ sig = SIGSEGV;
+ break;
+ case MENU_ID_SIGSTOP:
+ sig = SIGSTOP;
+ break;
+ case MENU_ID_SIGTERM:
+ sig = SIGTERM;
+ break;
+ case MENU_ID_SIGTSTP:
+ sig = SIGTSTP;
+ break;
+ case MENU_ID_SIGTTIN:
+ sig = SIGTTIN;
+ break;
+ case MENU_ID_SIGTTOU:
+ sig = SIGTTOU;
+ break;
+ case MENU_ID_SIGUSR1:
+ sig = SIGUSR1;
+ break;
+ case MENU_ID_SIGUSR2:
+ sig = SIGUSR2;
+ break;
+ }
+ if( kill( (pid_t) pid, sig )) {
+ switch( errno ) {
+ case EINVAL:
+ fprintf(CurrentClient, "4\n" );
+ break;
+ case ESRCH:
+ fprintf(CurrentClient, "3\n" );
+ break;
+ case EPERM:
+ fprintf(CurrentClient, "2\n" );
+ break;
+ default:
+ fprintf(CurrentClient, "1\n" ); /* unknown error */
+ break;
+ }
+ } else
+ fprintf(CurrentClient, "0\n");
+}
+
+void setPriority( const char *cmd ) {
+ int pid, prio;
+
+ sscanf( cmd, "%*s %d %d", &pid, &prio );
+ if( setpriority( PRIO_PROCESS, pid, prio )) {
+ switch( errno ) {
+ case EINVAL:
+ fprintf(CurrentClient, "4\n" );
+ break;
+ case ESRCH:
+ fprintf(CurrentClient, "3\n" );
+ break;
+ case EPERM:
+ case EACCES:
+ fprintf(CurrentClient, "2\n" );
+ break;
+ default:
+ fprintf(CurrentClient, "1\n" ); /* unknown error */
+ break;
+ }
+ } else
+ fprintf(CurrentClient, "0\n");
+}
diff --git a/ksysguard/ksysguardd/Irix/ProcessList.h b/ksysguard/ksysguardd/Irix/ProcessList.h
new file mode 100644
index 000000000..5d949279e
--- /dev/null
+++ b/ksysguard/ksysguardd/Irix/ProcessList.h
@@ -0,0 +1,43 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ Irix support by Carsten Kroll <ckroll@pinnaclesys.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _ProcessList_H_
+#define _ProcessList_H_
+
+#define PROCDIR "/proc"
+
+void initProcessList(struct SensorModul* sm);
+void exitProcessList(void);
+
+int updateProcessList(void);
+
+void printProcessList(const char*);
+void printProcessListInfo(const char*);
+
+void printProcessCount(const char* cmd);
+void printProcessCountInfo(const char* cmd);
+
+void killProcess(const char* cmd);
+void setPriority(const char* cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/Irix/cpu.c b/ksysguard/ksysguardd/Irix/cpu.c
new file mode 100644
index 000000000..9fdd25ab7
--- /dev/null
+++ b/ksysguard/ksysguardd/Irix/cpu.c
@@ -0,0 +1,262 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ Irix support by Carsten Kroll <ckroll@pinnaclesys.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/sysmp.h>
+#include <sys/sysinfo.h>
+
+#include "cpu.h"
+#include "Command.h"
+#include "ksysguardd.h"
+
+#define CPUSTATES 6
+
+long percentages(int cnt, int *out, long *new, long *old, long *diffs);
+
+static int nCPUs=0;
+
+
+long cp_time[CPUSTATES];
+long cp_old[CPUSTATES];
+long cp_diff[CPUSTATES];
+int cpu_states[CPUSTATES];
+
+struct cpu_info{
+ long cp_time[CPUSTATES];
+ long cp_old[CPUSTATES];
+ long cp_diff[CPUSTATES];
+ int cpu_states[CPUSTATES];
+};
+
+static struct cpu_info *g_ci;
+
+/* returns the requested cpu number starting at 0*/
+int getID(const char *cmd){
+ int id;
+ sscanf(cmd + 7, "%d", &id);
+ return id-1;
+}
+
+void
+initCpuInfo(struct SensorModul* sm)
+{
+ char mname[50];
+ int i;
+ if (sysmp(MP_NPROCS,&nCPUs) < 0) nCPUs=0;
+ nCPUs++;
+ g_ci = malloc(sizeof(struct cpu_info) * nCPUs);
+ memset(g_ci,0,sizeof(struct cpu_info) * nCPUs);
+
+ registerMonitor("cpu/user", "integer", printCPUUser,
+ printCPUUserInfo, sm);
+ registerMonitor("cpu/sys", "integer", printCPUSys,
+ printCPUSysInfo, sm);
+ registerMonitor("cpu/idle", "integer", printCPUIdle,
+ printCPUIdleInfo, sm);
+
+ if (nCPUs > 1) for (i=0;i<nCPUs;i++){
+ /* indidividual CPU load */
+ sprintf(mname,"cpu/cpu%d/user",i+1);
+ registerMonitor(mname, "integer", printCPUxUser,
+ printCPUUserInfo, sm);
+ sprintf(mname,"cpu/cpu%d/sys",i+1);
+ registerMonitor(mname, "integer", printCPUxSys,
+ printCPUSysInfo, sm);
+ sprintf(mname,"cpu/cpu%d/idle",i+1);
+ registerMonitor(mname, "integer", printCPUxIdle,
+ printCPUIdleInfo, sm);
+ }
+
+ updateCpuInfo();
+}
+
+void
+exitCpuInfo(void)
+{
+ free(g_ci);
+}
+
+int
+updateCpuInfo(void)
+{
+ struct sysinfo si;
+ int rv=0;
+ int i;
+ /* overall summary */
+ if (sysmp(MP_SAGET,MPSA_SINFO,&si,sizeof(struct sysinfo)) >=0){
+ cp_time[CPU_IDLE] =si.cpu[CPU_IDLE];
+ cp_time[CPU_USER] =si.cpu[CPU_USER];
+ cp_time[CPU_KERNEL]=si.cpu[CPU_KERNEL];
+ cp_time[CPU_SXBRK] =si.cpu[CPU_SXBRK];
+ cp_time[CPU_INTR] =si.cpu[CPU_INTR];
+ cp_time[CPU_WAIT] =si.cpu[CPU_WAIT];
+ percentages(CPUSTATES,cpu_states,cp_time,cp_old,cp_diff);
+ }
+ /* individual CPU statistics*/
+ if (nCPUs > 1) for (i=0;i<nCPUs;i++){
+ if (sysmp(MP_SAGET1,MPSA_SINFO,&si,sizeof(struct sysinfo),i) >=0){
+ g_ci[i].cp_time[CPU_IDLE] =si.cpu[CPU_IDLE];
+ g_ci[i].cp_time[CPU_USER] =si.cpu[CPU_USER];
+ g_ci[i].cp_time[CPU_KERNEL]=si.cpu[CPU_KERNEL];
+ g_ci[i].cp_time[CPU_SXBRK] =si.cpu[CPU_SXBRK];
+ g_ci[i].cp_time[CPU_INTR] =si.cpu[CPU_INTR];
+ g_ci[i].cp_time[CPU_WAIT] =si.cpu[CPU_WAIT];
+ percentages(CPUSTATES, g_ci[i].cpu_states, g_ci[i].cp_time, g_ci[i].cp_old,g_ci[i].cp_diff);
+ }else{
+ rv =-1;
+ }
+ }
+ return (rv);
+}
+
+void
+printCPUUser(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", cpu_states[CPU_USER]/10);
+}
+
+void
+printCPUUserInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "CPU User Load\t0\t100\t%%\n");
+}
+
+void
+printCPUSys(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", cpu_states[CPU_KERNEL]/10);
+}
+
+void
+printCPUSysInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "CPU System Load\t0\t100\t%%\n");
+}
+
+void
+printCPUIdle(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", cpu_states[CPU_IDLE]/10);
+}
+
+void
+printCPUIdleInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "CPU Idle Load\t0\t100\t%%\n");
+}
+/* same as above but for individual CPUs */
+void
+printCPUxUser(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", g_ci[getID(cmd)].cpu_states[CPU_USER]/10);
+}
+
+void
+printCPUxSys(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", g_ci[getID(cmd)].cpu_states[CPU_KERNEL]/10);
+}
+
+void
+printCPUxIdle(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", g_ci[getID(cmd)].cpu_states[CPU_IDLE]/10);
+}
+
+
+/* The part ripped from top... */
+/*
+ * Top users/processes display for Unix
+ * Version 3
+ *
+ * This program may be freely redistributed,
+ * but this entire comment MUST remain intact.
+ *
+ * Copyright (c) 1984, 1989, William LeFebvre, Rice University
+ * Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University
+ */
+
+/*
+ * percentages(cnt, out, new, old, diffs) - calculate percentage change
+ * between array "old" and "new", putting the percentages in "out".
+ * "cnt" is size of each array and "diffs" is used for scratch space.
+ * The array "old" is updated on each call.
+ * The routine assumes modulo arithmetic. This function is especially
+ * useful on BSD mchines for calculating cpu state percentages.
+ */
+
+long percentages(cnt, out, new, old, diffs)
+
+int cnt;
+int *out;
+register long *new;
+register long *old;
+long *diffs;
+
+{
+ register int i;
+ register long change;
+ register long total_change;
+ register long *dp;
+ long half_total;
+
+ /* initialization */
+ total_change = 0;
+ dp = diffs;
+
+ /* calculate changes for each state and the overall change */
+ for (i = 0; i < cnt; i++)
+ {
+ if ((change = *new - *old) < 0)
+ {
+ /* this only happens when the counter wraps */
+ change = (int)
+ ((unsigned long)*new-(unsigned long)*old);
+ }
+ total_change += (*dp++ = change);
+ *old++ = *new++;
+ }
+
+ /* avoid divide by zero potential */
+ if (total_change == 0)
+ {
+ total_change = 1;
+ }
+
+ /* calculate percentages based on overall change, rounding up */
+ half_total = total_change / 2l;
+
+ /* Do not divide by 0. Causes Floating point exception */
+ if(total_change) {
+ for (i = 0; i < cnt; i++)
+ {
+ *out++ = (int)((*diffs++ * 1000 + half_total) / total_change);
+ }
+ }
+
+ /* return the total in case the caller wants to use it */
+ return(total_change);
+}
diff --git a/ksysguard/ksysguardd/Irix/cpu.h b/ksysguard/ksysguardd/Irix/cpu.h
new file mode 100644
index 000000000..f61d12505
--- /dev/null
+++ b/ksysguard/ksysguardd/Irix/cpu.h
@@ -0,0 +1,43 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _cpuinfo_h_
+#define _cpuinfo_h_
+
+void initCpuInfo(struct SensorModul* sm);
+void exitCpuInfo(void);
+
+int updateCpuInfo(void);
+
+void printCPUUser(const char* cmd);
+void printCPUUserInfo(const char* cmd);
+void printCPUSys(const char* cmd);
+void printCPUSysInfo(const char* cmd);
+void printCPUIdle(const char* cmd);
+void printCPUIdleInfo(const char* cmd);
+void printCPUxUser(const char* cmd);
+void printCPUxUserInfo(const char* cmd);
+void printCPUxSys(const char* cmd);
+void printCPUxSysInfo(const char* cmd);
+void printCPUxIdle(const char* cmd);
+void printCPUxIdleInfo(const char* cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/Linux/Makefile.am b/ksysguard/ksysguardd/Linux/Makefile.am
new file mode 100644
index 000000000..928b4b66a
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/Makefile.am
@@ -0,0 +1,14 @@
+AM_CPPFLAGS = -D_GNU_SOURCE
+AM_CFLAGS = -Wall
+
+# add all supported modules
+if supports_i8k
+KSGRD_SUPPORTS = -DHAVE_I8K_SUPPORT
+endif
+
+
+INCLUDES = -I$(srcdir)/../../CContLib -I$(srcdir)/.. $(KSGRD_SUPPORTS) $(all_includes)
+
+noinst_LIBRARIES = libksysguardd.a
+libksysguardd_a_SOURCES = ProcessList.c Memory.c stat.c netdev.c apm.c acpi.c \
+ loadavg.c cpuinfo.c lmsensors.c netstat.c diskstat.c logfile.c i8k.c
diff --git a/ksysguard/ksysguardd/Linux/Memory.c b/ksysguard/ksysguardd/Linux/Memory.c
new file mode 100644
index 000000000..93c8d9edb
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/Memory.c
@@ -0,0 +1,293 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 - 2001 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "Command.h"
+#include "ksysguardd.h"
+
+#include "Memory.h"
+
+#define MEMINFOBUFSIZE (2 * 1024)
+
+static char MemInfoBuf[ MEMINFOBUFSIZE ];
+static int Dirty = 1;
+
+static unsigned long Total = 0;
+static unsigned long MFree = 0;
+static unsigned long Appl = 0;
+static unsigned long Used = 0;
+static unsigned long Buffers = 0;
+static unsigned long Cached = 0;
+static unsigned long STotal = 0;
+static unsigned long SFree = 0;
+static unsigned long SUsed = 0;
+
+static void scan_one( const char* buff, const char *key, unsigned long int* val )
+{
+ int o;
+ char *b = strstr( buff, key );
+ if ( b )
+ o = sscanf( b + strlen( key ), ": %lu", val );
+}
+
+static void processMemInfo()
+{
+ scan_one( MemInfoBuf, "MemTotal", &Total );
+ scan_one( MemInfoBuf, "MemFree", &MFree );
+ scan_one( MemInfoBuf, "Buffers", &Buffers );
+ scan_one( MemInfoBuf, "Cached", &Cached );
+ scan_one( MemInfoBuf, "SwapTotal", &STotal );
+ scan_one( MemInfoBuf, "SwapFree", &SFree );
+ Used = Total - MFree;
+ Appl = ( Used - ( Buffers + Cached ) );
+
+ if ( STotal == 0 ) /* no swap activated */
+ SUsed = 0;
+ else
+ SUsed = STotal - SFree;
+
+ Dirty = 0;
+}
+
+/*
+================================ public part =================================
+*/
+
+void initMemory( struct SensorModul* sm )
+{
+ /**
+ Make sure that /proc/meminfo exists and is readable. If not we do
+ not register any monitors for memory.
+ */
+ if ( updateMemory() < 0 )
+ return;
+
+ registerMonitor( "mem/physical/free", "integer", printMFree, printMFreeInfo, sm );
+ registerMonitor( "mem/physical/used", "integer", printUsed, printUsedInfo, sm );
+ registerMonitor( "mem/physical/application", "integer", printAppl, printApplInfo, sm );
+ registerMonitor( "mem/physical/buf", "integer", printBuffers, printBuffersInfo, sm );
+ registerMonitor( "mem/physical/cached", "integer", printCached, printCachedInfo, sm );
+ registerMonitor( "mem/swap/used", "integer", printSwapUsed, printSwapUsedInfo, sm );
+ registerMonitor( "mem/swap/free", "integer", printSwapFree, printSwapFreeInfo, sm );
+}
+
+void exitMemory( void )
+{
+}
+
+int updateMemory( void )
+{
+ /**
+ The amount of total and used memory is read from the /proc/meminfo.
+ It also contains the information about the swap space.
+ The 'file' looks like this:
+
+ MemTotal: 516560 kB
+ MemFree: 7812 kB
+ MemShared: 0 kB
+ Buffers: 80312 kB
+ Cached: 236432 kB
+ SwapCached: 468 kB
+ Active: 291992 kB
+ Inactive: 133556 kB
+ HighTotal: 0 kB
+ HighFree: 0 kB
+ LowTotal: 516560 kB
+ LowFree: 7812 kB
+ SwapTotal: 899632 kB
+ SwapFree: 898932 kB
+ Dirty: 2736 kB
+ Writeback: 0 kB
+ Mapped: 155996 kB
+ Slab: 73920 kB
+ Committed_AS: 315588 kB
+ PageTables: 1764 kB
+ ReverseMaps: 103458
+ */
+
+ int fd;
+ size_t n;
+
+ if ( ( fd = open( "/proc/meminfo", O_RDONLY ) ) < 0 ) {
+ print_error( "Cannot open \'/proc/meminfo\'!\n"
+ "The kernel needs to be compiled with support\n"
+ "for /proc filesystem enabled!\n" );
+ return -1;
+ }
+
+ if ( ( n = read( fd, MemInfoBuf, MEMINFOBUFSIZE - 1 ) ) == MEMINFOBUFSIZE - 1 ) {
+ log_error( "Internal buffer too small to read \'/proc/mem\'" );
+ close( fd );
+ return -1;
+ }
+
+ close( fd );
+ MemInfoBuf[ n ] = '\0';
+ Dirty = 1;
+
+ return 0;
+}
+
+void printMFree( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "%ld\n", MFree );
+}
+
+void printMFreeInfo( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "Free Memory\t0\t%ld\tKB\n", Total );
+}
+
+void printUsed( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "%ld\n", Used );
+}
+
+void printUsedInfo( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "Used Memory\t0\t%ld\tKB\n", Total );
+}
+
+void printAppl( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "%ld\n", Appl );
+}
+
+void printApplInfo( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "Application Memory\t0\t%ld\tKB\n", Total );
+}
+
+void printBuffers( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "%ld\n", Buffers );
+}
+
+void printBuffersInfo( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "Buffer Memory\t0\t%ld\tKB\n", Total );
+}
+
+void printCached( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "%ld\n", Cached );
+}
+
+void printCachedInfo( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "Cached Memory\t0\t%ld\tKB\n", Total );
+}
+
+void printSwapUsed( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "%ld\n", SUsed );
+}
+
+void printSwapUsedInfo( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "Used Swap Memory\t0\t%ld\tKB\n", STotal );
+}
+
+void printSwapFree( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "%ld\n", SFree );
+}
+
+void printSwapFreeInfo( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "Free Swap Memory\t0\t%ld\tKB\n", STotal );
+}
diff --git a/ksysguard/ksysguardd/Linux/Memory.h b/ksysguard/ksysguardd/Linux/Memory.h
new file mode 100644
index 000000000..2dbd6f2dc
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/Memory.h
@@ -0,0 +1,45 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 - 2001 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KSG_MEMORY_H
+#define KSG_MEMORY_H
+
+void initMemory( struct SensorModul* );
+void exitMemory( void );
+
+int updateMemory( void );
+
+void printMFree( const char* );
+void printMFreeInfo( const char* );
+void printUsed( const char* );
+void printUsedInfo( const char* );
+void printAppl( const char* );
+void printApplInfo( const char* );
+void printBuffers( const char* );
+void printBuffersInfo( const char* );
+void printCached( const char* );
+void printCachedInfo( const char* );
+void printSwapUsed( const char* );
+void printSwapUsedInfo( const char* );
+void printSwapFree( const char* );
+void printSwapFreeInfo( const char* );
+
+#endif
diff --git a/ksysguard/ksysguardd/Linux/ProcessList.c b/ksysguard/ksysguardd/Linux/ProcessList.c
new file mode 100644
index 000000000..b267c7005
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/ProcessList.c
@@ -0,0 +1,554 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 - 2001 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "../../gui/SignalIDs.h"
+#include "Command.h"
+#include "PWUIDCache.h"
+#include "ccont.h"
+#include "ksysguardd.h"
+
+#include "ProcessList.h"
+
+#define BUFSIZE 1024
+#define TAGSIZE 32
+#define KDEINITLEN strlen( "kdeinit: " )
+
+static CONTAINER ProcessList = 0;
+
+typedef struct {
+ /**
+ This flag is set for all found processes at the beginning of the
+ process list update. Processes that do not have this flag set will
+ be assumed dead and removed from the list. The flag is cleared after
+ each list update.
+ */
+ int alive;
+
+ /* The process ID */
+ pid_t pid;
+
+ /* The parent process ID */
+ pid_t ppid;
+
+ /* The real user ID */
+ uid_t uid;
+
+ /* The real group ID */
+ gid_t gid;
+
+ /* A character description of the process status */
+ char status[ 16 ];
+
+ /* The number of the tty the process owns */
+ int ttyNo;
+
+ /**
+ The nice level. The range should be -20 to 20. I'm not sure
+ whether this is true for all platforms.
+ */
+ int niceLevel;
+
+ /* The scheduling priority. */
+ int priority;
+
+ /**
+ The total amount of memory the process uses. This includes shared and
+ swapped memory.
+ */
+ unsigned int vmSize;
+
+ /* The amount of physical memory the process currently uses. */
+ unsigned int vmRss;
+
+ /**
+ The number of 1/100 of a second the process has spend in user space.
+ If a machine has an uptime of 1 1/2 years or longer this is not a
+ good idea. I never thought that the stability of UNIX could get me
+ into trouble! ;)
+ */
+ unsigned int userTime;
+
+ /**
+ The number of 1/100 of a second the process has spend in system space.
+ If a machine has an uptime of 1 1/2 years or longer this is not a
+ good idea. I never thought that the stability of UNIX could get me
+ into trouble! ;)
+ */
+ unsigned int sysTime;
+
+ /* The system time as multime of 100ms */
+ int centStamp;
+
+ /* The current CPU load (in %) from user space */
+ double userLoad;
+
+ /* The current CPU load (in %) from system space */
+ double sysLoad;
+
+ /* The name of the process */
+ char name[ 64 ];
+
+ /* The command used to start the process */
+ char cmdline[ 256 ];
+
+ /* The login name of the user that owns this process */
+ char userName[ 32 ];
+} ProcessInfo;
+
+static unsigned ProcessCount;
+
+static void validateStr( char* str )
+{
+ char* s = str;
+
+ /* All characters that could screw up the communication will be removed. */
+ while ( *s ) {
+ if ( *s == '\t' || *s == '\n' || *s == '\r' )
+ *s = ' ';
+ ++s;
+ }
+
+ /* Make sure that string contains at least one character (blank). */
+ if ( str[ 0 ] == '\0' )
+ strcpy( str, " " );
+}
+
+static int processCmp( void* p1, void* p2 )
+{
+ return ( ((ProcessInfo*)p1)->pid - ((ProcessInfo*)p2)->pid );
+}
+
+static ProcessInfo* findProcessInList( int pid )
+{
+ ProcessInfo key;
+ long idx;
+
+ key.pid = pid;
+ if ( ( idx = search_ctnr( ProcessList, processCmp, &key ) ) < 0 )
+ return 0;
+
+ return get_ctnr( ProcessList, idx );
+}
+
+static int updateProcess( int pid )
+{
+ ProcessInfo* ps;
+ FILE* fd;
+ char buf[ BUFSIZE ];
+ char tag[ TAGSIZE ];
+ char format[ 32 ];
+ char tagformat[ 32 ];
+ int userTime, sysTime;
+ const char* uName;
+ char status;
+
+ if ( ( ps = findProcessInList( pid ) ) == 0 ) {
+ struct timeval tv;
+
+ ps = (ProcessInfo*)malloc( sizeof( ProcessInfo ) );
+ ps->pid = pid;
+ ps->alive = 0;
+
+ gettimeofday( &tv, 0 );
+ ps->centStamp = tv.tv_sec * 100 + tv.tv_usec / 10000;
+
+ push_ctnr( ProcessList, ps );
+ bsort_ctnr( ProcessList, processCmp );
+ }
+
+ snprintf( buf, BUFSIZE - 1, "/proc/%d/status", pid );
+ if ( ( fd = fopen( buf, "r" ) ) == 0 ) {
+ /* process has terminated in the mean time */
+ return -1;
+ }
+
+ sprintf( format, "%%%d[^\n]\n", (int)sizeof( buf ) - 1 );
+ sprintf( tagformat, "%%%ds", (int)sizeof( tag ) - 1 );
+ for ( ;; ) {
+ if ( fscanf( fd, format, buf ) != 1 )
+ break;
+ buf[ sizeof( buf ) - 1 ] = '\0';
+ sscanf( buf, tagformat, tag );
+ tag[ sizeof( tag ) - 1 ] = '\0';
+ if ( strcmp( tag, "Name:" ) == 0 ) {
+ sscanf( buf, "%*s %63s", ps->name );
+ validateStr( ps->name );
+ } else if ( strcmp( tag, "Uid:" ) == 0 )
+ sscanf( buf, "%*s %d %*d %*d %*d", (int*)&ps->uid );
+ }
+
+ if ( fclose( fd ) )
+ return -1;
+
+ snprintf( buf, BUFSIZE - 1, "/proc/%d/stat", pid );
+ buf[ BUFSIZE - 1 ] = '\0';
+ if ( ( fd = fopen( buf, "r" ) ) == 0 )
+ return -1;
+
+ if ( fscanf( fd, "%*d %*s %c %d %d %*d %d %*d %*u %*u %*u %*u %*u %d %d"
+ "%*d %*d %*d %d %*u %*u %*d %u %u",
+ &status, (int*)&ps->ppid, (int*)&ps->gid, &ps->ttyNo,
+ &userTime, &sysTime, &ps->niceLevel, &ps->vmSize,
+ &ps->vmRss) != 9 ) {
+ fclose( fd );
+ return -1;
+ }
+
+ if ( fclose( fd ) )
+ return -1;
+
+ /* status decoding as taken from fs/proc/array.c */
+ if ( status == 'R' )
+ strcpy( ps->status, "running" );
+ else if ( status == 'S' )
+ strcpy( ps->status, "sleeping" );
+ else if ( status == 'D' )
+ strcpy( ps->status, "disk sleep" );
+ else if ( status == 'Z' )
+ strcpy( ps->status, "zombie" );
+ else if ( status == 'T' )
+ strcpy( ps->status, "stopped" );
+ else if ( status == 'W' )
+ strcpy( ps->status, "paging" );
+ else
+ sprintf( ps->status, "Unknown: %c", status );
+
+ ps->vmRss = ( ps->vmRss + 3 ) * sysconf(_SC_PAGESIZE);
+
+ {
+ int newCentStamp;
+ int timeDiff, userDiff, sysDiff;
+ struct timeval tv;
+
+ gettimeofday( &tv, 0 );
+ newCentStamp = tv.tv_sec * 100 + tv.tv_usec / 10000;
+
+ timeDiff = newCentStamp - ps->centStamp;
+ userDiff = userTime - ps->userTime;
+ sysDiff = sysTime - ps->sysTime;
+
+ if ( ( timeDiff > 0 ) && ( userDiff >= 0 ) && ( sysDiff >= 0 ) ) {
+ ps->userLoad = ( (double)userDiff / timeDiff ) * 100.0;
+ ps->sysLoad = ( (double)sysDiff / timeDiff ) * 100.0;
+ /**
+ During startup we get bigger loads since the time diff
+ cannot be correct. So we force it to 0.
+ */
+ if ( ps->userLoad > 100.0 )
+ ps->userLoad = 0.0;
+ if ( ps->sysLoad > 100.0 )
+ ps->sysLoad = 0.0;
+ } else
+ ps->sysLoad = ps->userLoad = 0.0;
+
+ ps->centStamp = newCentStamp;
+ ps->userTime = userTime;
+ ps->sysTime = sysTime;
+ }
+
+ snprintf( buf, BUFSIZE - 1, "/proc/%d/cmdline", pid );
+ if ( ( fd = fopen( buf, "r" ) ) == 0 )
+ return -1;
+
+ ps->cmdline[ 0 ] = '\0';
+ sprintf( buf, "%%%d[^\n]", (int)sizeof( ps->cmdline ) - 1 );
+ fscanf( fd, buf, ps->cmdline );
+ ps->cmdline[ sizeof( ps->cmdline ) - 1 ] = '\0';
+ validateStr( ps->cmdline );
+ if ( fclose( fd ) )
+ return -1;
+
+ /* Ugly hack to "fix" program name for kdeinit launched programs. */
+ if ( strcmp( ps->name, "kdeinit" ) == 0 &&
+ strncmp( ps->cmdline, "kdeinit: ", KDEINITLEN ) == 0 &&
+ strcmp( ps->cmdline + KDEINITLEN, "Running..." ) != 0 ) {
+ size_t len;
+ char* end = strchr( ps->cmdline + KDEINITLEN, ' ' );
+ if ( end )
+ len = ( end - ps->cmdline ) - KDEINITLEN;
+ else
+ len = strlen( ps->cmdline + KDEINITLEN );
+ if ( len > 0 ) {
+ if ( len > sizeof( ps->name ) - 1 )
+ len = sizeof( ps->name ) - 1;
+ strncpy( ps->name, ps->cmdline + KDEINITLEN, len );
+ ps->name[ len ] = '\0';
+ }
+ }
+
+ /* find out user name with the process uid */
+ uName = getCachedPWUID( ps->uid );
+ strncpy( ps->userName, uName, sizeof( ps->userName ) - 1 );
+ ps->userName[ sizeof( ps->userName ) - 1 ] = '\0';
+ validateStr( ps->userName );
+
+ ps->alive = 1;
+
+ return 0;
+}
+
+static void cleanupProcessList( void )
+{
+ ProcessInfo* ps;
+
+ ProcessCount = 0;
+ /**
+ All processes that do not have the active flag set are assumed dead
+ and will be removed from the list. The alive flag is cleared.
+ */
+ for ( ps = first_ctnr( ProcessList ); ps; ps = next_ctnr( ProcessList ) ) {
+ if ( ps->alive ) {
+ /* Process is still alive. Just clear flag. */
+ ps->alive = 0;
+ ProcessCount++;
+ } else {
+ /**
+ Process has probably died. We remove it from the list and
+ destruct the data structure. i needs to be decremented so
+ that after i++ the next list element will be inspected.
+ */
+ free( remove_ctnr( ProcessList ) );
+ }
+ }
+}
+
+int updateProcessList( void )
+{
+ DIR* dir;
+ struct dirent* entry;
+
+ /* read in current process list via the /proc filesystem entry */
+ if ( ( dir = opendir( "/proc" ) ) == NULL ) {
+ print_error( "Cannot open directory \'/proc\'!\n"
+ "The kernel needs to be compiled with support\n"
+ "for /proc filesystem enabled!\n" );
+ return 0;
+ }
+
+ while ( ( entry = readdir( dir ) ) ) {
+ if ( isdigit( entry->d_name[ 0 ] ) ) {
+ int pid;
+
+ pid = atoi( entry->d_name );
+ updateProcess( pid );
+ }
+ }
+ closedir( dir );
+
+ cleanupProcessList();
+ return 0;
+}
+
+/*
+================================ public part =================================
+*/
+
+void initProcessList( struct SensorModul* sm )
+{
+ initPWUIDCache();
+
+ ProcessList = new_ctnr();
+
+ registerMonitor( "pscount", "integer", printProcessCount, printProcessCountInfo, sm );
+ registerMonitor( "ps", "table", printProcessList, printProcessListInfo, sm );
+
+ if ( !RunAsDaemon ) {
+ registerCommand( "kill", killProcess );
+ registerCommand( "setpriority", setPriority );
+ }
+
+ updateProcessList();
+}
+
+void exitProcessList( void )
+{
+ removeMonitor( "ps" );
+ removeMonitor( "pscount" );
+
+ if ( !RunAsDaemon ) {
+ removeCommand( "kill" );
+ removeCommand( "setpriority" );
+ }
+
+ destr_ctnr( ProcessList, free );
+
+ exitPWUIDCache();
+}
+
+void printProcessListInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "Name\tPID\tPPID\tUID\tGID\tStatus\tUser%%\tSystem%%\tNice\tVmSize"
+ "\tVmRss\tLogin\tCommand\n" );
+ fprintf( CurrentClient, "s\td\td\td\td\tS\tf\tf\td\tD\tD\ts\ts\n" );
+}
+
+void printProcessList( const char* cmd )
+{
+ ProcessInfo* ps;
+
+ (void)cmd;
+
+ for ( ps = first_ctnr( ProcessList ); ps; ps = next_ctnr( ProcessList ) ) {
+ fprintf( CurrentClient, "%s\t%ld\t%ld\t%ld\t%ld\t%s\t%.2f\t%.2f\t%d\t%d\t%d"
+ "\t%s\t%s\n", ps->name, (long)ps->pid, (long)ps->ppid,
+ (long)ps->uid, (long)ps->gid, ps->status, ps->userLoad,
+ ps->sysLoad, ps->niceLevel, ps->vmSize / 1024, ps->vmRss / 1024,
+ ps->userName, ps->cmdline );
+ }
+
+ fprintf( CurrentClient, "\n" );
+}
+
+void printProcessCount( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "%d\n", ProcessCount );
+}
+
+void printProcessCountInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "Number of Processes\t0\t0\t\n" );
+}
+
+void killProcess( const char* cmd )
+{
+ int sig, pid;
+
+ sscanf( cmd, "%*s %d %d", &pid, &sig );
+ switch( sig ) {
+ case MENU_ID_SIGABRT:
+ sig = SIGABRT;
+ break;
+ case MENU_ID_SIGALRM:
+ sig = SIGALRM;
+ break;
+ case MENU_ID_SIGCHLD:
+ sig = SIGCHLD;
+ break;
+ case MENU_ID_SIGCONT:
+ sig = SIGCONT;
+ break;
+ case MENU_ID_SIGFPE:
+ sig = SIGFPE;
+ break;
+ case MENU_ID_SIGHUP:
+ sig = SIGHUP;
+ break;
+ case MENU_ID_SIGILL:
+ sig = SIGILL;
+ break;
+ case MENU_ID_SIGINT:
+ sig = SIGINT;
+ break;
+ case MENU_ID_SIGKILL:
+ sig = SIGKILL;
+ break;
+ case MENU_ID_SIGPIPE:
+ sig = SIGPIPE;
+ break;
+ case MENU_ID_SIGQUIT:
+ sig = SIGQUIT;
+ break;
+ case MENU_ID_SIGSEGV:
+ sig = SIGSEGV;
+ break;
+ case MENU_ID_SIGSTOP:
+ sig = SIGSTOP;
+ break;
+ case MENU_ID_SIGTERM:
+ sig = SIGTERM;
+ break;
+ case MENU_ID_SIGTSTP:
+ sig = SIGTSTP;
+ break;
+ case MENU_ID_SIGTTIN:
+ sig = SIGTTIN;
+ break;
+ case MENU_ID_SIGTTOU:
+ sig = SIGTTOU;
+ break;
+ case MENU_ID_SIGUSR1:
+ sig = SIGUSR1;
+ break;
+ case MENU_ID_SIGUSR2:
+ sig = SIGUSR2;
+ break;
+ }
+
+ if ( kill( (pid_t)pid, sig ) ) {
+ switch ( errno ) {
+ case EINVAL:
+ fprintf( CurrentClient, "4\t%d\n", pid );
+ break;
+ case ESRCH:
+ fprintf( CurrentClient, "3\t%d\n", pid );
+ break;
+ case EPERM:
+ if(vfork() == 0) {
+ exit(0);/* Won't execute unless execve fails. Need this for the parent process to continue */
+ }
+ fprintf( CurrentClient, "2\t%d\n", pid );
+ break;
+ default: /* unknown error */
+ fprintf( CurrentClient, "1\t%d\n", pid );
+ break;
+ }
+ } else
+ fprintf( CurrentClient, "0\t%d\n", pid );
+}
+
+void setPriority( const char* cmd )
+{
+ int pid, prio;
+
+ sscanf( cmd, "%*s %d %d", &pid, &prio );
+ if ( setpriority( PRIO_PROCESS, pid, prio ) ) {
+ switch ( errno ) {
+ case EINVAL:
+ fprintf( CurrentClient, "4\n" );
+ break;
+ case ESRCH:
+ fprintf( CurrentClient, "3\n" );
+ break;
+ case EPERM:
+ case EACCES:
+ fprintf( CurrentClient, "2\n" );
+ break;
+ default: /* unknown error */
+ fprintf( CurrentClient, "1\n" );
+ break;
+ }
+ } else
+ fprintf( CurrentClient, "0\n" );
+}
diff --git a/ksysguard/ksysguardd/Linux/ProcessList.h b/ksysguard/ksysguardd/Linux/ProcessList.h
new file mode 100644
index 000000000..709994a29
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/ProcessList.h
@@ -0,0 +1,38 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 - 2000 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KSG_PROCESSLIST_H
+#define KSG_PROCESSLIST_H
+
+void initProcessList( struct SensorModul* );
+void exitProcessList( void );
+
+int updateProcessList( void );
+
+void printProcessList( const char* );
+void printProcessListInfo( const char* );
+void printProcessCount( const char* );
+void printProcessCountInfo( const char* );
+
+void killProcess( const char* );
+void setPriority( const char* );
+
+#endif
diff --git a/ksysguard/ksysguardd/Linux/acpi.c b/ksysguard/ksysguardd/Linux/acpi.c
new file mode 100644
index 000000000..b3100c363
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/acpi.c
@@ -0,0 +1,418 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2003 Stephan Uhlmann <su@su2.info>
+ Copyright (c) 2005 Sirtaj Singh Kang <taj@kde.org> -- Battery fixes and Thermal
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "Command.h"
+#include "ksysguardd.h"
+
+#include "acpi.h"
+
+#define ACPIFILENAMELENGTHMAX 64
+#define ACPIBATTERYNUMMAX 6
+#define ACPIBATTERYINFOBUFSIZE 1024
+#define ACPIBATTERYSTATEBUFSIZE 512
+
+static int AcpiBatteryNum = 0;
+static char AcpiBatteryNames[ ACPIBATTERYNUMMAX ][ 8 ];
+static int AcpiBatteryCharge[ ACPIBATTERYNUMMAX ];
+static int AcpiBatteryUsage[ ACPIBATTERYNUMMAX ];
+
+static int AcpiThermalZones = -1;
+static int AcpiFans = -1;
+/*
+================================ public part =================================
+*/
+
+void initAcpi(struct SensorModul* sm)
+{
+ initAcpiBattery(sm);
+ initAcpiFan(sm);
+ initAcpiThermal(sm);
+}
+
+int updateAcpi( void )
+{
+ if (AcpiBatteryNum > 0) updateAcpiBattery();
+ if (AcpiFans > 0) updateAcpiFan();
+ if (AcpiThermalZones > 0) updateAcpiThermal();
+ return 0;
+}
+
+void exitAcpi( void )
+{
+ AcpiBatteryNum = -1;
+ AcpiFans = -1;
+ AcpiThermalZones = -1;
+}
+
+
+/************ ACPI Battery **********/
+
+void initAcpiBattery( struct SensorModul* sm )
+{
+ DIR *d;
+ struct dirent *de;
+ char s[ ACPIFILENAMELENGTHMAX ];
+
+ if ( ( d = opendir( "/proc/acpi/battery" ) ) == NULL ) {
+ AcpiBatteryNum = -1;
+ return;
+ } else {
+ AcpiBatteryNum = 0;
+ while ( ( de = readdir( d ) ) )
+ if ( ( strcmp( de->d_name, "." ) != 0 ) && ( strcmp( de->d_name, ".." ) != 0 ) ) {
+ strncpy( AcpiBatteryNames[ AcpiBatteryNum ], de->d_name, 8 );
+ snprintf( s, sizeof( s ), "acpi/battery/%d/batterycharge", AcpiBatteryNum );
+ registerMonitor( s, "integer", printAcpiBatFill, printAcpiBatFillInfo, sm );
+ snprintf( s, sizeof( s ), "acpi/battery/%d/batteryusage", AcpiBatteryNum );
+ registerMonitor( s, "integer", printAcpiBatUsage, printAcpiBatUsageInfo, sm);
+ AcpiBatteryCharge[ AcpiBatteryNum ] = 0;
+ AcpiBatteryNum++;
+ }
+ }
+}
+
+
+int updateAcpiBattery( void )
+{
+ int i, fd;
+ char s[ ACPIFILENAMELENGTHMAX ];
+ size_t n;
+ char AcpiBatInfoBuf[ ACPIBATTERYINFOBUFSIZE ];
+ char AcpiBatStateBuf[ ACPIBATTERYSTATEBUFSIZE ];
+ char *p;
+ int AcpiBatCapacity = 1;
+ int AcpiBatRemainingCapacity = 0;
+
+ if ( AcpiBatteryNum <= 0 )
+ return -1;
+
+ for ( i = 0; i < AcpiBatteryNum; i++ ) {
+ /* get total capacity */
+ snprintf( s, sizeof( s ), "/proc/acpi/battery/%s/info", AcpiBatteryNames[ i ] );
+ if ( ( fd = open( s, O_RDONLY ) ) < 0 ) {
+ print_error( "Cannot open file \'%s\'!\n"
+ "Load the battery ACPI kernel module or\n"
+ "compile it into your kernel.\n", s );
+ return -1;
+ }
+ if ( ( n = read( fd, AcpiBatInfoBuf, ACPIBATTERYINFOBUFSIZE - 1 ) ) ==
+ ACPIBATTERYINFOBUFSIZE - 1 ) {
+ log_error( "Internal buffer too small to read \'%s\'", s );
+ close( fd );
+ return -1;
+ }
+ close( fd );
+ p = AcpiBatInfoBuf;
+ while ( ( p!= NULL ) && ( sscanf( p, "last full capacity: %d ",
+ &AcpiBatCapacity ) != 1 ) ) {
+ p = strchr( p, '\n' );
+ if ( p )
+ p++;
+ }
+ /* get remaining capacity */
+ snprintf( s, sizeof( s ), "/proc/acpi/battery/%s/state", AcpiBatteryNames[ i ] );
+ if ( ( fd = open( s, O_RDONLY ) ) < 0 ) {
+ print_error( "Cannot open file \'%s\'!\n"
+ "Load the battery ACPI kernel module or\n"
+ "compile it into your kernel.\n", s );
+ return -1;
+ }
+ if ( ( n = read( fd, AcpiBatStateBuf, ACPIBATTERYSTATEBUFSIZE - 1 ) ) ==
+ ACPIBATTERYSTATEBUFSIZE - 1 ) {
+ log_error( "Internal buffer too small to read \'%s\'", s);
+ close( fd );
+ return -1;
+ }
+ close( fd );
+ p = AcpiBatStateBuf;
+ while ( ( p!= NULL ) && ( sscanf( p, "remaining capacity: %d ",
+ &AcpiBatRemainingCapacity ) != 1 ) ) {
+ p = strchr( p, '\n' );
+ if ( p )
+ p++;
+ }
+
+ /* get current battery usage, (current Current) */
+ p = AcpiBatStateBuf;
+ while ( ( p!= NULL ) && ( sscanf( p, "present rate: %d ",
+ &AcpiBatteryUsage[i] ) != 1 ) ) {
+ p = strchr( p, '\n' );
+ if ( p )
+ p++;
+ }
+
+
+ /* calculate charge rate */
+ if ( AcpiBatCapacity > 0 )
+ AcpiBatteryCharge[ i ] = AcpiBatRemainingCapacity * 100 / AcpiBatCapacity;
+ else
+ AcpiBatteryCharge[ i ] = 0;
+ }
+
+ return 0;
+}
+
+void printAcpiBatFill( const char* cmd )
+{
+ int i;
+
+ sscanf( cmd + 13, "%d", &i );
+ fprintf( CurrentClient, "%d\n", AcpiBatteryCharge[ i ] );
+}
+
+void printAcpiBatFillInfo( const char* cmd )
+{
+ int i;
+
+ sscanf( cmd + 13, "%d", &i );
+ fprintf( CurrentClient, "Battery %d charge\t0\t100\t%%\n", i );
+}
+
+void printAcpiBatUsage( const char* cmd)
+{
+ int i;
+
+ sscanf( cmd + 13, "%d", &i );
+ fprintf(CurrentClient, "%d\n", AcpiBatteryUsage[ i ] );
+}
+
+void printAcpiBatUsageInfo( const char* cmd)
+{
+
+ int i;
+
+ sscanf(cmd+13, "%d", &i);
+
+ fprintf(CurrentClient, "Battery %d usage\t0\t2500\tmA\n", i );
+}
+
+/************** ACPI Thermal *****************/
+
+#define THERMAL_ZONE_DIR "/proc/acpi/thermal_zone"
+#define TEMPERATURE_FILE "temperature"
+#define TEMPERATURE_FILE_MAXLEN 255
+
+
+/*static char **zone_names = NULL;*/
+
+/** Find the thermal zone name from the command.
+ * Assumes the command is of the form acpi/thermal_zone/<zone name>/...
+ * @p startidx is set to the start of the zone name. May be set to an
+ * undefined value if zone name is not found.
+ * @return length of found name, or 0 if nothing found.
+ */
+static int extract_zone_name(char **startidx, const char *cmd)
+{
+ char *idx = NULL;
+ idx = strchr(cmd, '/');
+ if (idx == NULL) return 0;
+ idx = strchr(idx+1, '/');
+ if (idx == NULL) return 0;
+ *startidx = idx+1;
+ idx = strchr(*startidx, '/');
+ if (idx == NULL) return 0;
+ return idx - *startidx;
+}
+
+void initAcpiThermal(struct SensorModul *sm)
+{
+
+ char th_ref[ ACPIFILENAMELENGTHMAX ];
+ DIR *d = NULL;
+ struct dirent *de;
+
+ d = opendir(THERMAL_ZONE_DIR);
+ if (d == NULL) {
+/* print_error( "Directory \'" THERMAL_ZONE_DIR
+ "\' does not exist or is not readable.\n"
+ "Load the ACPI thermal kernel module or compile it into your kernel.\n" );
+*/
+ AcpiThermalZones = -1;
+ return;
+ }
+
+ AcpiThermalZones = 0;
+ while ( (de = readdir(d)) != NULL ) {
+ if ( ( strcmp( de->d_name, "." ) == 0 )
+ || ( strcmp( de->d_name, ".." ) == 0 ) ) {
+ continue;
+ }
+
+ AcpiThermalZones++;
+ snprintf(th_ref, sizeof(th_ref),
+ "acpi/thermal_zone/%s/temperature", de->d_name);
+ registerMonitor(th_ref, "integer", printThermalZoneTemperature,
+ printThermalZoneTemperatureInfo, sm);
+ }
+
+ return;
+}
+
+int updateAcpiThermal()
+{
+ /* TODO: stub */
+ return 0;
+}
+
+static int getCurrentTemperature(const char *cmd)
+{
+ char th_file[ ACPIFILENAMELENGTHMAX ];
+ char input_buf[ TEMPERATURE_FILE_MAXLEN ];
+ char *zone_name = NULL;
+ int read_bytes = 0, fd = 0, len_zone_name = 0;
+ int temperature=0;
+
+ len_zone_name = extract_zone_name(&zone_name, cmd);
+ if (len_zone_name <= 0) return -1;
+
+ snprintf(th_file, sizeof(th_file),
+ THERMAL_ZONE_DIR "/%.*s/" TEMPERATURE_FILE,
+ len_zone_name, zone_name);
+
+ fd = open(th_file, O_RDONLY);
+ if (fd < 0) {
+ print_error( "Cannot open file \'%s\'!\n"
+ "Load the thermal ACPI kernel module or\n"
+ "compile it into your kernel.\n", th_file );
+ return -1;
+ }
+
+ read_bytes = read( fd, input_buf, sizeof(input_buf) - 1 );
+ if ( read_bytes == sizeof(input_buf) - 1 ) {
+ log_error( "Internal buffer too small to read \'%s\'", th_file );
+ close( fd );
+ return -1;
+ }
+ close(fd);
+
+ sscanf(input_buf, "temperature: %d C", &temperature);
+ return temperature;
+}
+
+void printThermalZoneTemperature(const char *cmd) {
+ int temperature = getCurrentTemperature(cmd);
+ fprintf(CurrentClient, "%d\n", temperature);
+}
+
+void printThermalZoneTemperatureInfo(const char *cmd)
+{
+ fprintf(CurrentClient, "Current temperature\t0\t0\tC\n");
+}
+
+/********** ACPI Fan State***************/
+
+#define FAN_DIR "/proc/acpi/fan"
+#define FAN_STATE_FILE "state"
+#define FAN_STATE_FILE_MAXLEN 255
+
+void initAcpiFan(struct SensorModul *sm)
+{
+
+ char th_ref[ ACPIFILENAMELENGTHMAX ];
+ DIR *d = NULL;
+ struct dirent *de;
+
+ d = opendir(FAN_DIR);
+ if (d == NULL) {
+/* print_error( "Directory \'" THERMAL_ZONE_DIR
+ "\' does not exist or is not readable.\n"
+ "Load the ACPI thermal kernel module or compile it into your kernel.\n" );
+*/
+ AcpiFans = -1;
+ return;
+ }
+
+ AcpiFans = 0;
+ while ( (de = readdir(d)) != NULL ) {
+ if ( ( strcmp( de->d_name, "." ) == 0 )
+ || ( strcmp( de->d_name, ".." ) == 0 ) ) {
+ continue;
+ }
+
+ AcpiFans++;
+ snprintf(th_ref, sizeof(th_ref),
+ "acpi/fan/%s/state", de->d_name);
+ registerMonitor(th_ref, "integer", printFanState,
+ printFanStateInfo, sm);
+ }
+
+ return;
+}
+
+int updateAcpiFan()
+{
+ /* TODO: stub */
+ return 0;
+}
+
+static int getFanState(const char *cmd)
+{
+ char fan_state_file[ ACPIFILENAMELENGTHMAX ];
+ char input_buf[ FAN_STATE_FILE_MAXLEN ];
+ char *fan_name = NULL;
+ int read_bytes = 0, fd = 0, len_fan_name = 0;
+ char fan_state[4];
+
+ len_fan_name = extract_zone_name(&fan_name, cmd);
+ if (len_fan_name <= 0) return -1;
+
+ snprintf(fan_state_file, sizeof(fan_state_file),
+ FAN_DIR "/%.*s/" FAN_STATE_FILE,
+ len_fan_name, fan_name);
+
+ fd = open(fan_state_file, O_RDONLY);
+ if (fd < 0) {
+ print_error( "Cannot open file \'%s\'!\n"
+ "Load the fan ACPI kernel module or\n"
+ "compile it into your kernel.\n", fan_state_file );
+ return -1;
+ }
+
+ read_bytes = read( fd, input_buf, sizeof(input_buf) - 1 );
+ if ( read_bytes == sizeof(input_buf) - 1 ) {
+ log_error( "Internal buffer too small to read \'%s\'", fan_state_file );
+ close( fd );
+ return -1;
+ }
+ close(fd);
+
+ sscanf(input_buf, "status: %2s", fan_state);
+ return (fan_state[1] == 'n') ? 1 : 0;
+}
+
+void printFanState(const char *cmd) {
+ int fan_state = getFanState(cmd);
+ fprintf(CurrentClient, "%d\n", fan_state);
+}
+
+void printFanStateInfo(const char *cmd)
+{
+ fprintf(CurrentClient, "Fan status\t0\t1\tboolean\n");
+}
+
+
diff --git a/ksysguard/ksysguardd/Linux/acpi.h b/ksysguard/ksysguardd/Linux/acpi.h
new file mode 100644
index 000000000..ae01ecad1
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/acpi.h
@@ -0,0 +1,45 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2003 Stephan Uhlmann <su@su2.info>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSG_ACPI_H
+#define KSG_ACPI_H
+
+void initAcpi( struct SensorModul* );
+void exitAcpi( void );
+
+int updateAcpi( void );
+
+void initAcpiBattery( struct SensorModul* );
+int updateAcpiBattery(void);
+void printAcpiBatFill( const char* );
+void printAcpiBatFillInfo( const char* );
+void printAcpiBatUsage( const char* );
+void printAcpiBatUsageInfo( const char* );
+
+void initAcpiThermal( struct SensorModul * );
+int updateAcpiThermal(void);
+void printThermalZoneTemperature(const char *cmd);
+void printThermalZoneTemperatureInfo(const char *cmd);
+
+void initAcpiFan( struct SensorModul * );
+int updateAcpiFan(void);
+void printFanState(const char *cmd);
+void printFanStateInfo(const char *cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/Linux/apm.c b/ksysguard/ksysguardd/Linux/apm.c
new file mode 100644
index 000000000..0c1d00bcb
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/apm.c
@@ -0,0 +1,126 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 - 2001 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "Command.h"
+#include "ksysguardd.h"
+
+#include "apm.h"
+
+static int ApmOK = 0;
+static int BatFill, BatTime;
+
+#define APMBUFSIZE 128
+static char ApmBuf[ APMBUFSIZE ];
+static int Dirty = 0;
+
+static void processApm( void )
+{
+ sscanf( ApmBuf, "%*f %*f %*x %*x %*x %*x %d%% %d min",
+ &BatFill, &BatTime );
+ Dirty = 0;
+}
+
+/*
+================================ public part =================================
+*/
+
+void initApm( struct SensorModul* sm )
+{
+ if ( updateApm() < 0 ) {
+ ApmOK = -1;
+ return;
+ } else
+ ApmOK = 1;
+
+ registerMonitor( "apm/batterycharge", "integer", printApmBatFill, printApmBatFillInfo, sm );
+ registerMonitor( "apm/remainingtime", "integer", printApmBatTime, printApmBatTimeInfo, sm );
+}
+
+void exitApm( void )
+{
+ ApmOK = -1;
+}
+
+int updateApm( void )
+{
+ size_t n;
+ int fd;
+
+ if ( ApmOK < 0 )
+ return -1;
+
+ if ( ( fd = open( "/proc/apm", O_RDONLY ) ) < 0 ) {
+ if ( ApmOK != 0 )
+ print_error( "Cannot open file \'/proc/apm\'!\n"
+ "The kernel needs to be compiled with support\n"
+ "for /proc filesystem enabled!\n" );
+ return -1;
+ }
+
+ if ( ( n = read( fd, ApmBuf, APMBUFSIZE - 1 ) ) == APMBUFSIZE - 1 ) {
+ log_error( "Internal buffer too small to read \'/proc/apm\'" );
+ close( fd );
+ return -1;
+ }
+
+ close( fd );
+ ApmBuf[ n ] = '\0';
+ Dirty = 1;
+
+ return 0;
+}
+
+void printApmBatFill( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processApm();
+
+ fprintf( CurrentClient, "%d\n", BatFill );
+}
+
+void printApmBatFillInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "Battery charge\t0\t100\t%%\n" );
+}
+
+void printApmBatTime( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processApm();
+
+ fprintf( CurrentClient, "%d\n", BatTime );
+}
+
+void printApmBatTimeInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "Remaining battery time\t0\t0\tmin\n" );
+}
diff --git a/ksysguard/ksysguardd/Linux/apm.h b/ksysguard/ksysguardd/Linux/apm.h
new file mode 100644
index 000000000..982c77f7c
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/apm.h
@@ -0,0 +1,34 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 - 2000 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KSG_APM_H
+#define KSG_APM_H
+
+void initApm( struct SensorModul* );
+void exitApm( void );
+
+int updateApm( void );
+
+void printApmBatFill( const char* );
+void printApmBatFillInfo( const char* );
+void printApmBatTime( const char* );
+void printApmBatTimeInfo( const char* );
+
+#endif
diff --git a/ksysguard/ksysguardd/Linux/cpuinfo.c b/ksysguard/ksysguardd/Linux/cpuinfo.c
new file mode 100644
index 000000000..de5deb80f
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/cpuinfo.c
@@ -0,0 +1,179 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2000-2001 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+
+#include "Command.h"
+#include "ksysguardd.h"
+
+#include "cpuinfo.h"
+
+static int CpuInfoOK = 0;
+static float* Clocks = 0;
+static int CPUs = 0;
+
+#define CPUINFOBUFSIZE (32 * 1024)
+static char CpuInfoBuf[ CPUINFOBUFSIZE ];
+static int Dirty = 0;
+static struct SensorModul *CpuInfoSM;
+
+static void processCpuInfo( void )
+{
+ char format[ 32 ];
+ char tag[ 32 ];
+ char value[ 256 ];
+ char* cibp = CpuInfoBuf;
+ int cpuId = 0;
+
+ if ( !CpuInfoOK )
+ return;
+
+ sprintf( format, "%%%d[^:]: %%%d[^\n]\n", (int)sizeof( tag ) - 1,
+ (int)sizeof( value ) - 1 );
+
+ while ( sscanf( cibp, format, tag, value ) == 2 ) {
+ char* p;
+ tag[ sizeof( tag ) - 1 ] = '\0';
+ value[ sizeof( value ) - 1 ] = '\0';
+ /* remove trailing whitespaces */
+ p = tag + strlen( tag ) - 1;
+ /* remove trailing whitespaces */
+ while ( ( *p == ' ' || *p == '\t' ) && p > tag )
+ *p-- = '\0';
+
+ if ( strcmp( tag, "processor" ) == 0 ) {
+ if ( sscanf( value, "%d", &cpuId ) == 1 ) {
+ if ( cpuId >= CPUs ) {
+ char cmdName[ 24 ];
+ if ( Clocks )
+ free( Clocks );
+ CPUs = cpuId + 1;
+ Clocks = malloc( CPUs * sizeof( float ) );
+ snprintf( cmdName, sizeof( cmdName ) - 1, "cpu%d/clock", cpuId );
+ registerMonitor( cmdName, "float", printCPUxClock, printCPUxClockInfo,
+ CpuInfoSM );
+ }
+ }
+ } else if ( strcmp( tag, "cpu MHz" ) == 0 )
+ sscanf( value, "%f", &Clocks[ cpuId ] );
+
+ /* Move cibp to begining of next line, if there is one. */
+ cibp = strchr( cibp, '\n' );
+ if ( cibp )
+ cibp++;
+ else
+ cibp = CpuInfoBuf + strlen( CpuInfoBuf );
+ }
+
+ Dirty = 0;
+}
+
+/*
+================================ public part =================================
+*/
+
+void initCpuInfo( struct SensorModul* sm )
+{
+ CpuInfoSM = sm;
+
+ if ( updateCpuInfo() < 0 )
+ return;
+
+ processCpuInfo();
+}
+
+void exitCpuInfo( void )
+{
+ CpuInfoOK = -1;
+
+ free( Clocks );
+}
+
+int updateCpuInfo( void )
+{
+ size_t n;
+ int fd;
+
+ if ( CpuInfoOK < 0 )
+ return -1;
+
+ if ( ( fd = open( "/proc/cpuinfo", O_RDONLY ) ) < 0 ) {
+ if ( CpuInfoOK != 0 )
+ print_error( "Cannot open file \'/proc/cpuinfo\'!\n"
+ "The kernel needs to be compiled with support\n"
+ "for /proc filesystem enabled!\n" );
+ CpuInfoOK = -1;
+ return -1;
+ }
+
+ n = 0;
+ for(;;) {
+ ssize_t len = read( fd, CpuInfoBuf + n, CPUINFOBUFSIZE - 1 - n );
+ if( len < 0 ) {
+ print_error( "Failed to read file \'/proc/cpuinfo\'!\n" );
+ CpuInfoOK = -1;
+ close( fd );
+ return -1;
+ }
+ n += len;
+ if( len == 0 ) /* reading finished */
+ break;
+ if( n == CPUINFOBUFSIZE - 1 ) {
+ log_error( "Internal buffer too small to read \'/proc/cpuinfo\'" );
+ CpuInfoOK = 0;
+ close( fd );
+ return -1;
+ }
+ }
+
+ close( fd );
+ CpuInfoOK = 1;
+ CpuInfoBuf[ n ] = '\0';
+ Dirty = 1;
+
+ return 0;
+}
+
+void printCPUxClock( const char* cmd )
+{
+ int id;
+
+ if ( Dirty )
+ processCpuInfo();
+
+ sscanf( cmd + 3, "%d", &id );
+ fprintf( CurrentClient, "%f\n", Clocks[ id ] );
+}
+
+void printCPUxClockInfo( const char* cmd )
+{
+ int id;
+
+ sscanf( cmd + 3, "%d", &id );
+ fprintf( CurrentClient, "CPU%d Clock Frequency\t0\t0\tMHz\n", id );
+}
diff --git a/ksysguard/ksysguardd/Linux/cpuinfo.h b/ksysguard/ksysguardd/Linux/cpuinfo.h
new file mode 100644
index 000000000..f2380cce7
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/cpuinfo.h
@@ -0,0 +1,32 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2000-2001 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KSG_CPUINFO_H
+#define KSG_CPUINFO_H
+
+void initCpuInfo( struct SensorModul* );
+void exitCpuInfo( void );
+
+int updateCpuInfo( void );
+
+void printCPUxClock( const char* );
+void printCPUxClockInfo( const char* );
+
+#endif
diff --git a/ksysguard/ksysguardd/Linux/diskstat.c b/ksysguard/ksysguardd/Linux/diskstat.c
new file mode 100644
index 000000000..012ed5a8e
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/diskstat.c
@@ -0,0 +1,265 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <config.h>
+
+#include <mntent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/vfs.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "Command.h"
+#include "ccont.h"
+#include "diskstat.h"
+#include "ksysguardd.h"
+
+typedef struct {
+ char device[ 256 ];
+ char mntpnt[ 256 ];
+ long blocks;
+ long bfree;
+ long bused;
+ int bused_percent;
+} DiskInfo;
+
+static CONTAINER DiskStatList = 0;
+static struct SensorModul* DiskStatSM;
+char *getMntPnt( const char* cmd );
+
+char *getMntPnt( const char* cmd )
+{
+ static char device[ 1025 ];
+ char* ptr;
+
+ memset( device, 0, sizeof( device ) );
+ sscanf( cmd, "partitions%1024s", device );
+
+ ptr = (char*)rindex( device, '/' );
+ *ptr = '\0';
+
+ return (char*)device;
+}
+
+/* ----------------------------- public part ------------------------------- */
+
+void initDiskStat( struct SensorModul* sm )
+{
+ char monitor[ 1024 ];
+ DiskInfo* disk_info;
+
+ DiskStatList = new_ctnr();
+ DiskStatSM = sm;
+
+ if ( updateDiskStat() < 0 )
+ return;
+
+ registerMonitor( "partitions/list", "listview", printDiskStat, printDiskStatInfo, sm );
+
+ for ( disk_info = first_ctnr( DiskStatList ); disk_info; disk_info = next_ctnr( DiskStatList ) ) {
+ snprintf( monitor, sizeof( monitor ), "partitions%s/usedspace", disk_info->mntpnt );
+ registerMonitor( monitor, "integer", printDiskStatUsed, printDiskStatUsedInfo, DiskStatSM );
+ snprintf( monitor, sizeof( monitor ), "partitions%s/freespace", disk_info->mntpnt );
+ registerMonitor( monitor, "integer", printDiskStatFree, printDiskStatFreeInfo, DiskStatSM );
+ snprintf( monitor, sizeof( monitor ), "partitions%s/filllevel", disk_info->mntpnt );
+ registerMonitor( monitor, "integer", printDiskStatPercent, printDiskStatPercentInfo, DiskStatSM );
+ }
+}
+
+void exitDiskStat( void )
+{
+ char monitor[ 1024 ];
+ DiskInfo* disk_info;
+
+ removeMonitor( "partitions/list" );
+
+ for ( disk_info = first_ctnr( DiskStatList ); disk_info; disk_info = next_ctnr( DiskStatList ) ) {
+ snprintf( monitor, sizeof( monitor ), "partitions%s/usedspace", disk_info->mntpnt );
+ removeMonitor( monitor );
+ snprintf( monitor, sizeof( monitor ), "partitions%s/freespace", disk_info->mntpnt );
+ removeMonitor( monitor );
+ snprintf( monitor, sizeof( monitor ), "partitions%s/filllevel", disk_info->mntpnt );
+ removeMonitor( monitor );
+ }
+
+ destr_ctnr( DiskStatList, free );
+}
+
+void checkDiskStat( void )
+{
+ struct stat mtab_info;
+ static off_t mtab_size = 0;
+
+ stat( "/etc/mtab", &mtab_info );
+ if ( !mtab_size )
+ mtab_size = mtab_info.st_size;
+
+ if ( mtab_info.st_size != mtab_size ) {
+ exitDiskStat();
+ initDiskStat( DiskStatSM );
+ mtab_size = mtab_info.st_size;
+ }
+}
+
+int updateDiskStat( void )
+{
+ DiskInfo *disk_info;
+ FILE *fh;
+ struct mntent *mnt_info;
+ float percent;
+ int i;
+ struct statfs fs_info;
+
+ if ( ( fh = setmntent( "/etc/mtab", "r" ) ) == NULL ) {
+ print_error( "Cannot open \'/etc/mtab\'!\n" );
+ return -1;
+ }
+
+ for ( i = level_ctnr( DiskStatList ); i >= 0; --i )
+ free( pop_ctnr( DiskStatList ) );
+
+ while ( ( mnt_info = getmntent( fh ) ) != NULL ) {
+ if ( statfs( mnt_info->mnt_dir, &fs_info ) < 0 )
+ continue;
+
+ if ( strcmp( mnt_info->mnt_type, "proc" ) &&
+ strcmp( mnt_info->mnt_type, "devfs" ) &&
+ strcmp( mnt_info->mnt_type, "usbfs" ) &&
+ strcmp( mnt_info->mnt_type, "sysfs" ) &&
+ strcmp( mnt_info->mnt_type, "tmpfs" ) &&
+ strcmp( mnt_info->mnt_type, "devpts" ) ) {
+ if ( fs_info.f_blocks != 0 )
+ {
+ percent = ( ( (float)fs_info.f_blocks - (float)fs_info.f_bfree ) /
+ (float)fs_info.f_blocks );
+ percent = percent * 100;
+ }
+ else
+ {
+ percent = 0;
+ }
+
+ if ( ( disk_info = (DiskInfo *)malloc( sizeof( DiskInfo ) ) ) == NULL )
+ continue;
+
+ memset( disk_info, 0, sizeof( DiskInfo ) );
+ strlcpy( disk_info->device, mnt_info->mnt_fsname, sizeof( disk_info->device ) );
+ if ( !strcmp( mnt_info->mnt_dir, "/" ) )
+ strlcpy( disk_info->mntpnt, "/root", sizeof( disk_info->mntpnt ) );
+ else
+ strlcpy( disk_info->mntpnt, mnt_info->mnt_dir, sizeof( disk_info->mntpnt ) );
+
+ disk_info->blocks = fs_info.f_blocks;
+ disk_info->bfree = fs_info.f_bfree;
+ disk_info->bused = fs_info.f_blocks - fs_info.f_bfree;
+ disk_info->bused_percent = (int)percent;
+
+ push_ctnr( DiskStatList, disk_info );
+ }
+ }
+
+ endmntent( fh );
+
+ return 0;
+}
+
+void printDiskStat( const char* cmd )
+{
+ DiskInfo* disk_info;
+
+ (void)cmd;
+ for ( disk_info = first_ctnr( DiskStatList ); disk_info; disk_info = next_ctnr( DiskStatList ) ) {
+ fprintf( CurrentClient, "%s\t%ld\t%ld\t%ld\t%d\t%s\n",
+ disk_info->device,
+ disk_info->blocks,
+ disk_info->bused,
+ disk_info->bfree,
+ disk_info->bused_percent,
+ disk_info->mntpnt );
+ }
+
+ fprintf( CurrentClient, "\n" );
+}
+
+void printDiskStatInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "Device\tBlocks\tUsed\tAvailable\tUsed %%\tMountPoint\nM\tD\tD\tD\td\ts\n" );
+}
+
+void printDiskStatUsed( const char* cmd )
+{
+ char *mntpnt = (char*)getMntPnt( cmd );
+ DiskInfo* disk_info;
+
+ for ( disk_info = first_ctnr( DiskStatList ); disk_info; disk_info = next_ctnr( DiskStatList ) ) {
+ if ( !strcmp( mntpnt, disk_info->mntpnt ) )
+ fprintf( CurrentClient, "%ld\n", disk_info->bused );
+ }
+
+ fprintf( CurrentClient, "\n" );
+}
+
+void printDiskStatUsedInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "Used Blocks\t0\t-\tBlocks\n" );
+}
+
+void printDiskStatFree( const char* cmd )
+{
+ char *mntpnt = (char*)getMntPnt( cmd );
+ DiskInfo* disk_info;
+
+ for ( disk_info = first_ctnr( DiskStatList ); disk_info; disk_info = next_ctnr( DiskStatList ) ) {
+ if ( !strcmp( mntpnt, disk_info->mntpnt ) )
+ fprintf( CurrentClient, "%ld\n", disk_info->bfree );
+ }
+
+ fprintf( CurrentClient, "\n" );
+}
+
+void printDiskStatFreeInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "Free Blocks\t0\t-\tBlocks\n" );
+}
+
+void printDiskStatPercent( const char* cmd )
+{
+ char *mntpnt = (char*)getMntPnt( cmd );
+ DiskInfo* disk_info;
+
+ for ( disk_info = first_ctnr( DiskStatList ); disk_info; disk_info = next_ctnr( DiskStatList ) ) {
+ if ( !strcmp( mntpnt, disk_info->mntpnt ) )
+ fprintf( CurrentClient, "%d\n", disk_info->bused_percent );
+ }
+
+ fprintf( CurrentClient, "\n" );
+}
+
+void printDiskStatPercentInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "Used Blocks\t0\t100\t%%\n" );
+}
diff --git a/ksysguard/ksysguardd/Linux/diskstat.h b/ksysguard/ksysguardd/Linux/diskstat.h
new file mode 100644
index 000000000..6a23e6148
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/diskstat.h
@@ -0,0 +1,40 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KSG_DISKSTAT_H
+#define KSG_DISKSTAT_H
+
+void initDiskStat( struct SensorModul* );
+void exitDiskStat( void );
+
+int updateDiskStat( void );
+void checkDiskStat( void );
+
+void printDiskStat( const char* );
+void printDiskStatInfo( const char* );
+
+void printDiskStatUsed( const char* );
+void printDiskStatUsedInfo( const char* );
+void printDiskStatFree( const char* );
+void printDiskStatFreeInfo( const char* );
+void printDiskStatPercent( const char* );
+void printDiskStatPercentInfo( const char* );
+
+#endif
diff --git a/ksysguard/ksysguardd/Linux/i8k.c b/ksysguard/ksysguardd/Linux/i8k.c
new file mode 100644
index 000000000..c6bbe7d72
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/i8k.c
@@ -0,0 +1,150 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 - 2001 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "Command.h"
+#include "ksysguardd.h"
+
+#include "i8k.h"
+
+#ifdef HAVE_I8K_SUPPORT
+
+static int I8kOK = 0;
+static int cpuTemp, fan0Speed, fan1Speed;
+
+#define I8KBUFSIZE 128
+static char I8kBuf[ I8KBUFSIZE ];
+
+/*
+================================ public part =================================
+*/
+
+void initI8k( struct SensorModul* sm )
+{
+ if ( updateI8k() < 0 ) {
+ I8kOK = -1;
+ return;
+ } else
+ I8kOK = 1;
+
+ registerMonitor( "dell/cputemp", "integer", printI8kCPUTemperature,
+ printI8kCPUTemperatureInfo, sm );
+ registerMonitor( "dell/fan0", "integer", printI8kFan0Speed,
+ printI8kFan0SpeedInfo, sm );
+ registerMonitor( "dell/fan1", "integer", printI8kFan1Speed,
+ printI8kFan1SpeedInfo, sm );
+}
+
+void exitI8k( void )
+{
+ I8kOK = -1;
+}
+
+int updateI8k( void )
+{
+ size_t n;
+ int fd;
+
+ if ( I8kOK < 0 )
+ return -1;
+
+ if ( ( fd = open( "/proc/i8k", O_RDONLY ) ) < 0 ) {
+ print_error( "Cannot open file \'/proc/i8k\'!\n"
+ "The kernel needs to be compiled with support\n"
+ "for /proc filesystem enabled!\n" );
+ return -1;
+ }
+
+ if ( ( n = read( fd, I8kBuf, I8KBUFSIZE - 1 ) ) == I8KBUFSIZE - 1 ) {
+ log_error( "Internal buffer too small to read \'/proc/i8k\'" );
+
+ close( fd );
+ return -1;
+ }
+
+ close( fd );
+ I8kBuf[ n ] = '\0';
+
+ sscanf( I8kBuf, "%*f %*s %*s %d %*d %*d %d %d %*d %*d",
+ &cpuTemp, &fan0Speed, &fan1Speed );
+
+ return 0;
+}
+
+void printI8kCPUTemperature( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "%d\n", cpuTemp );
+}
+
+void printI8kCPUTemperatureInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "CPU Temperature\t0\t0\tC\n" );
+}
+
+void printI8kFan0Speed( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "%d\n", fan0Speed );
+}
+
+void printI8kFan0SpeedInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "Left fan\t0\t0\trpm\n" );
+}
+
+void printI8kFan1Speed( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "%d\n", fan1Speed );
+}
+
+void printI8kFan1SpeedInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "Right fan\t0\t0\trpm\n" );
+}
+
+#else /* HAVE_I8K_SUPPORT */
+
+/* dummy version for systems that have no i8k support */
+
+void initI8k( struct SensorModul* sm )
+{
+ (void)sm;
+}
+
+void exitI8k( void )
+{
+}
+
+int updateI8k( void )
+{
+ return 0;
+}
+
+#endif
diff --git a/ksysguard/ksysguardd/Linux/i8k.h b/ksysguard/ksysguardd/Linux/i8k.h
new file mode 100644
index 000000000..40c2a886d
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/i8k.h
@@ -0,0 +1,36 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 - 2000 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KSG_I8K_H
+#define KSG_I8K_H
+
+void initI8k( struct SensorModul* );
+void exitI8k( void );
+
+int updateI8k( void );
+
+void printI8kCPUTemperature( const char* );
+void printI8kCPUTemperatureInfo( const char* );
+void printI8kFan0Speed( const char* );
+void printI8kFan0SpeedInfo( const char* );
+void printI8kFan1Speed( const char* );
+void printI8kFan1SpeedInfo( const char* );
+
+#endif
diff --git a/ksysguard/ksysguardd/Linux/lmsensors.c b/ksysguard/ksysguardd/Linux/lmsensors.c
new file mode 100644
index 000000000..37e41d2a1
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/lmsensors.c
@@ -0,0 +1,309 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 - 2001 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Command.h"
+#include "ccont.h"
+#include "ksysguardd.h"
+
+#include "lmsensors.h"
+
+#ifdef HAVE_SENSORS_SENSORS_H
+#include <sensors/sensors.h>
+
+#ifndef SENSORS_API_VERSION
+#define SENSORS_API_VERSION 0x000
+#endif
+#ifndef SENSORS_CHIP_NAME_BUS_PCI
+#define SENSORS_CHIP_NAME_BUS_PCI -5
+#endif
+#ifndef SENSORS_CHIP_NAME_BUS_ISA
+#define SENSORS_CHIP_NAME_BUS_ISA -1
+#endif
+
+#define BUFFER_SIZE_LMSEN 300
+typedef struct
+{
+ char* fullName;
+ const sensors_chip_name* scn;
+#if SENSORS_API_VERSION & 0x400
+ const sensors_feature *sf;
+ const sensors_subfeature *sfd;
+#else
+ const sensors_feature_data* sfd;
+#endif
+} LMSENSOR;
+
+static CONTAINER LmSensors;
+static int LmSensorsOk = -1;
+
+static int sensorCmp( void* s1, void* s2 )
+{
+ return strcmp( ((LMSENSOR*)s1)->fullName, ((LMSENSOR*)s2)->fullName );
+}
+
+static LMSENSOR* findMatchingSensor( const char* name )
+{
+ INDEX idx;
+ LMSENSOR key;
+ LMSENSOR* s;
+
+ if(name == NULL || name[0] == '\0') return 0;
+ key.fullName = strdup( name );
+ int end = strlen(key.fullName)-1;
+ if(key.fullName[end] == '?')
+ key.fullName[end] = '\0';
+ if ( ( idx = search_ctnr( LmSensors, sensorCmp, &key ) ) < 0 ) {
+ free( key.fullName );
+ return 0;
+ }
+
+ free( key.fullName );
+ s = get_ctnr( LmSensors, idx );
+
+ return s;
+}
+
+static const char *chipName(const sensors_chip_name *chip) {
+ static char buffer[256];
+#if SENSORS_API_VERSION & 0x400
+ sensors_snprintf_chip_name(buffer, sizeof(buffer), chip);
+#else /* SENSORS_API_VERSION & 0x400 */
+ if (chip->bus == SENSORS_CHIP_NAME_BUS_ISA)
+ snprintf (buffer, sizeof(buffer), "%s-isa-%04x", chip->prefix, chip->addr);
+ else if (chip->bus == SENSORS_CHIP_NAME_BUS_PCI)
+ snprintf (buffer, sizeof(buffer), "%s-pci-%04x", chip->prefix, chip->addr);
+ else
+ snprintf (buffer, sizeof(buffer), "%s-i2c-%d-%02x", chip->prefix, chip->bus, chip->addr);
+#endif /* SENSORS_API_VERSION & 0x400 */
+ return buffer;
+}
+
+#if SENSORS_API_VERSION & 0x400
+void initLmSensors( struct SensorModul* sm )
+{
+ const sensors_chip_name* scn;
+ int nr = 0;
+
+ if ( sensors_init( NULL ) ) {
+ LmSensorsOk = -1;
+ return;
+ }
+
+ LmSensors = new_ctnr();
+ while ( ( scn = sensors_get_detected_chips( NULL, &nr ) ) != NULL ) {
+ int nr1 = 0;
+ const sensors_feature* sf;
+
+ while ( ( sf = sensors_get_features( scn, &nr1 ) ) != 0 ) {
+ const sensors_subfeature *ssubf;
+ LMSENSOR *p;
+ char *s, *label;
+
+ switch( sf->type )
+ {
+ case SENSORS_FEATURE_IN:
+ ssubf = sensors_get_subfeature( scn, sf,
+ SENSORS_SUBFEATURE_IN_INPUT );
+ break;
+
+ case SENSORS_FEATURE_FAN:
+ ssubf = sensors_get_subfeature( scn, sf,
+ SENSORS_SUBFEATURE_FAN_INPUT );
+ break;
+
+ case SENSORS_FEATURE_TEMP:
+ ssubf = sensors_get_subfeature( scn, sf,
+ SENSORS_SUBFEATURE_TEMP_INPUT );
+ break;
+ default:
+ ssubf = NULL;
+ }
+
+ if ( !ssubf )
+ continue;
+
+ label = sensors_get_label( scn, sf );
+ p = (LMSENSOR*)malloc( sizeof( LMSENSOR ) );
+ p->fullName = (char*)malloc( strlen( "lmsensors/" ) +
+ strlen( scn->prefix ) + 1 +
+ strlen( label ) + 1 );
+ snprintf( p->fullName, BUFFER_SIZE_LMSEN, "lmsensors/%s/%s", scn->prefix, label );
+
+ /* Make sure that name contains only proper characters. */
+ for ( s = p->fullName; *s; s++ )
+ if ( *s == ' ' )
+ *s = '_';
+
+ p->scn = scn;
+ p->sf = sf;
+ p->sfd = ssubf;
+
+ /* Note a name collision should never happen with the lm_sensors-3x code,
+ but it does in the case of k8temp, when there are 2 identical labeled
+ sensors per CPU. This are really 2 distinct sensors measuring the
+ same thing, but fullName must be unique so we just drop the second
+ sensor */
+ if ( search_ctnr( LmSensors, sensorCmp, p ) < 0 ) {
+ push_ctnr( LmSensors, p );
+ registerMonitor( p->fullName, "float", printLmSensor, printLmSensorInfo, sm );
+ } else {
+ free( p->fullName );
+ free( p );
+ }
+ free( label );
+ }
+ }
+ bsort_ctnr( LmSensors, sensorCmp );
+}
+#else /* SENSORS_API_VERSION & 0x400 */
+void initLmSensors( struct SensorModul* sm )
+{
+ const sensors_chip_name* scn;
+ char buffer[BUFFER_SIZE_LMSEN];
+ int nr = 0;
+
+ FILE* input;
+ if ( ( input = fopen( "/etc/sensors.conf", "r" ) ) == NULL ) {
+ LmSensorsOk = -1;
+ return;
+ }
+
+ if ( sensors_init( input ) ) {
+ LmSensorsOk = -1;
+ fclose( input );
+ return;
+ }
+
+ fclose( input );
+
+ LmSensors = new_ctnr();
+ while ( ( scn = sensors_get_detected_chips( &nr ) ) != NULL ) {
+ int nr1, nr2;
+ const sensors_feature_data* sfd;
+ nr1 = nr2 = 0;
+ while ( ( sfd = sensors_get_all_features( *scn, &nr1, &nr2 ) ) != 0 ) {
+ if ( sfd->mapping == SENSORS_NO_MAPPING && sfd->mode & SENSORS_MODE_R /* readable feature */) {
+ LMSENSOR* p;
+ char* label=NULL;
+
+ if(sensors_get_label( *scn, sfd->number, &label ) != 0)
+ continue; /*error*/
+ else
+ free( label );
+ if(sensors_get_ignored( *scn, sfd->number) != 1 )
+ continue; /* 1 for not ignored, 0 for ignore, <0 for error */
+ double result;
+ if(sensors_get_feature( *scn, sfd->number, &result) != 0 )
+ continue; /* Make sure this feature actually works. 0 for success, <0 for fail */
+
+ p = (LMSENSOR*)malloc( sizeof( LMSENSOR ) );
+
+ snprintf( buffer, BUFFER_SIZE_LMSEN, "lmsensors/%s/%s", chipName(scn), sfd->name );
+
+ p->fullName = strndup(buffer, BUFFER_SIZE_LMSEN);
+
+ p->scn = scn;
+ p->sfd = sfd;
+ if ( search_ctnr( LmSensors, sensorCmp, p ) < 0 ) {
+ push_ctnr( LmSensors, p );
+ registerMonitor( p->fullName, "float", printLmSensor, printLmSensorInfo, sm );
+ } else {
+ free( p->fullName );
+ free( p );
+ }
+ }
+ }
+ }
+ bsort_ctnr( LmSensors, sensorCmp );
+}
+#endif /* SENSORS_API_VERSION & 0x400 */
+
+void exitLmSensors( void )
+{
+ destr_ctnr( LmSensors, free );
+}
+
+void printLmSensor( const char* cmd )
+{
+ double value;
+ LMSENSOR* s;
+
+ if ( ( s = findMatchingSensor( cmd ) ) == 0 ) { /* should never happen */
+ fprintf( CurrentClient, "0\n" );
+ return;
+ }
+#if SENSORS_API_VERSION & 0x400
+ sensors_get_value( s->scn, s->sfd->number, &value );
+#else
+ sensors_get_feature( *(s->scn), s->sfd->number, &value );
+#endif
+ fprintf( CurrentClient, "%f\n", value );
+}
+
+void printLmSensorInfo( const char* cmd )
+{
+ LMSENSOR* s;
+
+ if ( ( s = findMatchingSensor( cmd ) ) == 0 ) { /* should never happen */
+ fprintf( CurrentClient, "0\n" );
+ return;
+ }
+
+ /* TODO: print real name here */
+ char *label;
+#if SENSORS_API_VERSION & 0x400
+ label = sensors_get_label( s->scn, s->sf );
+ if (label == NULL) {
+#else
+ if(sensors_get_label( *s->scn, s->sfd->number, &label ) != 0) { /*error*/
+#endif
+ fprintf( CurrentClient, "0\n" );
+ return;
+ }
+ if( strncmp(s->sfd->name, "temp", sizeof("temp")-1) == 0)
+ fprintf( CurrentClient, "%s\t0\t0\t°C\n", label );
+ else if( strncmp(s->sfd->name, "fan", sizeof("fan")-1) == 0)
+ fprintf( CurrentClient, "%s\t0\t0\trpm\n", label );
+ else
+ fprintf( CurrentClient, "%s\t0\t0\tV\n", label ); /* For everything else, say it's in volts. */
+#if SENSORS_API_VERSION & 0x400
+ free(label);
+#endif
+}
+
+#else /* HAVE_SENSORS_SENSORS_H */
+
+/* dummy version for systems that have no lmsensors support */
+
+void initLmSensors( struct SensorModul* sm )
+{
+ (void)sm;
+}
+
+void exitLmSensors( void )
+{
+}
+
+#endif
diff --git a/ksysguard/ksysguardd/Linux/lmsensors.h b/ksysguard/ksysguardd/Linux/lmsensors.h
new file mode 100644
index 000000000..29f514d4a
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/lmsensors.h
@@ -0,0 +1,30 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 - 2001 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KSG_LMSENSORS_H
+#define KSG_LMSENSORS_H
+
+void initLmSensors( struct SensorModul* );
+void exitLmSensors( void );
+
+void printLmSensor( const char* );
+void printLmSensorInfo( const char* );
+
+#endif
diff --git a/ksysguard/ksysguardd/Linux/loadavg.c b/ksysguard/ksysguardd/Linux/loadavg.c
new file mode 100644
index 000000000..788e32793
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/loadavg.c
@@ -0,0 +1,143 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999, 2000 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include "ksysguardd.h"
+#include "Command.h"
+
+#include "loadavg.h"
+
+static int LoadAvgOK = 0;
+static double LoadAvg1, LoadAvg5, LoadAvg15;
+
+#define LOADAVGBUFSIZE 128
+static char LoadAvgBuf[ LOADAVGBUFSIZE ];
+static int Dirty = 0;
+
+static void processLoadAvg( void )
+{
+ sscanf( LoadAvgBuf, "%lf %lf %lf", &LoadAvg1, &LoadAvg5, &LoadAvg15 );
+ Dirty = 0;
+}
+
+/*
+================================ public part =================================
+*/
+
+void initLoadAvg( struct SensorModul* sm )
+{
+ if ( updateLoadAvg() < 0 ) {
+ LoadAvgOK = -1;
+ return;
+ } else
+ LoadAvgOK = 1;
+
+ registerMonitor( "cpu/loadavg1", "float", printLoadAvg1, printLoadAvg1Info, sm );
+ registerMonitor( "cpu/loadavg5", "float", printLoadAvg5, printLoadAvg5Info, sm );
+ registerMonitor( "cpu/loadavg15", "float", printLoadAvg15, printLoadAvg15Info, sm );
+}
+
+void exitLoadAvg( void )
+{
+ LoadAvgOK = -1;
+}
+
+int updateLoadAvg( void )
+{
+ size_t n;
+ int fd;
+
+ if ( LoadAvgOK < 0 )
+ return -1;
+
+ if ( ( fd = open( "/proc/loadavg", O_RDONLY ) ) < 0 ) {
+ if ( LoadAvgOK != 0 )
+ print_error( "Cannot open file \'/proc/loadavg\'!\n"
+ "The kernel needs to be compiled with support\n"
+ "for /proc filesystem enabled!\n" );
+ return -1;
+ }
+
+ if ( ( n = read( fd, LoadAvgBuf, LOADAVGBUFSIZE - 1 ) ) == LOADAVGBUFSIZE - 1 ) {
+ log_error( "Internal buffer too small to read \'/proc/loadavg\'" );
+
+ close( fd );
+ return -1;
+ }
+
+ close( fd );
+ LoadAvgBuf[ n ] = '\0';
+ Dirty = 1;
+
+ return 0;
+}
+
+void printLoadAvg1( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processLoadAvg();
+
+ fprintf( CurrentClient, "%f\n", LoadAvg1 );
+}
+
+void printLoadAvg1Info( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "Load average 1 min\t0\t0\t\n" );
+}
+
+void printLoadAvg5( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processLoadAvg();
+
+ fprintf( CurrentClient, "%f\n", LoadAvg5 );
+}
+
+void printLoadAvg5Info( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "Load average 5 min\t0\t0\t\n" );
+}
+
+void printLoadAvg15( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processLoadAvg();
+
+ fprintf( CurrentClient, "%f\n", LoadAvg15 );
+}
+
+void printLoadAvg15Info( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "Load average 15 min\t0\t0\t\n" );
+}
diff --git a/ksysguard/ksysguardd/Linux/loadavg.h b/ksysguard/ksysguardd/Linux/loadavg.h
new file mode 100644
index 000000000..31628ac96
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/loadavg.h
@@ -0,0 +1,36 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999, 2000 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KSG_LOADAVG_H
+#define KSG_LOADAVG_H
+
+void initLoadAvg( struct SensorModul* );
+void exitLoadAvg( void );
+
+int updateLoadAvg( void );
+
+void printLoadAvg1( const char* );
+void printLoadAvg1Info( const char* );
+void printLoadAvg5( const char* );
+void printLoadAvg5Info( const char* );
+void printLoadAvg15( const char* );
+void printLoadAvg15Info( const char* );
+
+#endif
diff --git a/ksysguard/ksysguardd/Linux/logfile.c b/ksysguard/ksysguardd/Linux/logfile.c
new file mode 100644
index 000000000..58915a207
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/logfile.c
@@ -0,0 +1,172 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Command.h"
+#include "ccont.h"
+#include "conf.h"
+#include "ksysguardd.h"
+
+#include "logfile.h"
+
+static CONTAINER LogFiles = 0;
+static unsigned long counter = 1;
+
+typedef struct {
+ char name[ 256 ];
+ FILE* fh;
+ unsigned long id;
+} LogFileEntry;
+
+extern CONTAINER LogFileList;
+
+/*
+================================ public part =================================
+*/
+
+void initLogFile( struct SensorModul* sm )
+{
+ char monitor[ 1024 ];
+ ConfigLogFile *entry;
+
+ registerCommand( "logfile_register", registerLogFile );
+ registerCommand( "logfile_unregister", unregisterLogFile );
+ registerCommand( "logfile_registered", printRegistered );
+
+ for ( entry = first_ctnr( LogFileList ); entry; entry = next_ctnr( LogFileList ) ) {
+ FILE* fp;
+ /* Register the log file only if we can actually read the file. */
+ if ( ( fp = fopen( entry->path, "r" ) ) != NULL ) {
+ snprintf( monitor, 1024, "logfiles/%s", entry->name );
+ registerMonitor( monitor, "logfile", printLogFile, printLogFileInfo, sm );
+ fclose( fp );
+ }
+ }
+
+ LogFiles = new_ctnr();
+}
+
+void exitLogFile( void )
+{
+ destr_ctnr( LogFiles, free );
+}
+
+void printLogFile( const char* cmd )
+{
+ char line[ 1024 ];
+ unsigned long id;
+ LogFileEntry *entry;
+
+ sscanf( cmd, "%*s %lu", &id );
+
+ for ( entry = first_ctnr( LogFiles ); entry; entry = next_ctnr( LogFiles ) ) {
+ if ( entry->id == id ) {
+ while ( fgets( line, 1024, entry->fh ) != NULL )
+ fprintf( CurrentClient, "%s", line );
+
+ /* delete the EOF */
+ clearerr( entry->fh );
+ }
+ }
+
+ fprintf( CurrentClient, "\n" );
+}
+
+void printLogFileInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "LogFile\n" );
+}
+
+void registerLogFile( const char* cmd )
+{
+ char name[ 257 ];
+ FILE* file;
+ LogFileEntry *entry;
+ int i;
+
+ memset( name, 0, sizeof( name ) );
+ sscanf( cmd, "%*s %256s", name );
+
+ for ( i = 0; i < level_ctnr( LogFileList ); i++ ) {
+ ConfigLogFile *conf = get_ctnr( LogFileList, i );
+ if ( !strcmp( conf->name, name ) ) {
+ if ( ( file = fopen( conf->path, "r" ) ) == NULL ) {
+ print_error( "fopen()" );
+ fprintf( CurrentClient, "0\n" );
+ return;
+ }
+
+ fseek( file, 0, SEEK_END );
+
+ if ( ( entry = (LogFileEntry*)malloc( sizeof( LogFileEntry ) ) ) == NULL ) {
+ print_error( "malloc()" );
+ fprintf( CurrentClient, "0\n" );
+ return;
+ }
+
+ entry->fh = file;
+ strncpy( entry->name, conf->name, 256 );
+ entry->id = counter;
+
+ push_ctnr( LogFiles, entry );
+
+ fprintf( CurrentClient, "%lu\n", counter );
+ counter++;
+
+ return;
+ }
+ }
+
+ fprintf( CurrentClient, "\n" );
+}
+
+void unregisterLogFile( const char* cmd )
+{
+ unsigned long id;
+ LogFileEntry *entry;
+
+ sscanf( cmd, "%*s %lu", &id );
+
+ for ( entry = first_ctnr( LogFiles ); entry; entry = next_ctnr( LogFiles ) ) {
+ if ( entry->id == id ) {
+ fclose( entry->fh );
+ free( remove_ctnr( LogFiles ) );
+ fprintf( CurrentClient, "\n" );
+ return;
+ }
+ }
+
+ fprintf( CurrentClient, "\n" );
+}
+
+void printRegistered( const char* cmd )
+{
+ LogFileEntry *entry;
+
+ (void)cmd;
+ for ( entry = first_ctnr( LogFiles ); entry; entry = next_ctnr( LogFiles ) )
+ fprintf( CurrentClient, "%s:%lu\n", entry->name, entry->id );
+
+ fprintf( CurrentClient, "\n" );
+}
diff --git a/ksysguard/ksysguardd/Linux/logfile.h b/ksysguard/ksysguardd/Linux/logfile.h
new file mode 100644
index 000000000..5eecb2f70
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/logfile.h
@@ -0,0 +1,36 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KSG_LOGFILE_H
+#define KSG_LOGFILE_H
+
+void initLogFile( struct SensorModul* );
+void exitLogFile( void );
+
+void printLogFile( const char* );
+void printLogFileInfo( const char* );
+
+void registerLogFile( const char* );
+void unregisterLogFile( const char* );
+
+/* debug command */
+void printRegistered( const char* );
+
+#endif
diff --git a/ksysguard/ksysguardd/Linux/netdev.c b/ksysguard/ksysguardd/Linux/netdev.c
new file mode 100644
index 000000000..55e812807
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/netdev.c
@@ -0,0 +1,367 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 - 2001 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "Command.h"
+#include "ksysguardd.h"
+
+#include "netdev.h"
+
+#define MON_SIZE 128
+
+#define CALC( a, b, c, d, e ) \
+{ \
+ NetDevs[ i ].a = a - NetDevs[ i ].Old##a; \
+ NetDevs[ i ].Old##a = a; \
+}
+
+#define REGISTERSENSOR( a, b, c, d, e ) \
+{ \
+ snprintf( mon, MON_SIZE, "network/interfaces/%s/%s", tag, b ); \
+ registerMonitor( mon, "integer", printNetDev##a, printNetDev##a##Info, NetDevSM ); \
+}
+
+#define UNREGISTERSENSOR( a, b, c, d, e ) \
+{ \
+ snprintf( mon, MON_SIZE, "network/interfaces/%s/%s", NetDevs[ i ].name, b ); \
+ removeMonitor( mon ); \
+}
+
+#define DEFMEMBERS( a, b, c, d, e ) \
+unsigned long long Old##a; \
+unsigned long long a; \
+unsigned long a##Scale;
+
+#define DEFVARS( a, b, c, d, e ) \
+unsigned long long a;
+
+#define FORALL( a ) \
+ a( recBytes, "receiver/data", "Received Data", "kBytes/s", 1024 ) \
+ a( recPacks, "receiver/packets", "Received Packets", "1/s", 1 ) \
+ a( recErrs, "receiver/errors", "Receiver Errors", "1/s", 1 ) \
+ a( recDrop, "receiver/drops", "Receiver Drops", "1/s", 1 ) \
+ a( recFifo, "receiver/fifo", "Receiver FIFO Overruns", "1/s", 1 ) \
+ a( recFrame, "receiver/frame", "Receiver Frame Errors", "1/s", 1 ) \
+ a( recCompressed, "receiver/compressed", "Received Compressed Packets", "1/s", 1 ) \
+ a( recMulticast, "receiver/multicast", "Received Multicast Packets", "1/s", 1 ) \
+ a( sentBytes, "transmitter/data", "Sent Data", "kBytes/s", 1024 ) \
+ a( sentPacks, "transmitter/packets", "Sent Packets", "1/s", 1 ) \
+ a( sentErrs, "transmitter/errors", "Transmitter Errors", "1/s", 1 ) \
+ a( sentDrop, "transmitter/drops", "Transmitter Drops", "1/s", 1 ) \
+ a( sentFifo, "transmitter/fifo", "Transmitter FIFO overruns", "1/s", 1 ) \
+ a( sentColls, "transmitter/collisions", "Transmitter Collisions", "1/s", 1 ) \
+ a( sentCarrier, "transmitter/carrier", "Transmitter Carrier losses", "1/s", 1 ) \
+ a( sentCompressed, "transmitter/compressed", "Transmitter Compressed Packets", "1/s", 1 )
+
+#define SETZERO( a, b, c, d, e ) \
+a = 0;
+
+#define SETMEMBERZERO( a, b, c, d, e ) \
+NetDevs[ i ].a = 0; \
+NetDevs[ i ].a##Scale = e;
+
+#define DECLAREFUNC( a, b, c, d, e ) \
+void printNetDev##a( const char* cmd ); \
+void printNetDev##a##Info( const char* cmd );
+
+typedef struct
+{
+ FORALL( DEFMEMBERS )
+ char name[ 32 ];
+} NetDevInfo;
+
+/* We have observed deviations of up to 5% in the accuracy of the timer
+ * interrupts. So we try to measure the interrupt interval and use this
+ * value to calculate timing dependant values. */
+static float timeInterval = 0;
+static struct timeval lastSampling;
+static struct timeval currSampling;
+static struct SensorModul* NetDevSM;
+
+#define NETDEVBUFSIZE 4096
+static char NetDevBuf[ NETDEVBUFSIZE ];
+static int NetDevCnt = 0;
+static int Dirty = 0;
+static int NetDevOk = 0;
+static long OldHash = 0;
+
+#define MAXNETDEVS 64
+static NetDevInfo NetDevs[ MAXNETDEVS ];
+
+void processNetDev( void );
+
+FORALL( DECLAREFUNC )
+
+static int processNetDev_( void )
+{
+ int i;
+ char format[ 32 ];
+ char devFormat[ 16 ];
+ char buf[ 1024 ];
+ char tag[ 64 ];
+ char* netDevBufP = NetDevBuf;
+
+ sprintf( format, "%%%d[^\n]\n", (int)sizeof( buf ) - 1 );
+ sprintf( devFormat, "%%%ds", (int)sizeof( tag ) - 1 );
+
+ /* skip 2 first lines */
+ for ( i = 0; i < 2; i++ ) {
+ sscanf( netDevBufP, format, buf );
+ buf[ sizeof( buf ) - 1 ] = '\0';
+ netDevBufP += strlen( buf ) + 1; /* move netDevBufP to next line */
+ }
+
+ for ( i = 0; sscanf( netDevBufP, format, buf ) == 1; ++i ) {
+ buf[ sizeof( buf ) - 1 ] = '\0';
+ netDevBufP += strlen( buf ) + 1; /* move netDevBufP to next line */
+
+ if ( sscanf( buf, devFormat, tag ) ) {
+ char* pos = strchr( tag, ':' );
+ if ( pos ) {
+ FORALL( DEFVARS );
+ *pos = '\0';
+ FORALL( SETZERO );
+ sscanf( buf + 7, "%llu %llu %llu %llu %llu %llu %llu %llu "
+ "%llu %llu %llu %llu %llu %llu %llu %llu",
+ &recBytes, &recPacks, &recErrs, &recDrop, &recFifo,
+ &recFrame, &recCompressed, &recMulticast,
+ &sentBytes, &sentPacks, &sentErrs, &sentDrop,
+ &sentFifo, &sentColls, &sentCarrier, &sentCompressed );
+
+ if ( i >= NetDevCnt || strcmp( NetDevs[ i ].name, tag ) != 0 ) {
+ /* The network device configuration has changed. We
+ * need to reconfigure the netdev module. */
+ return -1;
+ } else {
+ FORALL( CALC );
+ }
+ }
+ }
+ }
+
+ if ( i != NetDevCnt )
+ return -1;
+
+ /* save exact time inverval between this and the last read of
+ * /proc/net/dev */
+ timeInterval = currSampling.tv_sec - lastSampling.tv_sec +
+ ( currSampling.tv_usec - lastSampling.tv_usec ) / 1000000.0;
+ lastSampling = currSampling;
+ Dirty = 0;
+
+ return 0;
+}
+
+void processNetDev( void )
+{
+ int i;
+
+ if ( NetDevCnt == 0 )
+ return;
+
+ for ( i = 0; i < 5 && processNetDev_() < 0; ++i )
+ checkNetDev();
+
+ /* If 5 reconfiguration attemts failed, something is very wrong and
+ * we close the netdev module for further use. */
+ if ( i == 5 )
+ exitNetDev();
+}
+
+/*
+================================ public part =================================
+*/
+
+void initNetDev( struct SensorModul* sm )
+{
+ int i;
+ char format[ 32 ];
+ char devFormat[ 16 ];
+ char buf[ 1024 ];
+ char tag[ 64 ];
+ char* netDevBufP = NetDevBuf;
+
+ NetDevSM = sm;
+
+ if ( updateNetDev() < 0 )
+ return;
+
+ sprintf( format, "%%%d[^\n]\n", (int)sizeof( buf ) - 1 );
+ sprintf( devFormat, "%%%ds", (int)sizeof( tag ) - 1 );
+
+ /* skip 2 first lines */
+ for ( i = 0; i < 2; i++ ) {
+ sscanf( netDevBufP, format, buf );
+ buf[ sizeof( buf ) - 1 ] = '\0';
+ netDevBufP += strlen( buf ) + 1; /* move netDevBufP to next line */
+ }
+
+ for ( i = 0; sscanf( netDevBufP, format, buf ) == 1; ++i ) {
+ buf[ sizeof( buf ) - 1 ] = '\0';
+ netDevBufP += strlen( buf ) + 1; /* move netDevBufP to next line */
+
+ if ( sscanf( buf, devFormat, tag ) ) {
+ char* pos = strchr( tag, ':' );
+ if ( pos ) {
+ char mon[ MON_SIZE ];
+ *pos = '\0';
+ strlcpy( NetDevs[ i ].name, tag, sizeof( NetDevs[ i ].name ) );
+ FORALL( REGISTERSENSOR );
+ sscanf( pos + 1, "%llu %llu %llu %llu %llu %llu %llu %llu"
+ "%llu %llu %llu %llu %llu %llu %llu %llu",
+ &NetDevs[ i ].recBytes, &NetDevs[ i ].recPacks,
+ &NetDevs[ i ].recErrs, &NetDevs[ i ].recDrop,
+ &NetDevs[ i ].recFifo, &NetDevs[ i ].recFrame,
+ &NetDevs[ i ].recCompressed, &NetDevs[ i ].recMulticast,
+ &NetDevs[ i ].sentBytes, &NetDevs[ i ].sentPacks,
+ &NetDevs[ i ].sentErrs, &NetDevs[ i ].sentDrop,
+ &NetDevs[ i ].sentFifo, &NetDevs[ i ].sentColls,
+ &NetDevs[ i ].sentCarrier, &NetDevs[ i ].sentCompressed );
+ NetDevCnt++;
+ }
+ FORALL( SETMEMBERZERO );
+ }
+ }
+
+ /* Call processNetDev to elimitate initial peek values. */
+ processNetDev();
+}
+
+void exitNetDev( void )
+{
+ int i;
+
+ for ( i = 0; i < NetDevCnt; ++i ) {
+ char mon[ MON_SIZE ];
+ FORALL( UNREGISTERSENSOR );
+ }
+ NetDevCnt = 0;
+}
+
+int updateNetDev( void )
+{
+ /* We read the information about the network interfaces from
+ /proc/net/dev. The file should look like this:
+
+ Inter-| Receive | Transmit
+ face | bytes packets errs drop fifo frame compressed multicast| bytes packets errs drop fifo colls carrier compressed
+ lo:275135772 1437448 0 0 0 0 0 0 275135772 1437448 0 0 0 0 0 0
+ eth0:123648812 655251 0 0 0 0 0 0 246847871 889636 0 0 0 0 0 0 Inter-| Receive | Transmit
+ face | bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
+ lo:275135772 1437448 0 0 0 0 0 0 275135772 1437448 0 0 0 0 0 0
+ eth0:123648812 655251 0 0 0 0 0 0 246847871 889636 0 0 0 0 0 0
+ */
+
+ size_t n;
+ int fd;
+ long hash;
+ char* p;
+
+ if ( NetDevOk < 0 )
+ return 0;
+
+ if ( ( fd = open( "/proc/net/dev", O_RDONLY ) ) < 0 ) {
+ /* /proc/net/dev may not exist on some machines. */
+ NetDevOk = -1;
+ return 0;
+ }
+
+ if ( ( n = read( fd, NetDevBuf, NETDEVBUFSIZE - 1 ) ) == NETDEVBUFSIZE - 1 ) {
+ log_error( "Internal buffer too small to read \'/proc/net/dev\'" );
+ NetDevOk = -1;
+
+ close( fd );
+ return -1;
+ }
+
+ gettimeofday( &currSampling, 0 );
+ close( fd );
+ NetDevOk = 1;
+ NetDevBuf[ n ] = '\0';
+
+ /* Calculate hash over the first 7 characters of each line starting
+ * after the first newline. */
+ for ( p = NetDevBuf, hash = 0; *p; ++p )
+ if ( *p == '\n' )
+ for ( ++p; *p && *p != ':' && *p != '|'; ++p )
+ hash = ( ( hash << 6 ) + *p ) % 390389;
+
+ if ( OldHash != 0 && OldHash != hash ) {
+ print_error( "RECONFIGURE\n" );
+ CheckSetupFlag = 1;
+ }
+ OldHash = hash;
+
+ Dirty = 1;
+
+ return 0;
+}
+
+void checkNetDev( void )
+{
+ /* Values for other network devices are lost, but it is still better
+ * than not detecting any new devices. TODO: Fix after 2.1 is out. */
+ exitNetDev();
+ initNetDev( NetDevSM );
+}
+
+#define PRINTFUNC( a, b, c, d, e ) \
+void printNetDev##a( const char* cmd ) \
+{ \
+ int i; \
+ char* beg; \
+ char* end; \
+ char dev[ 64 ]; \
+ \
+ beg = strchr( cmd, '/' ); \
+ beg = strchr( beg + 1, '/' ); \
+ end = strchr( beg + 1, '/' ); \
+ strncpy( dev, beg + 1, end - beg - 1 ); \
+ dev[ end - beg - 1 ] = '\0'; \
+ \
+ if ( Dirty ) \
+ processNetDev(); \
+ \
+ for ( i = 0; i < MAXNETDEVS; ++i ) \
+ if ( strcmp( NetDevs[ i ].name, dev ) == 0) { \
+ fprintf( CurrentClient, "%lu\n", (unsigned long) \
+ ( NetDevs[ i ].a / ( NetDevs[ i ].a##Scale * timeInterval ) ) ); \
+ return; \
+ } \
+ \
+ fprintf( CurrentClient, "0\n" ); \
+} \
+ \
+void printNetDev##a##Info( const char* cmd ) \
+{ \
+ (void)cmd; \
+ fprintf( CurrentClient, "%s\t0\t0\t%s\n", c, d ); \
+}
+
+FORALL( PRINTFUNC )
diff --git a/ksysguard/ksysguardd/Linux/netdev.h b/ksysguard/ksysguardd/Linux/netdev.h
new file mode 100644
index 000000000..d470adfae
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/netdev.h
@@ -0,0 +1,35 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999, 2000 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KSG_NETDEV_H
+#define KSG_NETDEV_H
+
+void initNetDev( struct SensorModul* );
+void exitNetDev( void );
+
+int updateNetDev( void );
+void checkNetDev( void );
+
+void printNetDevRecBytes( const char* );
+void printNetDevRecBytesInfo( const char* );
+void printNetDevSentBytes( const char* );
+void printNetDevSentBytesInfo( const char* );
+
+#endif
diff --git a/ksysguard/ksysguardd/Linux/netstat.c b/ksysguard/ksysguardd/Linux/netstat.c
new file mode 100644
index 000000000..c8570f617
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/netstat.c
@@ -0,0 +1,495 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <config.h>
+
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "ksysguardd.h"
+#include "Command.h"
+#include "ccont.h"
+#include "netstat.h"
+
+static CONTAINER TcpSocketList = 0;
+static CONTAINER UdpSocketList = 0;
+static CONTAINER UnixSocketList = 0;
+static CONTAINER RawSocketList = 0;
+
+static int num_tcp = 0;
+static int num_udp = 0;
+static int num_unix = 0;
+static int num_raw = 0;
+
+typedef struct {
+ char local_addr[128];
+ char local_port[128];
+ char remote_addr[128];
+ char remote_port[128];
+ char state[128];
+ int uid;
+} SocketInfo;
+
+typedef struct {
+ int refcount;
+ char type[128];
+ char state[128];
+ int inode;
+ char path[256];
+} UnixInfo;
+
+char *get_serv_name(int port, const char *proto);
+char *get_host_name(int addr);
+char *get_proto_name(int number);
+int get_num_sockets(FILE *netstat);
+void printSocketInfo(SocketInfo* socket_info);
+
+static time_t TcpUdpRaw_timeStamp = 0;
+static time_t Unix_timeStamp = 0;
+static time_t NetStat_timeStamp = 0;
+
+static const char *raw_type[] =
+{
+ "",
+ "stream",
+ "dgram",
+ "raw",
+ "rdm",
+ "seqpacket",
+ "packet"
+};
+
+static const char *raw_state[] =
+{
+ "free",
+ "unconnected",
+ "connecting",
+ "connected",
+ "disconnecting"
+};
+
+static const char *conn_state[] =
+{
+ "",
+ "established",
+ "syn_sent",
+ "syn_recv",
+ "fin_wait1",
+ "fin_wait2",
+ "time_wait",
+ "close",
+ "close_wait",
+ "last_ack",
+ "listen",
+ "closing"
+};
+
+char *get_serv_name(int port, const char *proto)
+{
+ static char buffer[1024];
+ struct servent *service;
+
+ if (port == 0) {
+ return (char *)"*";
+ }
+
+ memset(buffer, 0, sizeof(buffer));
+
+ if ((service = getservbyport(ntohs(port), proto)) == NULL) {
+ snprintf(buffer, sizeof(buffer), "%d", port);
+ } else {
+ strlcpy(buffer, service->s_name, sizeof(buffer));
+ }
+
+ return (char *)buffer;
+}
+
+char *get_host_name(int addr)
+{
+ static char buffer[1024];
+ struct hostent *host;
+ struct in_addr a_addr;
+
+ if (addr == 0) {
+ return (char *)"*";
+ }
+
+ memset(buffer, 0, sizeof(buffer));
+
+ if ((host = gethostbyaddr((char *)&addr, 4, AF_INET)) == NULL) {
+ a_addr.s_addr = addr;
+ return inet_ntoa(a_addr);
+ } else {
+ strlcpy(buffer, host->h_name, sizeof(buffer));
+ return (char *)buffer;
+ }
+}
+
+char *get_proto_name(int number)
+{
+ static char buffer[1024];
+ struct protoent *protocol;
+
+ if (number == 0) {
+ return (char *)"*";
+ }
+
+ memset(buffer, 0, sizeof(buffer));
+
+ if ((protocol = getprotobynumber(number)) == NULL) {
+ snprintf(buffer, sizeof(buffer), "%d", number);
+ } else {
+ strlcpy(buffer, protocol->p_name, sizeof(buffer));
+ }
+
+ return (char *)buffer;
+}
+
+int get_num_sockets(FILE *netstat)
+{
+ char line[1024];
+ int line_count = 0;
+
+ while (fgets(line, 1024, netstat) != NULL)
+ line_count++;
+
+ return line_count - 1;
+}
+
+void printSocketInfo(SocketInfo* socket_info)
+{
+ fprintf(CurrentClient, "%s\t%s\t%s\t%s\t%s\t%d\n",
+ socket_info->local_addr,
+ socket_info->local_port,
+ socket_info->remote_addr,
+ socket_info->remote_port,
+ socket_info->state,
+ socket_info->uid);
+}
+
+/*
+================================ public part =================================
+*/
+
+void
+initNetStat(struct SensorModul* sm)
+{
+ FILE *netstat;
+
+ if ((netstat = fopen("/proc/net/tcp", "r")) != NULL) {
+ registerMonitor("network/sockets/tcp/count", "integer", printNetStat, printNetStatInfo, sm);
+ registerMonitor("network/sockets/tcp/list", "listview", printNetStatTcpUdpRaw, printNetStatTcpUdpRawInfo, sm);
+ fclose(netstat);
+ }
+ if ((netstat = fopen("/proc/net/udp", "r")) != NULL) {
+ registerMonitor("network/sockets/udp/count", "integer", printNetStat, printNetStatInfo, sm);
+ registerMonitor("network/sockets/udp/list", "listview", printNetStatTcpUdpRaw, printNetStatTcpUdpRawInfo, sm);
+ fclose(netstat);
+ }
+ if ((netstat = fopen("/proc/net/unix", "r")) != NULL) {
+ registerMonitor("network/sockets/unix/count", "integer", printNetStat, printNetStatInfo, sm);
+ registerMonitor("network/sockets/unix/list", "listview", printNetStatUnix, printNetStatUnixInfo, sm);
+ fclose(netstat);
+ }
+ if ((netstat = fopen("/proc/net/raw", "r")) != NULL) {
+ registerMonitor("network/sockets/raw/count", "integer", printNetStat, printNetStatInfo, sm);
+ registerMonitor("network/sockets/raw/list", "listview", printNetStatTcpUdpRaw, printNetStatTcpUdpRawInfo, sm);
+ fclose(netstat);
+ }
+
+ TcpSocketList = new_ctnr();
+ UdpSocketList = new_ctnr();
+ RawSocketList = new_ctnr();
+ UnixSocketList = new_ctnr();
+}
+
+void
+exitNetStat(void)
+{
+ destr_ctnr(TcpSocketList, free);
+ destr_ctnr(UdpSocketList, free);
+ destr_ctnr(RawSocketList, free);
+ destr_ctnr(UnixSocketList, free);
+}
+
+int
+updateNetStat(void)
+{
+ FILE *netstat;
+
+ if ((netstat = fopen("/proc/net/tcp", "r")) != NULL) {
+ num_tcp = get_num_sockets(netstat);
+ fclose(netstat);
+ }
+
+ if ((netstat = fopen("/proc/net/udp", "r")) != NULL) {
+ num_udp = get_num_sockets(netstat);
+ fclose(netstat);
+ }
+
+ if ((netstat = fopen("/proc/net/unix", "r")) != NULL) {
+ num_unix = get_num_sockets(netstat);
+ fclose(netstat);
+ }
+ if ((netstat = fopen("/proc/net/raw", "r")) != NULL) {
+ num_raw = get_num_sockets(netstat);
+ fclose(netstat);
+ }
+
+ NetStat_timeStamp = time(0);
+ return 0;
+}
+
+int
+updateNetStatTcpUdpRaw(const char *cmd)
+{
+ FILE *netstat;
+ char buffer[1024];
+ uint local_addr, local_port;
+ uint remote_addr, remote_port;
+ int uid, i;
+ uint state;
+ SocketInfo *socket_info;
+
+ if (strstr(cmd, "tcp")) {
+ snprintf(buffer, sizeof(buffer), "/proc/net/tcp");
+ for (i = level_ctnr(TcpSocketList); i >= 0; --i)
+ free(pop_ctnr(TcpSocketList));
+ }
+
+ if (strstr(cmd, "udp")) {
+ snprintf(buffer, sizeof(buffer), "/proc/net/udp");
+ for (i = level_ctnr(UdpSocketList); i >= 0; --i)
+ free(pop_ctnr(UdpSocketList));
+ }
+
+ if (strstr(cmd, "raw")) {
+ snprintf(buffer, sizeof(buffer), "/proc/net/raw");
+ for (i = level_ctnr(RawSocketList); i >= 0; --i)
+ free(pop_ctnr(RawSocketList));
+ }
+
+ if ((netstat = fopen(buffer, "r")) == NULL) {
+ print_error("Cannot open \'%s\'!\n"
+ "The kernel needs to be compiled with support\n"
+ "for /proc filesystem enabled!\n", buffer);
+ return -1;
+ }
+
+ fgets(buffer, sizeof(buffer), netstat);
+
+ while (fgets(buffer, sizeof(buffer), netstat) != NULL) {
+ if (strcmp(buffer, "")) {
+ sscanf(buffer, "%*d: %x:%x %x:%x %x %*x:%*x %*x:%*x %d",
+ &local_addr, &local_port,
+ &remote_addr, &remote_port,
+ &state,
+ &uid);
+
+ if ((socket_info = (SocketInfo *)malloc(sizeof(SocketInfo))) == NULL) {
+ continue;
+ }
+ strlcpy(socket_info->local_addr, get_host_name(local_addr), sizeof(socket_info->local_addr));
+ strlcpy(socket_info->remote_addr, get_host_name(remote_addr), sizeof(socket_info->remote_addr));
+
+ if (strstr(cmd, "tcp")) {
+ strlcpy(socket_info->local_port, get_serv_name(local_port, "tcp"), sizeof(socket_info->local_port));
+ strlcpy(socket_info->remote_port, get_serv_name(remote_port, "tcp"), sizeof(socket_info->remote_port));
+ strlcpy(socket_info->state, conn_state[state], sizeof(socket_info->state));
+ socket_info->uid = uid;
+
+ push_ctnr(TcpSocketList, socket_info);
+ }
+
+ if (strstr(cmd, "udp")) {
+ strlcpy(socket_info->local_port, get_serv_name(local_port, "udp"), sizeof(socket_info->local_port));
+ strlcpy(socket_info->remote_port, get_serv_name(remote_port, "udp"), sizeof(socket_info->remote_port));
+ strlcpy(socket_info->state, conn_state[state], sizeof(socket_info->state));
+ socket_info->uid = uid;
+
+ push_ctnr(UdpSocketList, socket_info);
+ }
+
+ if (strstr(cmd, "raw")) {
+ strlcpy(socket_info->local_port, get_proto_name(local_port), sizeof(socket_info->local_port));
+ strlcpy(socket_info->remote_port, get_proto_name(remote_port), sizeof(socket_info->remote_port));
+ snprintf(socket_info->state, sizeof(socket_info->state)-1, "%d", state);
+ socket_info->uid = uid;
+
+ push_ctnr(RawSocketList, socket_info);
+ }
+ }
+ }
+ fclose(netstat);
+ TcpUdpRaw_timeStamp = time(0);
+
+ return 0;
+}
+
+int
+updateNetStatUnix(void)
+{
+ FILE *file;
+ char buffer[1024];
+ char path[256];
+ int ref_count, type, state, inode, i;
+ UnixInfo *unix_info;
+
+ if ((file = fopen("/proc/net/unix", "r")) == NULL) {
+ print_error("Cannot open \'/proc/net/unix\'!\n"
+ "The kernel needs to be compiled with support\n"
+ "for /proc filesystem enabled!\n");
+ return -1;
+ }
+
+ for (i = level_ctnr(UnixSocketList); i >= 0; --i)
+ free(pop_ctnr(UnixSocketList));
+
+ fgets(buffer, sizeof(buffer), file);
+
+ while (fgets(buffer, sizeof(buffer), file) != NULL) {
+ if (strcmp(buffer, "")) {
+ sscanf(buffer, "%*x: %d %*d %*d %d %d %d %255s",
+ &ref_count, &type, &state, &inode, path);
+
+ if ((unix_info = (UnixInfo *)malloc(sizeof(UnixInfo))) == NULL) {
+ continue;
+ }
+
+ unix_info->refcount = ref_count;
+ strlcpy(unix_info->type, raw_type[type], sizeof(unix_info->type));
+ strlcpy(unix_info->state, raw_state[state], sizeof(unix_info->state));
+ unix_info->inode = inode;
+ strlcpy(unix_info->path, path, sizeof(unix_info->path));
+
+ push_ctnr(UnixSocketList, unix_info);
+ }
+ }
+ fclose(file);
+ Unix_timeStamp = time(0);
+
+ return 0;
+}
+
+void
+printNetStat(const char* cmd)
+{
+ if ((time(0) - NetStat_timeStamp) >= UPDATEINTERVAL)
+ updateNetStat();
+
+ if (strstr(cmd, "tcp") != NULL)
+ fprintf(CurrentClient, "%d\n", num_tcp);
+ if (strstr(cmd, "udp") != NULL)
+ fprintf(CurrentClient, "%d\n", num_udp);
+ if (strstr(cmd, "unix") != NULL)
+ fprintf(CurrentClient, "%d\n", num_unix);
+ if (strstr(cmd, "raw") != NULL)
+ fprintf(CurrentClient, "%d\n", num_raw);
+}
+
+void
+printNetStatInfo(const char* cmd)
+{
+ if (strstr(cmd, "tcp") != NULL)
+ fprintf(CurrentClient, "Number of TCP-Sockets\t0\t0\tSockets\n");
+ if (strstr(cmd, "udp") != NULL)
+ fprintf(CurrentClient, "Number of UDP-Sockets\t0\t0\tSockets\n");
+ if (strstr(cmd, "unix") != NULL)
+ fprintf(CurrentClient, "Number of UnixDomain-Sockets\t0\t0\tSockets\n");
+ if (strstr(cmd, "raw") != NULL)
+ fprintf(CurrentClient, "Number of Raw-Sockets\t0\t0\tSockets\n");
+}
+
+void
+printNetStatTcpUdpRaw(const char *cmd)
+{
+ SocketInfo* socket_info;
+
+ if (strstr(cmd, "tcp")) {
+ if ((time(0) - TcpUdpRaw_timeStamp) >= UPDATEINTERVAL)
+ updateNetStatTcpUdpRaw("tcp");
+
+ for (socket_info = first_ctnr(TcpSocketList); socket_info; socket_info = next_ctnr(TcpSocketList))
+ printSocketInfo(socket_info);
+
+ if (level_ctnr(TcpSocketList) == 0)
+ fprintf(CurrentClient, "\n");
+ }
+
+ if (strstr(cmd, "udp")) {
+ if ((time(0) - TcpUdpRaw_timeStamp) >= UPDATEINTERVAL)
+ updateNetStatTcpUdpRaw("udp");
+
+ for (socket_info = first_ctnr(UdpSocketList); socket_info; socket_info = next_ctnr(UdpSocketList))
+ printSocketInfo(socket_info);
+
+ if (level_ctnr(UdpSocketList) == 0)
+ fprintf(CurrentClient, "\n");
+ }
+
+ if (strstr(cmd, "raw")) {
+ if ((time(0) - TcpUdpRaw_timeStamp) >= UPDATEINTERVAL)
+ updateNetStatTcpUdpRaw("raw");
+
+ for (socket_info = first_ctnr(RawSocketList); socket_info; socket_info = next_ctnr(RawSocketList))
+ printSocketInfo(socket_info);
+
+ if (level_ctnr(RawSocketList) == 0)
+ fprintf(CurrentClient, "\n");
+ }
+}
+
+void
+printNetStatTcpUdpRawInfo(const char *cmd)
+{
+ (void) cmd;
+ fprintf(CurrentClient, "Local Address\tPort\tForeign Address\tPort\tState\tUID\ns\ts\ts\ts\ts\td\n");
+}
+
+void printNetStatUnix(const char *cmd)
+{
+ UnixInfo* unix_info;
+
+ (void) cmd;
+ if ((time(0) - Unix_timeStamp) >= UPDATEINTERVAL)
+ updateNetStatUnix();
+
+ for (unix_info = first_ctnr(UnixSocketList); unix_info; unix_info = next_ctnr(UnixSocketList)) {
+ fprintf(CurrentClient, "%d\t%s\t%s\t%d\t%s\n",
+ unix_info->refcount,
+ unix_info->type,
+ unix_info->state,
+ unix_info->inode,
+ unix_info->path);
+ }
+
+ if (level_ctnr(UnixSocketList) == 0)
+ fprintf(CurrentClient, "\n");
+}
+
+void printNetStatUnixInfo(const char *cmd)
+{
+ (void) cmd;
+ fprintf(CurrentClient, "RefCount\tType\tState\tInode\tPath\nd\ts\ts\td\ts\n");
+}
diff --git a/ksysguard/ksysguardd/Linux/netstat.h b/ksysguard/ksysguardd/Linux/netstat.h
new file mode 100644
index 000000000..be0c3a850
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/netstat.h
@@ -0,0 +1,39 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _netstat_h_
+#define _netstat_h_
+
+void initNetStat(struct SensorModul* sm);
+void exitNetStat(void);
+
+int updateNetStat(void);
+int updateNetStatTcpUdpRaw(const char* cmd);
+int updateNetStatUnix(void);
+
+void printNetStat(const char* cmd);
+void printNetStatInfo(const char* cmd);
+
+void printNetStatTcpUdpRaw(const char *cmd);
+void printNetStatTcpUdpRawInfo(const char *cmd);
+
+void printNetStatUnix(const char *cmd);
+void printNetStatUnixInfo(const char *cmd);
+#endif
diff --git a/ksysguard/ksysguardd/Linux/stat.c b/ksysguard/ksysguardd/Linux/stat.c
new file mode 100644
index 000000000..0e03e4d53
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/stat.c
@@ -0,0 +1,1184 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999, 2000 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "Command.h"
+#include "ksysguardd.h"
+
+#include "stat.h"
+
+typedef struct
+{
+ /* A CPU can be loaded with user processes, reniced processes and
+ * system processes. Unused processing time is called idle load.
+ * These variable store the percentage of each load type. */
+ int userLoad;
+ int niceLoad;
+ int sysLoad;
+ int idleLoad;
+
+ /* To calculate the loads we need to remember the tick values for each
+ * load type. */
+ unsigned long userTicks;
+ unsigned long niceTicks;
+ unsigned long sysTicks;
+ unsigned long idleTicks;
+} CPULoadInfo;
+
+typedef struct
+{
+ unsigned long delta;
+ unsigned long old;
+} DiskLoadSample;
+
+typedef struct
+{
+ /* 5 types of samples are taken:
+ total, rio, wio, rBlk, wBlk */
+ DiskLoadSample s[ 5 ];
+} DiskLoadInfo;
+
+typedef struct DiskIOInfo
+{
+ int major;
+ int minor;
+ int alive;
+ DiskLoadSample total;
+ DiskLoadSample rio;
+ DiskLoadSample wio;
+ DiskLoadSample rblk;
+ DiskLoadSample wblk;
+ struct DiskIOInfo* next;
+} DiskIOInfo;
+
+#define STATBUFSIZE (32 * 1024)
+
+static char StatBuf[ STATBUFSIZE ];
+static char VmStatBuf[ STATBUFSIZE ];
+static char IOStatBuf[ STATBUFSIZE ]; /* Buffer for /proc/diskstats */
+static int Dirty = 0;
+
+/* We have observed deviations of up to 5% in the accuracy of the timer
+ * interrupts. So we try to measure the interrupt interval and use this
+ * value to calculate timing dependant values. */
+static float timeInterval = 0;
+static struct timeval lastSampling;
+static struct timeval currSampling;
+static struct SensorModul* StatSM;
+
+static CPULoadInfo CPULoad;
+static CPULoadInfo* SMPLoad = 0;
+static unsigned CPUCount = 0;
+static DiskLoadInfo* DiskLoad = 0;
+static unsigned DiskCount = 0;
+static DiskIOInfo* DiskIO = 0;
+static unsigned long PageIn = 0;
+static unsigned long OldPageIn = 0;
+static unsigned long PageOut = 0;
+static unsigned long OldPageOut = 0;
+static unsigned long Ctxt = 0;
+static unsigned long OldCtxt = 0;
+static unsigned int NumOfInts = 0;
+static unsigned long* OldIntr = 0;
+static unsigned long* Intr = 0;
+
+static int initStatDisk( char* tag, char* buf, const char* label, const char* shortLabel,
+ int idx, cmdExecutor ex, cmdExecutor iq );
+static void updateCPULoad( const char* line, CPULoadInfo* load );
+static int processDisk( char* tag, char* buf, const char* label, int idx );
+static void processStat( void );
+static int processDiskIO( const char* buf );
+static int process26DiskIO( const char* buf );
+static void cleanupDiskList( void );
+
+static int initStatDisk( char* tag, char* buf, const char* label,
+ const char* shortLabel, int idx, cmdExecutor ex, cmdExecutor iq )
+{
+ char sensorName[ 128 ];
+
+ gettimeofday( &lastSampling, 0 );
+
+ if ( strcmp( label, tag ) == 0 ) {
+ unsigned int i;
+ buf = buf + strlen( label ) + 1;
+
+ for ( i = 0; i < DiskCount; ++i ) {
+ sscanf( buf, "%lu", &DiskLoad[ i ].s[ idx ].old );
+ while ( *buf && isblank( *buf++ ) );
+ while ( *buf && isdigit( *buf++ ) );
+ sprintf( sensorName, "disk/disk%d/%s", i, shortLabel );
+ registerMonitor( sensorName, "integer", ex, iq, StatSM );
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static void updateCPULoad( const char* line, CPULoadInfo* load )
+{
+ unsigned long currUserTicks, currSysTicks, currNiceTicks, currIdleTicks;
+ unsigned long totalTicks;
+
+ sscanf( line, "%*s %lu %lu %lu %lu", &currUserTicks, &currNiceTicks,
+ &currSysTicks, &currIdleTicks );
+
+ totalTicks = ( currUserTicks - load->userTicks ) +
+ ( currSysTicks - load->sysTicks ) +
+ ( currNiceTicks - load->niceTicks ) +
+ ( currIdleTicks - load->idleTicks );
+
+ if ( totalTicks > 10 ) {
+ load->userLoad = ( 100 * ( currUserTicks - load->userTicks ) ) / totalTicks;
+ load->sysLoad = ( 100 * ( currSysTicks - load->sysTicks ) ) / totalTicks;
+ load->niceLoad = ( 100 * ( currNiceTicks - load->niceTicks ) ) / totalTicks;
+ load->idleLoad = ( 100 - ( load->userLoad + load->sysLoad + load->niceLoad ) );
+ } else
+ load->userLoad = load->sysLoad = load->niceLoad = load->idleLoad = 0;
+
+ load->userTicks = currUserTicks;
+ load->sysTicks = currSysTicks;
+ load->niceTicks = currNiceTicks;
+ load->idleTicks = currIdleTicks;
+}
+
+static int processDisk( char* tag, char* buf, const char* label, int idx )
+{
+ if ( strcmp( label, tag ) == 0 ) {
+ unsigned long val;
+ unsigned int i;
+ buf = buf + strlen( label ) + 1;
+
+ for ( i = 0; i < DiskCount; ++i ) {
+ sscanf( buf, "%lu", &val );
+ while ( *buf && isblank( *buf++ ) );
+ while ( *buf && isdigit( *buf++ ) );
+ DiskLoad[ i ].s[ idx ].delta = val - DiskLoad[ i ].s[ idx ].old;
+ DiskLoad[ i ].s[ idx ].old = val;
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static int processDiskIO( const char* buf )
+{
+ /* Process disk_io lines as provided by 2.4.x kernels.
+ * disk_io: (2,0):(3,3,6,0,0) (3,0):(1413012,511622,12155382,901390,26486215) */
+ int major, minor;
+ unsigned long total, rblk, rio, wblk, wio;
+ DiskIOInfo* ptr = DiskIO;
+ DiskIOInfo* last = 0;
+ char sensorName[ 128 ];
+ const char* p;
+
+ p = buf + strlen( "disk_io: " );
+ while ( p && *p ) {
+ if ( sscanf( p, "(%d,%d):(%lu,%lu,%lu,%lu,%lu)", &major, &minor,
+ &total, &rio, &rblk, &wio, &wblk ) != 7 )
+ return -1;
+
+ last = 0;
+ ptr = DiskIO;
+ while ( ptr ) {
+ if ( ptr->major == major && ptr->minor == minor ) {
+ /* The IO device has already been registered. */
+ ptr->total.delta = total - ptr->total.old;
+ ptr->total.old = total;
+ ptr->rio.delta = rio - ptr->rio.old;
+ ptr->rio.old = rio;
+ ptr->wio.delta = wio - ptr->wio.old;
+ ptr->wio.old = wio;
+ ptr->rblk.delta = rblk - ptr->rblk.old;
+ ptr->rblk.old = rblk;
+ ptr->wblk.delta = wblk - ptr->wblk.old;
+ ptr->wblk.old = wblk;
+ ptr->alive = 1;
+ break;
+ }
+ last = ptr;
+ ptr = ptr->next;
+ }
+
+ if ( !ptr ) {
+ /* The IO device has not been registered yet. We need to add it. */
+ ptr = (DiskIOInfo*)malloc( sizeof( DiskIOInfo ) );
+ ptr->major = major;
+ ptr->minor = minor;
+ ptr->total.delta = 0;
+ ptr->total.old = total;
+ ptr->rio.delta = 0;
+ ptr->rio.old = rio;
+ ptr->wio.delta = 0;
+ ptr->wio.old = wio;
+ ptr->rblk.delta = 0;
+ ptr->rblk.old = rblk;
+ ptr->wblk.delta = 0;
+ ptr->wblk.old = wblk;
+ ptr->alive = 1;
+ ptr->next = 0;
+ if ( last ) {
+ /* Append new entry at end of list. */
+ last->next = ptr;
+ } else {
+ /* List is empty, so we insert the fist element into the list. */
+ DiskIO = ptr;
+ }
+
+ sprintf( sensorName, "disk/%d:%d/total", major, minor );
+ registerMonitor( sensorName, "integer", printDiskIO, printDiskIOInfo, StatSM );
+ sprintf( sensorName, "disk/%d:%d/rio", major, minor );
+ registerMonitor( sensorName, "integer", printDiskIO, printDiskIOInfo, StatSM );
+ sprintf( sensorName, "disk/%d:%d/wio", major, minor );
+ registerMonitor( sensorName, "integer", printDiskIO, printDiskIOInfo, StatSM );
+ sprintf( sensorName, "disk/%d:%d/rblk", major, minor );
+ registerMonitor( sensorName, "integer", printDiskIO, printDiskIOInfo, StatSM );
+ sprintf( sensorName, "disk/%d:%d/wblk", major, minor );
+ registerMonitor( sensorName, "integer", printDiskIO, printDiskIOInfo, StatSM );
+ }
+ /* Move p after the sencond ')'. We can safely assume that
+ * those two ')' exist. */
+ p = strchr( p, ')' ) + 1;
+ p = strchr( p, ')' ) + 1;
+ if ( p && *p )
+ p = strchr( p, '(' );
+ }
+
+ return 0;
+}
+
+static int process26DiskIO( const char* buf )
+{
+ /* Process values from /proc/diskstats (Linux >= 2.6.x) */
+
+ /* For each disk /proc/diskstats includes lines as follows:
+ * 3 0 hda 1314558 74053 26451438 14776742 1971172 4607401 52658448 202855090 0 9597019 217637839
+ * 3 1 hda1 178 360 0 0
+ * 3 2 hda2 354 360 0 0
+ * 3 3 hda3 354 360 0 0
+ * 3 4 hda4 0 0 0 0
+ * 3 5 hda5 529506 9616000 4745856 37966848
+ *
+ * - See Documentation/iostats.txt for details on the changes
+ */
+ int major, minor;
+ char devname[16];
+ unsigned long total,
+ rio, rmrg, rblk, rtim,
+ wio, wmrg, wblk, wtim,
+ ioprog, iotim, iotimw;
+ DiskIOInfo *ptr = DiskIO;
+ DiskIOInfo *last = 0;
+ char sensorName[128];
+
+ switch (sscanf(buf, "%d %d %s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
+ &major, &minor, devname,
+ &rio, &rmrg, &rblk, &rtim,
+ &wio, &wmrg, &wblk, &wtim,
+ &ioprog, &iotim, &iotimw))
+ {
+ case 7:
+ /* Partition stats entry */
+ /* Adjust read fields rio rmrg rblk rtim -> rio rblk wio wblk */
+ wblk = rtim;
+ wio = rblk;
+ rblk = rmrg;
+
+ total = rio + wio;
+
+ break;
+ case 14:
+ /* Disk stats entry */
+ total = rio + wio;
+
+ break;
+ default:
+ /* Something unexepected */
+ return -1;
+ }
+
+ last = 0;
+ ptr = DiskIO;
+ while (ptr)
+ {
+ if (ptr->major == major && ptr->minor == minor)
+ {
+ /* The IO device has already been registered. */
+ ptr->total.delta = total - ptr->total.old;
+ ptr->total.old = total;
+ ptr->rio.delta = rio - ptr->rio.old;
+ ptr->rio.old = rio;
+ ptr->wio.delta = wio - ptr->wio.old;
+ ptr->wio.old = wio;
+ ptr->rblk.delta = rblk - ptr->rblk.old;
+ ptr->rblk.old = rblk;
+ ptr->wblk.delta = wblk - ptr->wblk.old;
+ ptr->wblk.old = wblk;
+ ptr->alive = 1;
+ break;
+ }
+
+ last = ptr;
+ ptr = ptr->next;
+ }
+
+ if (!ptr)
+ {
+ /* The IO device has not been registered yet. We need to add it. */
+ ptr = (DiskIOInfo*)malloc( sizeof( DiskIOInfo ) );
+ ptr->major = major;
+ ptr->minor = minor;
+ ptr->total.delta = 0;
+ ptr->total.old = total;
+ ptr->rio.delta = 0;
+ ptr->rio.old = rio;
+ ptr->wio.delta = 0;
+ ptr->wio.old = wio;
+ ptr->rblk.delta = 0;
+ ptr->rblk.old = rblk;
+ ptr->wblk.delta = 0;
+ ptr->wblk.old = wblk;
+ ptr->alive = 1;
+ ptr->next = 0;
+ if (last)
+ {
+ /* Append new entry at end of list. */
+ last->next = ptr;
+ }
+ else
+ {
+ /* List is empty, so we insert the fist element into the list. */
+ DiskIO = ptr;
+ }
+
+ sprintf(sensorName, "disk/%d:%d/total", major, minor);
+ registerMonitor(sensorName, "integer", printDiskIO, printDiskIOInfo,
+ StatSM);
+ sprintf(sensorName, "disk/%d:%d/rio", major, minor);
+ registerMonitor(sensorName, "integer", printDiskIO, printDiskIOInfo,
+ StatSM);
+ sprintf(sensorName, "disk/%d:%d/wio", major, minor);
+ registerMonitor(sensorName, "integer", printDiskIO, printDiskIOInfo,
+ StatSM);
+ sprintf(sensorName, "disk/%d:%d/rblk", major, minor);
+ registerMonitor(sensorName, "integer", printDiskIO, printDiskIOInfo,
+ StatSM);
+ sprintf(sensorName, "disk/%d:%d/wblk", major, minor);
+ registerMonitor(sensorName, "integer", printDiskIO, printDiskIOInfo,
+ StatSM);
+ }
+
+ return 0;
+}
+
+static void cleanupDiskList( void )
+{
+ DiskIOInfo* ptr = DiskIO;
+ DiskIOInfo* last = 0;
+
+ while ( ptr ) {
+ if ( ptr->alive == 0 ) {
+ DiskIOInfo* newPtr;
+ char sensorName[ 128 ];
+
+ /* Disk device has disappeared. We have to remove it from
+ * the list and unregister the monitors. */
+ sprintf( sensorName, "disk/%d:%d/total", ptr->major, ptr->minor );
+ removeMonitor( sensorName );
+ sprintf( sensorName, "disk/%d:%d/rio", ptr->major, ptr->minor );
+ removeMonitor( sensorName );
+ sprintf( sensorName, "disk/%d:%d/wio", ptr->major, ptr->minor );
+ removeMonitor( sensorName );
+ sprintf( sensorName, "disk/%d:%d/rblk", ptr->major, ptr->minor );
+ removeMonitor( sensorName );
+ sprintf( sensorName, "disk/%d:%d/wblk", ptr->major, ptr->minor );
+ removeMonitor( sensorName );
+ if ( last ) {
+ last->next = ptr->next;
+ newPtr = ptr->next;
+ } else {
+ DiskIO = ptr->next;
+ newPtr = DiskIO;
+ last = 0;
+ }
+
+ free ( ptr );
+ ptr = newPtr;
+ } else {
+ ptr->alive = 0;
+ last = ptr;
+ ptr = ptr->next;
+ }
+ }
+}
+
+static void processStat( void )
+{
+ char format[ 32 ];
+ char tagFormat[ 16 ];
+ char buf[ 1024 ];
+ char tag[ 32 ];
+ char* statBufP = StatBuf;
+ char* vmstatBufP = VmStatBuf;
+ char* iostatBufP = IOStatBuf;
+
+ sprintf( format, "%%%d[^\n]\n", (int)sizeof( buf ) - 1 );
+ sprintf( tagFormat, "%%%ds", (int)sizeof( tag ) - 1 );
+
+ while ( sscanf( statBufP, format, buf ) == 1 ) {
+ buf[ sizeof( buf ) - 1 ] = '\0';
+ statBufP += strlen( buf ) + 1; /* move statBufP to next line */
+ sscanf( buf, tagFormat, tag );
+
+ if ( strcmp( "cpu", tag ) == 0 ) {
+ /* Total CPU load */
+ updateCPULoad( buf, &CPULoad );
+ } else if ( strncmp( "cpu", tag, 3 ) == 0 ) {
+ /* Load for each SMP CPU */
+ int id;
+ sscanf( tag + 3, "%d", &id );
+ updateCPULoad( buf, &SMPLoad[ id ] );
+ } else if ( processDisk( tag, buf, "disk", 0 ) ) {
+ } else if ( processDisk( tag, buf, "disk_rio", 1 ) ) {
+ } else if ( processDisk( tag, buf, "disk_wio", 2 ) ) {
+ } else if ( processDisk( tag, buf, "disk_rblk", 3 ) ) {
+ } else if ( processDisk( tag, buf, "disk_wblk", 4 ) ) {
+ } else if ( strcmp( "disk_io:", tag ) == 0 ) {
+ processDiskIO( buf );
+ } else if ( strcmp( "page", tag ) == 0 ) {
+ unsigned long v1, v2;
+ sscanf( buf + 5, "%lu %lu", &v1, &v2 );
+ PageIn = v1 - OldPageIn;
+ OldPageIn = v1;
+ PageOut = v2 - OldPageOut;
+ OldPageOut = v2;
+ } else if ( strcmp( "intr", tag ) == 0 ) {
+ unsigned int i = 0;
+ char* p = buf + 5;
+
+ for ( i = 0; i < NumOfInts; i++ ) {
+ unsigned long val;
+
+ sscanf( p, "%lu", &val );
+ Intr[ i ] = val - OldIntr[ i ];
+ OldIntr[ i ] = val;
+ while ( *p && *p != ' ' )
+ p++;
+ while ( *p && *p == ' ' )
+ p++;
+ }
+ } else if ( strcmp( "ctxt", tag ) == 0 ) {
+ unsigned long val;
+
+ sscanf( buf + 5, "%lu", &val );
+ Ctxt = val - OldCtxt;
+ OldCtxt = val;
+ }
+ }
+
+ /* Read Linux 2.5.x /proc/vmstat */
+ while ( sscanf( vmstatBufP, format, buf ) == 1 ) {
+ buf[ sizeof( buf ) - 1 ] = '\0';
+ vmstatBufP += strlen( buf ) + 1; /* move vmstatBufP to next line */
+ sscanf( buf, tagFormat, tag );
+
+ if ( strcmp( "pgpgin", tag ) == 0 ) {
+ unsigned long v1;
+ sscanf( buf + 7, "%lu", &v1 );
+ PageIn = v1 - OldPageIn;
+ OldPageIn = v1;
+ } else if ( strcmp( "pgpgout", tag ) == 0 ) {
+ unsigned long v1;
+ sscanf( buf + 7, "%lu", &v1 );
+ PageOut = v1 - OldPageOut;
+ OldPageOut = v1;
+ }
+ }
+
+ /* Process values from /proc/diskstats (Linux >= 2.6.x) */
+ while (sscanf(iostatBufP, format, buf) == 1)
+ {
+ buf[sizeof(buf) - 1] = '\0';
+ iostatBufP += strlen(buf) + 1; /* move IOstatBufP to next line */
+
+ process26DiskIO(buf);
+ }
+
+ /* save exact time inverval between this and the last read of /proc/stat */
+ timeInterval = currSampling.tv_sec - lastSampling.tv_sec +
+ ( currSampling.tv_usec - lastSampling.tv_usec ) / 1000000.0;
+ lastSampling = currSampling;
+
+ cleanupDiskList();
+
+ Dirty = 0;
+}
+
+/*
+================================ public part =================================
+*/
+
+void initStat( struct SensorModul* sm )
+{
+ /* The CPU load is calculated from the values in /proc/stat. The cpu
+ * entry contains 4 counters. These counters count the number of ticks
+ * the system has spend on user processes, system processes, nice
+ * processes and idle time.
+ *
+ * SMP systems will have cpu1 to cpuN lines right after the cpu info. The
+ * format is identical to cpu and reports the information for each cpu.
+ * Linux kernels <= 2.0 do not provide this information!
+ *
+ * The /proc/stat file looks like this:
+ *
+ * cpu 1586 4 808 36274
+ * disk 7797 0 0 0
+ * disk_rio 6889 0 0 0
+ * disk_wio 908 0 0 0
+ * disk_rblk 13775 0 0 0
+ * disk_wblk 1816 0 0 0
+ * page 27575 1330
+ * swap 1 0
+ * intr 50444 38672 2557 0 0 0 0 2 0 2 0 0 3 1429 1 7778 0
+ * ctxt 54155
+ * btime 917379184
+ * processes 347
+ *
+ * Linux kernel >= 2.4.0 have one or more disk_io: lines instead of
+ * the disk_* lines.
+ *
+ * Linux kernel >= 2.6.x(?) have disk I/O stats in /proc/diskstats
+ * and no disk relevant lines are found in /proc/stat
+ */
+
+ char format[ 32 ];
+ char tagFormat[ 16 ];
+ char buf[ 1024 ];
+ char tag[ 32 ];
+ char* statBufP = StatBuf;
+ char* vmstatBufP = VmStatBuf;
+ char* iostatBufP = IOStatBuf;
+
+ StatSM = sm;
+
+ updateStat();
+
+ sprintf( format, "%%%d[^\n]\n", (int)sizeof( buf ) - 1 );
+ sprintf( tagFormat, "%%%ds", (int)sizeof( tag ) - 1 );
+
+ while ( sscanf( statBufP, format, buf ) == 1 ) {
+ buf[ sizeof( buf ) - 1 ] = '\0';
+ statBufP += strlen( buf ) + 1; /* move statBufP to next line */
+ sscanf( buf, tagFormat, tag );
+
+ if ( strcmp( "cpu", tag ) == 0 ) {
+ /* Total CPU load */
+ registerMonitor( "cpu/user", "integer", printCPUUser, printCPUUserInfo, StatSM );
+ registerMonitor( "cpu/nice", "integer", printCPUNice, printCPUNiceInfo, StatSM );
+ registerMonitor( "cpu/sys", "integer", printCPUSys, printCPUSysInfo, StatSM );
+ registerMonitor( "cpu/idle", "integer", printCPUIdle, printCPUIdleInfo, StatSM );
+ } else if ( strncmp( "cpu", tag, 3 ) == 0 ) {
+ char cmdName[ 24 ];
+ /* Load for each SMP CPU */
+ int id;
+
+ sscanf( tag + 3, "%d", &id );
+ CPUCount++;
+ sprintf( cmdName, "cpu%d/user", id );
+ registerMonitor( cmdName, "integer", printCPUxUser, printCPUxUserInfo, StatSM );
+ sprintf( cmdName, "cpu%d/nice", id );
+ registerMonitor( cmdName, "integer", printCPUxNice, printCPUxNiceInfo, StatSM );
+ sprintf( cmdName, "cpu%d/sys", id );
+ registerMonitor( cmdName, "integer", printCPUxSys, printCPUxSysInfo, StatSM );
+ sprintf( cmdName, "cpu%d/idle", id );
+ registerMonitor( cmdName, "integer", printCPUxIdle, printCPUxIdleInfo, StatSM );
+ } else if ( strcmp( "disk", tag ) == 0 ) {
+ unsigned long val;
+ char* b = buf + 5;
+
+ /* Count the number of registered disks */
+ for ( DiskCount = 0; *b && sscanf( b, "%lu", &val ) == 1; DiskCount++ ) {
+ while ( *b && isblank( *b++ ) );
+ while ( *b && isdigit( *b++ ) );
+ }
+
+ if ( DiskCount > 0 )
+ DiskLoad = (DiskLoadInfo*)malloc( sizeof( DiskLoadInfo ) * DiskCount );
+ initStatDisk( tag, buf, "disk", "disk", 0, printDiskTotal, printDiskTotalInfo );
+ } else if ( initStatDisk( tag, buf, "disk_rio", "rio", 1, printDiskRIO,
+ printDiskRIOInfo ) );
+ else if ( initStatDisk( tag, buf, "disk_wio", "wio", 2, printDiskWIO,
+ printDiskWIOInfo ) );
+ else if ( initStatDisk( tag, buf, "disk_rblk", "rblk", 3, printDiskRBlk,
+ printDiskRBlkInfo ) );
+ else if ( initStatDisk( tag, buf, "disk_wblk", "wblk", 4, printDiskWBlk,
+ printDiskWBlkInfo ) );
+ else if ( strcmp( "disk_io:", tag ) == 0 )
+ processDiskIO( buf );
+ else if ( strcmp( "page", tag ) == 0 ) {
+ sscanf( buf + 5, "%lu %lu", &OldPageIn, &OldPageOut );
+ registerMonitor( "cpu/pageIn", "integer", printPageIn,
+ printPageInInfo, StatSM );
+ registerMonitor( "cpu/pageOut", "integer", printPageOut,
+ printPageOutInfo, StatSM );
+ } else if ( strcmp( "intr", tag ) == 0 ) {
+ unsigned int i;
+ char cmdName[ 32 ];
+ char* p = buf + 5;
+
+ /* Count the number of listed values in the intr line. */
+ NumOfInts = 0;
+ while ( *p )
+ if ( *p++ == ' ' )
+ NumOfInts++;
+
+ /* It looks like anything above 24 is always 0. So let's just
+ * ignore this for the time being. */
+ if ( NumOfInts > 25 )
+ NumOfInts = 25;
+ OldIntr = (unsigned long*)malloc( NumOfInts * sizeof( unsigned long ) );
+ Intr = (unsigned long*)malloc( NumOfInts * sizeof( unsigned long ) );
+ i = 0;
+ p = buf + 5;
+ for ( i = 0; p && i < NumOfInts; i++ ) {
+ sscanf( p, "%lu", &OldIntr[ i ] );
+ while ( *p && *p != ' ' )
+ p++;
+ while ( *p && *p == ' ' )
+ p++;
+ sprintf( cmdName, "cpu/interrupts/int%02d", i );
+ registerMonitor( cmdName, "integer", printInterruptx,
+ printInterruptxInfo, StatSM );
+ }
+ } else if ( strcmp( "ctxt", tag ) == 0 ) {
+ sscanf( buf + 5, "%lu", &OldCtxt );
+ registerMonitor( "cpu/context", "integer", printCtxt,
+ printCtxtInfo, StatSM );
+ }
+ }
+
+ while ( sscanf( vmstatBufP, format, buf ) == 1 ) {
+ buf[ sizeof( buf ) - 1 ] = '\0';
+ vmstatBufP += strlen( buf ) + 1; /* move vmstatBufP to next line */
+ sscanf( buf, tagFormat, tag );
+
+ if ( strcmp( "pgpgin", tag ) == 0 ) {
+ sscanf( buf + 7, "%lu", &OldPageIn );
+ registerMonitor( "cpu/pageIn", "integer", printPageIn,
+ printPageInInfo, StatSM );
+ } else if ( strcmp( "pgpgout", tag ) == 0 ) {
+ sscanf( buf + 7, "%lu", &OldPageOut );
+ registerMonitor( "cpu/pageOut", "integer", printPageOut,
+ printPageOutInfo, StatSM );
+ }
+ }
+
+ /* Process values from /proc/diskstats (Linux >= 2.6.x) */
+ while (sscanf(iostatBufP, format, buf) == 1)
+ {
+ buf[sizeof(buf) - 1] = '\0';
+ iostatBufP += strlen(buf) + 1; /* move IOstatBufP to next line */
+
+ process26DiskIO(buf);
+ }
+
+ if ( CPUCount > 0 )
+ SMPLoad = (CPULoadInfo*)malloc( sizeof( CPULoadInfo ) * CPUCount );
+
+ /* Call processStat to eliminate initial peek values. */
+ processStat();
+}
+
+void exitStat( void )
+{
+ free( DiskLoad );
+ DiskLoad = 0;
+
+ free( SMPLoad );
+ SMPLoad = 0;
+
+ free( OldIntr );
+ OldIntr = 0;
+
+ free( Intr );
+ Intr = 0;
+}
+
+int updateStat( void )
+{
+ size_t n;
+ int fd;
+
+ if ( ( fd = open( "/proc/stat", O_RDONLY ) ) < 0 ) {
+ print_error( "Cannot open file \'/proc/stat\'!\n"
+ "The kernel needs to be compiled with support\n"
+ "for /proc filesystem enabled!\n" );
+ return -1;
+ }
+
+ if ( ( n = read( fd, StatBuf, STATBUFSIZE - 1 ) ) == STATBUFSIZE - 1 ) {
+ log_error( "Internal buffer too small to read \'/proc/stat\'" );
+
+ close( fd );
+ return -1;
+ }
+
+ gettimeofday( &currSampling, 0 );
+ close( fd );
+ StatBuf[ n ] = '\0';
+ Dirty = 1;
+
+ VmStatBuf[ 0 ] = '\0';
+ if ( ( fd = open( "/proc/vmstat", O_RDONLY ) ) < 0 )
+ return 0; /* failure is okay, only exists for Linux >= 2.5.x */
+
+ if ( ( n = read( fd, VmStatBuf, STATBUFSIZE - 1 ) ) == STATBUFSIZE - 1 ) {
+ log_error( "Internal buffer too small to read \'/proc/vmstat\'" );
+
+ close( fd );
+ return -1;
+ }
+
+ close( fd );
+ VmStatBuf[ n ] = '\0';
+
+ /* Linux >= 2.6.x has disk I/O stats in /proc/diskstats */
+ IOStatBuf[ 0 ] = '\0';
+ if ( ( fd = open( "/proc/diskstats", O_RDONLY ) ) < 0 )
+ return 0; /* failure is okay, only exists for Linux >= 2.6.x */
+
+ if ( ( n = read( fd, IOStatBuf, STATBUFSIZE - 1 ) ) == STATBUFSIZE - 1 ) {
+ log_error( "Internal buffer too small to read \'/proc/diskstats\'" );
+
+ close( fd );
+ return -1;
+ }
+
+ close( fd );
+ IOStatBuf[ n ] = '\0';
+
+ return 0;
+}
+
+void printCPUUser( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processStat();
+
+ fprintf( CurrentClient, "%d\n", CPULoad.userLoad );
+}
+
+void printCPUUserInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "CPU User Load\t0\t100\t%%\n" );
+}
+
+void printCPUNice( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processStat();
+
+ fprintf( CurrentClient, "%d\n", CPULoad.niceLoad );
+}
+
+void printCPUNiceInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "CPU Nice Load\t0\t100\t%%\n" );
+}
+
+void printCPUSys( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processStat();
+
+ fprintf( CurrentClient, "%d\n", CPULoad.sysLoad );
+}
+
+void printCPUSysInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "CPU System Load\t0\t100\t%%\n" );
+}
+
+void printCPUIdle( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processStat();
+
+ fprintf( CurrentClient, "%d\n", CPULoad.idleLoad );
+}
+
+void printCPUIdleInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "CPU Idle Load\t0\t100\t%%\n" );
+}
+
+void printCPUxUser( const char* cmd )
+{
+ int id;
+
+ if ( Dirty )
+ processStat();
+
+ sscanf( cmd + 3, "%d", &id );
+ fprintf( CurrentClient, "%d\n", SMPLoad[ id ].userLoad );
+}
+
+void printCPUxUserInfo( const char* cmd )
+{
+ int id;
+
+ sscanf( cmd + 3, "%d", &id );
+ fprintf( CurrentClient, "CPU%d User Load\t0\t100\t%%\n", id );
+}
+
+void printCPUxNice( const char* cmd )
+{
+ int id;
+
+ if ( Dirty )
+ processStat();
+
+ sscanf( cmd + 3, "%d", &id );
+ fprintf( CurrentClient, "%d\n", SMPLoad[ id ].niceLoad );
+}
+
+void printCPUxNiceInfo( const char* cmd )
+{
+ int id;
+
+ sscanf( cmd + 3, "%d", &id );
+ fprintf( CurrentClient, "CPU%d Nice Load\t0\t100\t%%\n", id );
+}
+
+void printCPUxSys( const char* cmd )
+{
+ int id;
+
+ if ( Dirty )
+ processStat();
+
+ sscanf( cmd + 3, "%d", &id );
+ fprintf( CurrentClient, "%d\n", SMPLoad[ id ].sysLoad );
+}
+
+void printCPUxSysInfo( const char* cmd )
+{
+ int id;
+
+ sscanf( cmd + 3, "%d", &id );
+ fprintf( CurrentClient, "CPU%d System Load\t0\t100\t%%\n", id );
+}
+
+void printCPUxIdle( const char* cmd )
+{
+ int id;
+
+ if ( Dirty )
+ processStat();
+
+ sscanf( cmd + 3, "%d", &id );
+ fprintf( CurrentClient, "%d\n", SMPLoad[ id ].idleLoad );
+}
+
+void printCPUxIdleInfo( const char* cmd )
+{
+ int id;
+
+ sscanf( cmd + 3, "%d", &id );
+ fprintf( CurrentClient, "CPU%d Idle Load\t0\t100\t%%\n", id );
+}
+
+void printDiskTotal( const char* cmd )
+{
+ int id;
+
+ if ( Dirty )
+ processStat();
+
+ sscanf( cmd + 9, "%d", &id );
+ fprintf( CurrentClient, "%lu\n", (unsigned long)( DiskLoad[ id ].s[ 0 ].delta
+ / timeInterval ) );
+}
+
+void printDiskTotalInfo( const char* cmd )
+{
+ int id;
+
+ sscanf( cmd + 9, "%d", &id );
+ fprintf( CurrentClient, "Disk%d Total Load\t0\t0\tkBytes/s\n", id );
+}
+
+void printDiskRIO( const char* cmd )
+{
+ int id;
+
+ if ( Dirty )
+ processStat();
+
+ sscanf( cmd + 9, "%d", &id );
+ fprintf( CurrentClient, "%lu\n", (unsigned long)( DiskLoad[ id ].s[ 1 ].delta
+ / timeInterval ) );
+}
+
+void printDiskRIOInfo( const char* cmd )
+{
+ int id;
+
+ sscanf( cmd + 9, "%d", &id );
+ fprintf( CurrentClient, "Disk%d Read\t0\t0\tkBytes/s\n", id );
+}
+
+void printDiskWIO( const char* cmd )
+{
+ int id;
+
+ if ( Dirty )
+ processStat();
+
+ sscanf( cmd + 9, "%d", &id );
+ fprintf( CurrentClient, "%lu\n", (unsigned long)( DiskLoad[ id ].s[ 2 ].delta
+ / timeInterval ) );
+}
+
+void printDiskWIOInfo( const char* cmd )
+{
+ int id;
+
+ sscanf( cmd + 9, "%d", &id );
+ fprintf( CurrentClient, "Disk%d Write\t0\t0\tkBytes/s\n", id );
+}
+
+void printDiskRBlk( const char* cmd )
+{
+ int id;
+
+ if ( Dirty )
+ processStat();
+
+ sscanf( cmd + 9, "%d", &id );
+ /* a block is 512 bytes or 1/2 kBytes */
+ fprintf( CurrentClient, "%lu\n", (unsigned long)( DiskLoad[ id ].s[ 3 ].delta
+ / timeInterval * 2 ) );
+}
+
+void printDiskRBlkInfo( const char* cmd )
+{
+ int id;
+
+ sscanf( cmd + 9, "%d", &id );
+ fprintf( CurrentClient, "Disk%d Read Data\t0\t0\tkBytes/s\n", id );
+}
+
+void printDiskWBlk( const char* cmd )
+{
+ int id;
+
+ if ( Dirty )
+ processStat();
+
+ sscanf( cmd + 9, "%d", &id );
+ /* a block is 512 bytes or 1/2 kBytes */
+ fprintf( CurrentClient, "%lu\n", (unsigned long)( DiskLoad[ id ].s[ 4 ].delta
+ / timeInterval * 2 ) );
+}
+
+void printDiskWBlkInfo( const char* cmd )
+{
+ int id;
+
+ sscanf( cmd + 9, "%d", &id );
+ fprintf( CurrentClient, "Disk%d Write Data\t0\t0\tkBytes/s\n", id );
+}
+
+void printPageIn( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processStat();
+
+ fprintf( CurrentClient, "%lu\n", (unsigned long)( PageIn / timeInterval ) );
+}
+
+void printPageInInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "Paged in Pages\t0\t0\t1/s\n" );
+}
+
+void printPageOut( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processStat();
+
+ fprintf( CurrentClient, "%lu\n", (unsigned long)( PageOut / timeInterval ) );
+}
+
+void printPageOutInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "Paged out Pages\t0\t0\t1/s\n" );
+}
+
+void printInterruptx( const char* cmd )
+{
+ int id;
+
+ if ( Dirty )
+ processStat();
+
+ sscanf( cmd + strlen( "cpu/interrupts/int" ), "%d", &id );
+ fprintf( CurrentClient, "%lu\n", (unsigned long)( Intr[ id ] / timeInterval ) );
+}
+
+void printInterruptxInfo( const char* cmd )
+{
+ int id;
+
+ sscanf( cmd + strlen( "cpu/interrupt/int" ), "%d", &id );
+ fprintf( CurrentClient, "Interrupt %d\t0\t0\t1/s\n", id );
+}
+
+void printCtxt( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processStat();
+
+ fprintf( CurrentClient, "%lu\n", (unsigned long)( Ctxt / timeInterval ) );
+}
+
+void printCtxtInfo( const char* cmd )
+{
+ (void)cmd;
+ fprintf( CurrentClient, "Context switches\t0\t0\t1/s\n" );
+}
+
+void printDiskIO( const char* cmd )
+{
+ int major, minor;
+ char name[ 17 ];
+ DiskIOInfo* ptr;
+
+ sscanf( cmd, "disk/%d:%d/%16s", &major, &minor, name );
+
+ if ( Dirty )
+ processStat();
+
+ ptr = DiskIO;
+ while ( ptr && ( ptr->major != major || ptr->minor != minor ) )
+ ptr = ptr->next;
+
+ if ( !ptr ) {
+ print_error( "RECONFIGURE" );
+ fprintf( CurrentClient, "0\n" );
+
+ log_error( "Disk device disappeared" );
+ return;
+ }
+
+ if ( strcmp( name, "total" ) == 0 )
+ fprintf( CurrentClient, "%lu\n", (unsigned long)( ptr->total.delta
+ / timeInterval ) );
+ else if ( strcmp( name, "rio" ) == 0 )
+ fprintf( CurrentClient, "%lu\n", (unsigned long)( ptr->rio.delta
+ / timeInterval ) );
+ else if ( strcmp( name, "wio" ) == 0 )
+ fprintf( CurrentClient, "%lu\n", (unsigned long)( ptr->wio.delta
+ / timeInterval ) );
+ else if ( strcmp( name, "rblk" ) == 0 )
+ fprintf( CurrentClient, "%lu\n", (unsigned long)( ptr->rblk.delta
+ / ( timeInterval * 2 ) ) );
+ else if ( strcmp( name, "wblk" ) == 0 )
+ fprintf( CurrentClient, "%lu\n", (unsigned long)( ptr->wblk.delta
+ / ( timeInterval * 2 ) ) );
+ else {
+ fprintf( CurrentClient, "0\n" );
+ log_error( "Unknown disk device property \'%s\'", name );
+ }
+}
+
+void printDiskIOInfo( const char* cmd )
+{
+ int major, minor;
+ char name[ 17 ];
+ DiskIOInfo* ptr = DiskIO;
+
+ sscanf( cmd, "disk/%d:%d/%16s", &major, &minor, name );
+
+ while ( ptr && ( ptr->major != major || ptr->minor != minor ) )
+ ptr = ptr->next;
+
+ if ( !ptr ) {
+ /* Disk device has disappeared. Print a dummy answer. */
+ fprintf( CurrentClient, "Dummy\t0\t0\t\n" );
+ return;
+ }
+
+ /* remove trailing '?' */
+ name[ strlen( name ) - 1 ] = '\0';
+
+ if ( strcmp( name, "total" ) == 0 )
+ fprintf( CurrentClient, "Total accesses device %d, %d\t0\t0\t1/s\n",
+ major, minor );
+ else if ( strcmp( name, "rio" ) == 0 )
+ fprintf( CurrentClient, "Read data device %d, %d\t0\t0\t1/s\n",
+ major, minor );
+ else if ( strcmp( name, "wio" ) == 0 )
+ fprintf( CurrentClient, "Write data device %d, %d\t0\t0\t1/s\n",
+ major, minor );
+ else if ( strcmp( name, "rblk" ) == 0 )
+ fprintf( CurrentClient, "Read accesses device %d, %d\t0\t0\tkBytes/s\n",
+ major, minor );
+ else if ( strcmp( name, "wblk" ) == 0 )
+ fprintf( CurrentClient, "Write accesses device %d, %d\t0\t0\tkBytes/s\n",
+ major, minor );
+ else {
+ fprintf( CurrentClient, "Dummy\t0\t0\t\n" );
+ log_error( "Request for unknown device property \'%s\'", name );
+ }
+}
diff --git a/ksysguard/ksysguardd/Linux/stat.h b/ksysguard/ksysguardd/Linux/stat.h
new file mode 100644
index 000000000..9107d3aa3
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/stat.h
@@ -0,0 +1,66 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999, 2000 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KSG_STAT_H
+#define KSG_STAT_H
+
+void initStat( struct SensorModul* );
+void exitStat( void );
+
+int updateStat( void );
+
+void printCPUUser( const char* );
+void printCPUUserInfo( const char* );
+void printCPUNice( const char* );
+void printCPUNiceInfo( const char* );
+void printCPUSys( const char* );
+void printCPUSysInfo( const char* );
+void printCPUIdle( const char* );
+void printCPUIdleInfo( const char* );
+void printCPUxUser( const char* );
+void printCPUxUserInfo( const char* );
+void printCPUxNice( const char* );
+void printCPUxNiceInfo( const char* );
+void printCPUxSys( const char* );
+void printCPUxSysInfo( const char* );
+void printCPUxIdle( const char* );
+void printCPUxIdleInfo( const char* );
+void printDiskTotal( const char* );
+void printDiskTotalInfo( const char* );
+void printDiskRIO( const char* );
+void printDiskRIOInfo( const char* );
+void printDiskWIO( const char* );
+void printDiskWIOInfo( const char* );
+void printDiskRBlk( const char* );
+void printDiskRBlkInfo( const char* );
+void printDiskWBlk( const char* );
+void printDiskWBlkInfo( const char* );
+void printPageIn( const char* );
+void printPageInInfo( const char* );
+void printPageOut( const char* );
+void printPageOutInfo( const char* );
+void printInterruptx( const char* );
+void printInterruptxInfo( const char* );
+void printCtxt( const char* );
+void printCtxtInfo( const char* );
+void printDiskIO( const char* );
+void printDiskIOInfo( const char* );
+
+#endif
diff --git a/ksysguard/ksysguardd/Makefile.am b/ksysguard/ksysguardd/Makefile.am
new file mode 100644
index 000000000..485700780
--- /dev/null
+++ b/ksysguard/ksysguardd/Makefile.am
@@ -0,0 +1,35 @@
+AUTOMAKE_OPTIONS = foreign
+
+if include_ksysguardd_linux
+linux_SUBDIR = Linux
+endif
+if include_ksysguardd_freebsd
+freebsd_SUBDIR = FreeBSD
+endif
+if include_ksysguardd_netbsd
+netbsd_SUBDIR = NetBSD
+endif
+if include_ksysguardd_solaris
+solaris_SUBDIR = Solaris
+endif
+if include_ksysguardd_tru64
+tru64_SUBDIR = Tru64
+endif
+if include_ksysguardd_irix
+irix_SUBDIR = Irix
+endif
+if include_ksysguardd_openbsd
+openbsd_SUBDIR = OpenBSD
+endif
+
+SUBDIRS = $(linux_SUBDIR) $(freebsd_SUBDIR) $(netbsd_SUBDIR)\
+ $(solaris_SUBDIR) $(tru64_SUBDIR) $(irix_SUBDIR) $(openbsd_SUBDIR)
+
+KSYSGUARDDRCFILE=$(sysconfdir)/ksysguarddrc
+INCLUDES = -DKSYSGUARDDRCFILE="\"$(KSYSGUARDDRCFILE)\"" -DOSTYPE_$(UNAME) -I$(srcdir)/../CContLib -I$(srcdir)/$(UNAME) $(all_includes)
+
+bin_PROGRAMS = ksysguardd
+
+ksysguardd_SOURCES = Command.c conf.c ksysguardd.c PWUIDCache.c
+ksysguardd_LDFLAGS = $(all_libraries)
+ksysguardd_LDADD = $(top_builddir)/ksysguard/ksysguardd/$(UNAME)/libksysguardd.a ../CContLib/libccont.a -lkdefakes_nonpic $(LIBHOSTS) $(LIB_DNSSD) $(LIB_KINFO)
diff --git a/ksysguard/ksysguardd/NetBSD/CPU.c b/ksysguard/ksysguardd/NetBSD/CPU.c
new file mode 100644
index 000000000..959924087
--- /dev/null
+++ b/ksysguard/ksysguardd/NetBSD/CPU.c
@@ -0,0 +1,206 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <sys/dkstat.h>
+#include <sys/sched.h> /* CPUSTATES */
+#include <fcntl.h>
+#include <kvm.h>
+#include <nlist.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "CPU.h"
+#include "Command.h"
+#include "ksysguardd.h"
+
+long percentages(int cnt, int *out, long *new, long *old, long *diffs);
+
+struct nlist my_nlist[] = {
+ {"_cp_time"},
+ { 0 }
+};
+
+kvm_t *kd;
+
+unsigned long cp_time_offset;
+
+long cp_time[CPUSTATES];
+long cp_old[CPUSTATES];
+long cp_diff[CPUSTATES];
+int cpu_states[CPUSTATES];
+
+void
+initCpuInfo(struct SensorModul* sm)
+{
+ /* Total CPU load */
+ registerMonitor("cpu/user", "integer", printCPUUser,
+ printCPUUserInfo, sm);
+ registerMonitor("cpu/nice", "integer", printCPUNice,
+ printCPUNiceInfo, sm);
+ registerMonitor("cpu/sys", "integer", printCPUSys,
+ printCPUSysInfo, sm);
+ registerMonitor("cpu/idle", "integer", printCPUIdle,
+ printCPUIdleInfo, sm);
+ kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open");
+ kvm_nlist(kd, my_nlist);
+ cp_time_offset = my_nlist[0].n_value;
+
+ updateCpuInfo();
+}
+
+void
+exitCpuInfo(void)
+{
+ kvm_close(kd);
+}
+
+int
+updateCpuInfo(void)
+{
+ kvm_read(kd, cp_time_offset, (char *)cp_time, sizeof(cp_time));
+ percentages(CPUSTATES, cpu_states, cp_time, cp_old, cp_diff);
+ return (0);
+}
+
+void
+printCPUUser(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", cpu_states[CP_USER]/10);
+}
+
+void
+printCPUUserInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "CPU User Load\t0\t100\t%%\n");
+}
+
+void
+printCPUNice(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", cpu_states[CP_NICE]/10);
+}
+
+void
+printCPUNiceInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "CPU Nice Load\t0\t100\t%%\n");
+}
+
+void
+printCPUSys(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", cpu_states[CP_SYS]/10);
+}
+
+void
+printCPUSysInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "CPU System Load\t0\t100\t%%\n");
+}
+
+void
+printCPUIdle(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", cpu_states[CP_IDLE]/10);
+}
+
+void
+printCPUIdleInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "CPU Idle Load\t0\t100\t%%\n");
+}
+
+
+/* The part ripped from top... */
+/*
+ * Top users/processes display for Unix
+ * Version 3
+ *
+ * This program may be freely redistributed,
+ * but this entire comment MUST remain intact.
+ *
+ * Copyright (c) 1984, 1989, William LeFebvre, Rice University
+ * Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University
+ */
+
+/*
+ * percentages(cnt, out, new, old, diffs) - calculate percentage change
+ * between array "old" and "new", putting the percentages i "out".
+ * "cnt" is size of each array and "diffs" is used for scratch space.
+ * The array "old" is updated on each call.
+ * The routine assumes modulo arithmetic. This function is especially
+ * useful on BSD mchines for calculating cpu state percentages.
+ */
+
+long percentages(cnt, out, new, old, diffs)
+
+int cnt;
+int *out;
+register long *new;
+register long *old;
+long *diffs;
+
+{
+ register int i;
+ register long change;
+ register long total_change;
+ register long *dp;
+ long half_total;
+
+ /* initialization */
+ total_change = 0;
+ dp = diffs;
+
+ /* calculate changes for each state and the overall change */
+ for (i = 0; i < cnt; i++)
+ {
+ if ((change = *new - *old) < 0)
+ {
+ /* this only happens when the counter wraps */
+ change = (int)
+ ((unsigned long)*new-(unsigned long)*old);
+ }
+ total_change += (*dp++ = change);
+ *old++ = *new++;
+ }
+
+ /* avoid divide by zero potential */
+ if (total_change == 0)
+ {
+ total_change = 1;
+ }
+
+ /* calculate percentages based on overall change, rounding up */
+ half_total = total_change / 2l;
+
+ /* Do not divide by 0. Causes Floating point exception */
+ if(total_change) {
+ for (i = 0; i < cnt; i++)
+ {
+ *out++ = (int)((*diffs++ * 1000 + half_total) / total_change);
+ }
+ }
+
+ /* return the total in case the caller wants to use it */
+ return(total_change);
+}
diff --git a/ksysguard/ksysguardd/NetBSD/CPU.h b/ksysguard/ksysguardd/NetBSD/CPU.h
new file mode 100644
index 000000000..c35932ac8
--- /dev/null
+++ b/ksysguard/ksysguardd/NetBSD/CPU.h
@@ -0,0 +1,49 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _cpuinfo_h_
+#define _cpuinfo_h_
+
+struct SensorModul;
+
+void initCpuInfo(struct SensorModul* sm);
+void exitCpuInfo(void);
+
+int updateCpuInfo(void);
+
+void printCPUUser(const char* cmd);
+void printCPUUserInfo(const char* cmd);
+void printCPUNice(const char* cmd);
+void printCPUNiceInfo(const char* cmd);
+void printCPUSys(const char* cmd);
+void printCPUSysInfo(const char* cmd);
+void printCPUIdle(const char* cmd);
+void printCPUIdleInfo(const char* cmd);
+void printCPUxUser(const char* cmd);
+void printCPUxUserInfo(const char* cmd);
+void printCPUxNice(const char* cmd);
+void printCPUxNiceInfo(const char* cmd);
+void printCPUxSys(const char* cmd);
+void printCPUxSysInfo(const char* cmd);
+void printCPUxIdle(const char* cmd);
+void printCPUxIdleInfo(const char* cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/NetBSD/Makefile.am b/ksysguard/ksysguardd/NetBSD/Makefile.am
new file mode 100644
index 000000000..29860a407
--- /dev/null
+++ b/ksysguard/ksysguardd/NetBSD/Makefile.am
@@ -0,0 +1,8 @@
+#
+#
+
+INCLUDES = -I$(srcdir)/../../CContLib -I$(srcdir)/..
+
+noinst_LIBRARIES = libksysguardd.a
+libksysguardd_a_SOURCES = CPU.c Memory.c ProcessList.c apm.c diskstat.c \
+ loadavg.c logfile.c netdev.c
diff --git a/ksysguard/ksysguardd/NetBSD/Memory.c b/ksysguard/ksysguardd/NetBSD/Memory.c
new file mode 100644
index 000000000..8e9779506
--- /dev/null
+++ b/ksysguard/ksysguardd/NetBSD/Memory.c
@@ -0,0 +1,202 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999-2000 Hans Petter Bieker <bieker@kde.org>
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <fcntl.h>
+#include <kvm.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#include <sys/vmmeter.h>
+#include <unistd.h>
+/* Everything post 1.5.x uses uvm/uvm_* includes */
+#if __NetBSD_Version__ >= 105010000
+#include <uvm/uvm_param.h>
+#else
+#include <vm/vm_param.h>
+#endif
+
+#include "Command.h"
+#include "Memory.h"
+#include "ksysguardd.h"
+
+static size_t Total = 0;
+static size_t MFree = 0;
+static size_t Used = 0;
+static size_t Buffers = 0;
+static size_t Cached = 0;
+static size_t STotal = 0;
+static size_t SFree = 0;
+static size_t SUsed = 0;
+static kvm_t *kd;
+
+void
+initMemory(struct SensorModul* sm)
+{
+ char *nlistf = NULL;
+ char *memf = NULL;
+ char buf[_POSIX2_LINE_MAX];
+
+ if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf)) == NULL) {
+ log_error("kvm_openfiles()");
+ return;
+ }
+
+ registerMonitor("mem/physical/free", "integer", printMFree, printMFreeInfo, sm);
+ registerMonitor("mem/physical/used", "integer", printUsed, printUsedInfo, sm);
+ registerMonitor("mem/physical/buf", "integer", printBuffers, printBuffersInfo, sm);
+ registerMonitor("mem/physical/cached", "integer", printCached, printCachedInfo, sm);
+ registerMonitor("mem/swap/free", "integer", printSwapFree, printSwapFreeInfo, sm);
+ registerMonitor("mem/swap/used", "integer", printSwapUsed, printSwapUsedInfo, sm);
+}
+
+void
+exitMemory(void)
+{
+ kvm_close(kd);
+}
+
+int
+updateMemory(void)
+{
+
+#define ARRLEN(X) (sizeof(X)/sizeof(X[0]))
+ long pagesize; /* using a long promotes the arithmetic */
+ size_t len;
+
+ {
+ static int mib[]={ CTL_HW, HW_PHYSMEM };
+
+ len = sizeof(Total);
+ sysctl(mib, ARRLEN(mib), &Total, &len, NULL, 0);
+ Total >>= 10;
+ }
+
+ {
+ struct uvmexp x;
+ static int mib[] = { CTL_VM, VM_UVMEXP };
+
+ len = sizeof(x);
+ STotal = SUsed = SFree = -1;
+ pagesize = 1;
+ if (-1 < sysctl(mib, ARRLEN(mib), &x, &len, NULL, 0)) {
+ pagesize = x.pagesize;
+ STotal = (pagesize*x.swpages) >> 10;
+ SUsed = (pagesize*x.swpginuse) >> 10;
+ SFree = STotal - SUsed;
+ }
+ }
+
+ /* can't find NetBSD filesystem buffer info */
+ Buffers = -1;
+
+ /* NetBSD doesn't know about vm.stats */
+ Cached = -1;
+
+ {
+ static int mib[]={ CTL_VM, VM_METER };
+ struct vmtotal x;
+
+ len = sizeof(x);
+ MFree = Used = -1;
+ if (sysctl(mib, ARRLEN(mib), &x, &len, NULL, 0) > -1) {
+ MFree = (x.t_free * pagesize) >> 10;
+ Used = (x.t_rm * pagesize) >> 10;
+ }
+ }
+ return 0;
+}
+
+void
+printMFree(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", MFree);
+}
+
+void
+printMFreeInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Free Memory\t0\t%d\tKB\n", Total);
+}
+
+void
+printUsed(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", Used);
+}
+
+void
+printUsedInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Used Memory\t0\t%d\tKB\n", Total);
+}
+
+void
+printBuffers(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", Buffers);
+}
+
+void
+printBuffersInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Buffer Memory\t0\t%d\tKB\n", Total);
+}
+
+void
+printCached(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", Cached);
+}
+
+void
+printCachedInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Cached Memory\t0\t%d\tKB\n", Total);
+}
+
+void
+printSwapUsed(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", SUsed);
+}
+
+void
+printSwapUsedInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Used Swap Memory\t0\t%d\tKB\n", STotal);
+}
+
+void
+printSwapFree(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", SFree);
+}
+
+void
+printSwapFreeInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Free Swap Memory\t0\t%d\tKB\n", STotal);
+}
diff --git a/ksysguard/ksysguardd/NetBSD/Memory.h b/ksysguard/ksysguardd/NetBSD/Memory.h
new file mode 100644
index 000000000..57abb73a2
--- /dev/null
+++ b/ksysguard/ksysguardd/NetBSD/Memory.h
@@ -0,0 +1,43 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _memory_h_
+#define _memory_h_
+
+void initMemory(struct SensorModul* sm);
+void exitMemory(void);
+
+int updateMemory(void);
+
+void printMFree(const char* cmd);
+void printMFreeInfo(const char* cmd);
+void printUsed(const char* cmd);
+void printUsedInfo(const char* cmd);
+void printBuffers(const char* cmd);
+void printBuffersInfo(const char* cmd);
+void printCached(const char* cmd);
+void printCachedInfo(const char* cmd);
+void printSwapUsed(const char* cmd);
+void printSwapUsedInfo(const char* cmd);
+void printSwapFree(const char* cmd);
+void printSwapFreeInfo(const char* cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/NetBSD/ProcessList.c b/ksysguard/ksysguardd/NetBSD/ProcessList.c
new file mode 100644
index 000000000..54ab65513
--- /dev/null
+++ b/ksysguard/ksysguardd/NetBSD/ProcessList.c
@@ -0,0 +1,457 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999-2000 Hans Petter Bieker<bieker@kde.org>
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <config.h>
+
+#include <ctype.h>
+#include <dirent.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include "../../gui/SignalIDs.h"
+#include "Command.h"
+#include "ProcessList.h"
+#include "ccont.h"
+#include "ksysguardd.h"
+
+CONTAINER ProcessList = 0;
+
+#define BUFSIZE 1024
+
+typedef struct
+{
+ /* This flag is set for all found processes at the beginning of the
+ * process list update. Processes that do not have this flag set will
+ * be assumed dead and removed from the list. The flag is cleared after
+ * each list update. */
+ int alive;
+
+ /* the process ID */
+ pid_t pid;
+
+ /* the parent process ID */
+ pid_t ppid;
+
+ /* the real user ID */
+ uid_t uid;
+
+ /* the real group ID */
+ gid_t gid;
+
+ /* a character description of the process status */
+ char status[16];
+
+ /* the number of the tty the process owns */
+ int ttyNo;
+
+ /*
+ * The nice level. The range should be -20 to 20. I'm not sure
+ * whether this is true for all platforms.
+ */
+ int niceLevel;
+
+ /*
+ * The scheduling priority.
+ */
+ int priority;
+
+ /*
+ * The total amount of memory the process uses. This includes shared and
+ * swapped memory.
+ */
+ unsigned int vmSize;
+
+ /*
+ * The amount of physical memory the process currently uses.
+ */
+ unsigned int vmRss;
+
+ /*
+ * The amount of memory (shared/swapped/etc) the process shares with
+ * other processes.
+ */
+ unsigned int vmLib;
+
+ /*
+ * The number of 1/100 of a second the process has spend in user space.
+ * If a machine has an uptime of 1 1/2 years or longer this is not a
+ * good idea. I never thought that the stability of UNIX could get me
+ * into trouble! ;)
+ */
+ unsigned int userTime;
+
+ /*
+ * The number of 1/100 of a second the process has spend in system space.
+ * If a machine has an uptime of 1 1/2 years or longer this is not a
+ * good idea. I never thought that the stability of UNIX could get me
+ * into trouble! ;)
+ */
+ unsigned int sysTime;
+
+ /* system time as multime of 100ms */
+ int centStamp;
+
+ /* the current CPU load (in %) from user space */
+ double userLoad;
+
+ /* the current CPU load (in %) from system space */
+ double sysLoad;
+
+ /* the name of the process */
+ char name[64];
+
+ /* the command used to start the process */
+ char cmdline[256];
+
+ /* the login name of the user that owns this process */
+ char userName[32];
+} ProcessInfo;
+
+static unsigned ProcessCount;
+
+static int
+processCmp(void* p1, void* p2)
+{
+ return (((ProcessInfo*) p1)->pid - ((ProcessInfo*) p2)->pid);
+}
+
+static ProcessInfo*
+findProcessInList(int pid)
+{
+ ProcessInfo key;
+ long index;
+
+ key.pid = pid;
+ if ((index = search_ctnr(ProcessList, processCmp, &key)) < 0)
+ return (0);
+
+ return (get_ctnr(ProcessList, index));
+}
+
+static int
+updateProcess(int pid)
+{
+ static char *statuses[] = { "idle","run","sleep","stop","zombie" };
+
+ ProcessInfo* ps;
+ struct passwd* pwent;
+ int mib[4];
+ struct kinfo_proc p;
+ size_t len;
+
+ if ((ps = findProcessInList(pid)) == 0)
+ {
+ ps = (ProcessInfo*) malloc(sizeof(ProcessInfo));
+ ps->pid = pid;
+ ps->centStamp = 0;
+ push_ctnr(ProcessList, ps);
+ bsort_ctnr(ProcessList, processCmp);
+ }
+
+ ps->alive = 1;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = pid;
+
+ len = sizeof (p);
+ if (sysctl(mib, 4, &p, &len, NULL, 0) == -1 || !len)
+ return -1;
+
+ ps->pid = p.kp_proc.p_pid;
+ ps->ppid = p.kp_eproc.e_ppid;
+ ps->uid = p.kp_eproc.e_ucred.cr_uid;
+ ps->gid = p.kp_eproc.e_pgid;
+ ps->priority = p.kp_proc.p_priority;
+ ps->niceLevel = p.kp_proc.p_nice;
+
+ /* this isn't usertime -- it's total time (??) */
+ ps->userTime = p.kp_proc.p_rtime.tv_sec*100+p.kp_proc.p_rtime.tv_usec/100;
+ ps->sysTime = 0;
+ ps->sysLoad = 0;
+
+ /* memory, process name, process uid */
+ /* find out user name with process uid */
+ pwent = getpwuid(ps->uid);
+ strlcpy(ps->userName,pwent&&pwent->pw_name? pwent->pw_name:"????",sizeof(ps->userName));
+ ps->userName[sizeof(ps->userName)-1]='\0';
+
+ ps->userLoad = p.kp_proc.p_pctcpu / 100;
+ ps->vmSize = (p.kp_eproc.e_vm.vm_tsize +
+ p.kp_eproc.e_vm.vm_dsize +
+ p.kp_eproc.e_vm.vm_ssize) * getpagesize();
+ ps->vmRss = p.kp_eproc.e_vm.vm_rssize * getpagesize();
+ strlcpy(ps->name,p.kp_proc.p_comm ? p.kp_proc.p_comm : "????", sizeof(ps->name));
+ strlcpy(ps->status,(p.kp_proc.p_stat>=1)&&(p.kp_proc.p_stat<=5)? statuses[p.kp_proc.p_stat-1]:"????", sizeof(ps->status));
+
+ /* process command line */
+ /* the following line causes segfaults on some FreeBSD systems... why?
+ strncpy(ps->cmdline, p.kp_proc.p_args->ar_args, sizeof(ps->cmdline) - 1);
+ */
+ strcpy(ps->cmdline, "????");
+
+ return (0);
+}
+
+static void
+cleanupProcessList(void)
+{
+ ProcessInfo* ps;
+
+ ProcessCount = 0;
+ /* All processes that do not have the active flag set are assumed dead
+ * and will be removed from the list. The alive flag is cleared. */
+ for (ps = first_ctnr(ProcessList); ps; ps = next_ctnr(ProcessList))
+ {
+ if (ps->alive)
+ {
+ /* Process is still alive. Just clear flag. */
+ ps->alive = 0;
+ ProcessCount++;
+ }
+ else
+ {
+ /* Process has probably died. We remove it from the list and
+ * destruct the data structure. i needs to be decremented so
+ * that after i++ the next list element will be inspected. */
+ free(remove_ctnr(ProcessList));
+ }
+ }
+}
+
+/*
+================================ public part ==================================
+*/
+
+void
+initProcessList(struct SensorModul* sm)
+{
+ ProcessList = new_ctnr();
+
+ registerMonitor("ps", "table", printProcessList, printProcessListInfo, sm);
+ registerMonitor("pscount", "integer", printProcessCount, printProcessCountInfo, sm);
+
+ if (!RunAsDaemon)
+ {
+ registerCommand("kill", killProcess);
+ registerCommand("setpriority", setPriority);
+ }
+
+ updateProcessList();
+}
+
+void
+exitProcessList(void)
+{
+ removeMonitor("ps");
+ removeMonitor("pscount");
+
+ if (ProcessList)
+ free (ProcessList);
+}
+
+int
+updateProcessList(void)
+{
+ int mib[3];
+ size_t len;
+ size_t num;
+ struct kinfo_proc *p;
+
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_ALL;
+ sysctl(mib, 3, NULL, &len, NULL, 0);
+ p = malloc(len);
+ sysctl(mib, 3, p, &len, NULL, 0);
+
+ for (num = 0; num < len / sizeof(struct kinfo_proc); num++)
+ updateProcess(p[num].kp_proc.p_pid);
+ free(p);
+ cleanupProcessList();
+
+ return (0);
+}
+
+void
+printProcessListInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Name\tPID\tPPID\tUID\tGID\tStatus\tUser%%\tSystem%%\tNice\tVmSize\tVmRss\tLogin\tCommand\n");
+ fprintf(CurrentClient, "s\td\td\td\td\tS\tf\tf\td\tD\tD\ts\ts\n");
+}
+
+void
+printProcessList(const char* cmd)
+{
+ ProcessInfo* ps;
+
+ ps = first_ctnr(ProcessList); /* skip 'kernel' entry */
+ for (ps = next_ctnr(ProcessList); ps; ps = next_ctnr(ProcessList))
+ {
+ fprintf(CurrentClient, "%s\t%ld\t%ld\t%ld\t%ld\t%s\t%.2f\t%.2f\t%d\t%d\t%d\t%s\t%s\n",
+ ps->name, (long)ps->pid, (long)ps->ppid,
+ (long)ps->uid, (long)ps->gid, ps->status,
+ ps->userLoad, ps->sysLoad, ps->niceLevel,
+ ps->vmSize / 1024, ps->vmRss / 1024, ps->userName, ps->cmdline);
+ }
+}
+
+void
+printProcessCount(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", ProcessCount);
+}
+
+void
+printProcessCountInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Number of Processes\t1\t65535\t\n");
+}
+
+void
+killProcess(const char* cmd)
+{
+ int sig, pid;
+
+ sscanf(cmd, "%*s %d %d", &pid, &sig);
+ switch(sig)
+ {
+ case MENU_ID_SIGABRT:
+ sig = SIGABRT;
+ break;
+ case MENU_ID_SIGALRM:
+ sig = SIGALRM;
+ break;
+ case MENU_ID_SIGCHLD:
+ sig = SIGCHLD;
+ break;
+ case MENU_ID_SIGCONT:
+ sig = SIGCONT;
+ break;
+ case MENU_ID_SIGFPE:
+ sig = SIGFPE;
+ break;
+ case MENU_ID_SIGHUP:
+ sig = SIGHUP;
+ break;
+ case MENU_ID_SIGILL:
+ sig = SIGILL;
+ break;
+ case MENU_ID_SIGINT:
+ sig = SIGINT;
+ break;
+ case MENU_ID_SIGKILL:
+ sig = SIGKILL;
+ break;
+ case MENU_ID_SIGPIPE:
+ sig = SIGPIPE;
+ break;
+ case MENU_ID_SIGQUIT:
+ sig = SIGQUIT;
+ break;
+ case MENU_ID_SIGSEGV:
+ sig = SIGSEGV;
+ break;
+ case MENU_ID_SIGSTOP:
+ sig = SIGSTOP;
+ break;
+ case MENU_ID_SIGTERM:
+ sig = SIGTERM;
+ break;
+ case MENU_ID_SIGTSTP:
+ sig = SIGTSTP;
+ break;
+ case MENU_ID_SIGTTIN:
+ sig = SIGTTIN;
+ break;
+ case MENU_ID_SIGTTOU:
+ sig = SIGTTOU;
+ break;
+ case MENU_ID_SIGUSR1:
+ sig = SIGUSR1;
+ break;
+ case MENU_ID_SIGUSR2:
+ sig = SIGUSR2;
+ break;
+ }
+ if (kill((pid_t) pid, sig))
+ {
+ switch(errno)
+ {
+ case EINVAL:
+ fprintf(CurrentClient, "4\t%d\n", pid);
+ break;
+ case ESRCH:
+ fprintf(CurrentClient, "3\t%d\n", pid);
+ break;
+ case EPERM:
+ fprintf(CurrentClient, "2\t%d\n", pid);
+ break;
+ default:
+ fprintf(CurrentClient, "1\t%d\n", pid); /* unknown error */
+ break;
+ }
+
+ }
+ else
+ fprintf(CurrentClient, "0\t%d\n", pid);
+}
+
+void
+setPriority(const char* cmd)
+{
+ int pid, prio;
+
+ sscanf(cmd, "%*s %d %d", &pid, &prio);
+ if (setpriority(PRIO_PROCESS, pid, prio))
+ {
+ switch(errno)
+ {
+ case EINVAL:
+ fprintf(CurrentClient, "4\n");
+ break;
+ case ESRCH:
+ fprintf(CurrentClient, "3\n");
+ break;
+ case EPERM:
+ case EACCES:
+ fprintf(CurrentClient, "2\n");
+ break;
+ default:
+ fprintf(CurrentClient, "1\n"); /* unknown error */
+ break;
+ }
+ }
+ else
+ fprintf(CurrentClient, "0\n");
+}
diff --git a/ksysguard/ksysguardd/NetBSD/ProcessList.h b/ksysguard/ksysguardd/NetBSD/ProcessList.h
new file mode 100644
index 000000000..925c55f5a
--- /dev/null
+++ b/ksysguard/ksysguardd/NetBSD/ProcessList.h
@@ -0,0 +1,38 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _process_list_h_
+#define _process_list_h_
+
+void initProcessList(struct SensorModul* sm);
+void exitProcessList(void);
+
+int updateProcessList(void);
+
+void printProcessList(const char*);
+void printProcessListInfo(const char*);
+void printProcessCount(const char* cmd);
+void printProcessCountInfo(const char* cmd);
+
+void killProcess(const char* cmd);
+void setPriority(const char* cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/NetBSD/apm.c b/ksysguard/ksysguardd/NetBSD/apm.c
new file mode 100644
index 000000000..f24887483
--- /dev/null
+++ b/ksysguard/ksysguardd/NetBSD/apm.c
@@ -0,0 +1,100 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+
+#include <fcntl.h>
+#include <machine/apmvar.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include "Command.h"
+#include "apm.h"
+#include "ksysguardd.h"
+
+static int ApmFD, BattFill, BattTime;
+
+#define APMDEV "/dev/apm"
+
+/*
+================================ public part =================================
+*/
+
+void
+initApm(struct SensorModul* sm)
+{
+ if ((ApmFD = open(APMDEV, O_RDONLY)) < 0)
+ return;
+
+ if (updateApm() < 0)
+ return;
+
+ registerMonitor("apm/batterycharge", "integer", printApmBatFill,
+ printApmBatFillInfo, sm);
+ registerMonitor("apm/remainingtime", "integer", printApmBatTime,
+ printApmBatTimeInfo, sm);
+}
+
+void
+exitApm(void)
+{
+ removeMonitor("apm/batterycharge");
+ removeMonitor("apm/remainingtime");
+
+ close(ApmFD);
+}
+
+int
+updateApm(void)
+{
+ int retval;
+ struct apm_power_info info;
+ retval = ioctl(ApmFD, APM_IOC_GETPOWER, &info);
+
+ BattFill = info.battery_life;
+ BattTime = info.minutes_left;
+
+ return retval;
+}
+
+void
+printApmBatFill(const char* c)
+{
+ fprintf(CurrentClient, "%d\n", BattFill);
+}
+
+void
+printApmBatFillInfo(const char* c)
+{
+ fprintf(CurrentClient, "Battery charge\t0\t100\t%%\n");
+}
+
+void
+printApmBatTime(const char* c)
+{
+ fprintf(CurrentClient, "%d\n", BattTime);
+}
+
+void
+printApmBatTimeInfo(const char* c)
+{
+ fprintf(CurrentClient, "Remaining battery time\t0\t0\tmin\n");
+}
+
diff --git a/ksysguard/ksysguardd/NetBSD/apm.h b/ksysguard/ksysguardd/NetBSD/apm.h
new file mode 100644
index 000000000..4e3c0c0d3
--- /dev/null
+++ b/ksysguard/ksysguardd/NetBSD/apm.h
@@ -0,0 +1,34 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _apm_h_
+#define _apm_h_
+
+void initApm(struct SensorModul* sm);
+void exitApm(void);
+
+int updateApm(void);
+
+void printApmBatFill(const char*);
+void printApmBatFillInfo(const char*);
+void printApmBatTime(const char*);
+void printApmBatTimeInfo(const char*);
+
+#endif
diff --git a/ksysguard/ksysguardd/NetBSD/diskstat.c b/ksysguard/ksysguardd/NetBSD/diskstat.c
new file mode 100644
index 000000000..818eee1d4
--- /dev/null
+++ b/ksysguard/ksysguardd/NetBSD/diskstat.c
@@ -0,0 +1,249 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/ucred.h>
+#include <sys/mount.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "Command.h"
+#include "ccont.h"
+#include "diskstat.h"
+#include "ksysguardd.h"
+
+typedef struct {
+ char device[256];
+ char mntpnt[256];
+ long blocks;
+ long bfree;
+ long bused;
+ int bused_percent;
+} DiskInfo;
+
+static CONTAINER DiskStatList = 0;
+static struct SensorModul* DiskStatSM;
+
+char *getMntPnt(const char *cmd)
+{
+ static char device[1025];
+ char *ptr;
+
+ memset(device, 0, sizeof(device));
+ sscanf(cmd, "partitions%1024s", device);
+
+ ptr = (char *)rindex(device, '/');
+ *ptr = '\0';
+
+ return (char *)device;
+}
+
+int numMntPnt(void)
+{
+ struct statfs *fs_info;
+ int i, n, counter = 0;
+
+ n = getmntinfo(&fs_info, MNT_WAIT);
+ for (i = 0; i < n; i++)
+ if (strcmp(fs_info[i].f_fstypename, "procfs") && strcmp(fs_info[i].f_fstypename, "swap") && strcmp(fs_info[i].f_fstypename, "devfs"))
+ counter++;
+
+ return counter;
+}
+
+/* ------------------------------ public part --------------------------- */
+
+void initDiskStat(struct SensorModul* sm)
+{
+ char monitor[1024];
+ DiskInfo* disk_info;
+
+ DiskStatList = new_ctnr();
+ DiskStatSM = sm;
+
+ updateDiskStat();
+
+ registerMonitor("partitions/list", "listview", printDiskStat, printDiskStatInfo, DiskStatSM);
+
+ for (disk_info = first_ctnr(DiskStatList); disk_info; disk_info = next_ctnr(DiskStatList)) {
+ snprintf(monitor, sizeof(monitor), "partitions%s/usedspace", disk_info->mntpnt);
+ registerMonitor(monitor, "integer", printDiskStatUsed, printDiskStatUsedInfo, DiskStatSM);
+ snprintf(monitor, sizeof(monitor), "partitions%s/freespace", disk_info->mntpnt);
+ registerMonitor(monitor, "integer", printDiskStatFree, printDiskStatFreeInfo, DiskStatSM);
+ snprintf(monitor, sizeof(monitor), "partitions%s/filllevel", disk_info->mntpnt);
+ registerMonitor(monitor, "integer", printDiskStatPercent, printDiskStatPercentInfo, DiskStatSM);
+ }
+}
+
+void checkDiskStat(void)
+{
+ if (numMntPnt() != level_ctnr(DiskStatList)) {
+ /* a filesystem was mounted or unmounted
+ so we do a reset */
+ exitDiskStat();
+ initDiskStat(DiskStatSM);
+ }
+}
+
+void exitDiskStat(void)
+{
+ DiskInfo *disk_info;
+ char monitor[1024];
+
+ removeMonitor("partitions/list");
+
+ for (disk_info = first_ctnr(DiskStatList); disk_info; disk_info = next_ctnr(DiskStatList)) {
+ snprintf(monitor, sizeof(monitor), "partitions%s/usedspace", disk_info->mntpnt);
+ removeMonitor(monitor);
+ snprintf(monitor, sizeof(monitor), "partitions%s/freespace", disk_info->mntpnt);
+ removeMonitor(monitor);
+ snprintf(monitor, sizeof(monitor), "partitions%s/filllevel", disk_info->mntpnt);
+ removeMonitor(monitor);
+ }
+
+ destr_ctnr(DiskStatList, free);
+}
+
+int updateDiskStat(void)
+{
+ struct statfs *fs_info;
+ struct statfs fs;
+ float percent;
+ int i, mntcount;
+ DiskInfo *disk_info;
+
+ /* let's hope there is no difference between the DiskStatList and
+ the number of mounted filesystems */
+ for (i = level_ctnr(DiskStatList); i >= 0; --i)
+ free(pop_ctnr(DiskStatList));
+
+ mntcount = getmntinfo(&fs_info, MNT_WAIT);
+
+ for (i = 0; i < mntcount; i++) {
+ fs = fs_info[i];
+ if (strcmp(fs.f_fstypename, "procfs") && strcmp(fs.f_fstypename, "devfs") && strcmp(fs.f_fstypename, "devfs")) {
+ percent = (((float)fs.f_blocks - (float)fs.f_bfree)/(float)fs.f_blocks);
+ percent = percent * 100;
+ if ((disk_info = (DiskInfo *)malloc(sizeof(DiskInfo))) == NULL) {
+ continue;
+ }
+ memset(disk_info, 0, sizeof(DiskInfo));
+ strlcpy(disk_info->device, fs.f_mntfromname, sizeof(disk_info->device));
+ if (!strcmp(fs.f_mntonname, "/")) {
+ strncpy(disk_info->mntpnt, "/root", 6);
+ } else {
+ strlcpy(disk_info->mntpnt, fs.f_mntonname, sizeof(disk_info->mntpnt));
+ }
+ disk_info->blocks = fs.f_blocks;
+ disk_info->bfree = fs.f_bfree;
+ disk_info->bused = (fs.f_blocks - fs.f_bfree);
+ disk_info->bused_percent = (int)percent;
+
+ push_ctnr(DiskStatList, disk_info);
+ }
+ }
+
+ return 0;
+}
+
+void printDiskStat(const char* cmd)
+{
+ DiskInfo* disk_info;
+
+ for (disk_info = first_ctnr(DiskStatList); disk_info; disk_info = next_ctnr(DiskStatList)) {
+ fprintf(CurrentClient, "%s\t%ld\t%ld\t%ld\t%d\t%s\n",
+ disk_info->device,
+ disk_info->blocks,
+ disk_info->bused,
+ disk_info->bfree,
+ disk_info->bused_percent,
+ disk_info->mntpnt);
+ }
+
+ fprintf(CurrentClient, "\n");
+}
+
+void printDiskStatInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Device\tBlocks\tUsed\tAvailable\tUsed %%\tMountPoint\nM\tD\tD\tD\td\ts\n");
+}
+
+void printDiskStatUsed(const char* cmd)
+{
+ DiskInfo* disk_info;
+ char *mntpnt = (char *)getMntPnt(cmd);
+
+ for (disk_info = first_ctnr(DiskStatList); disk_info; disk_info = next_ctnr(DiskStatList)) {
+ if (!strcmp(mntpnt, disk_info->mntpnt)) {
+ fprintf(CurrentClient, "%ld\n", disk_info->bused);
+ }
+ }
+
+ fprintf(CurrentClient, "\n");
+}
+
+void printDiskStatUsedInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Used Blocks\t0\t-\tBlocks\n");
+}
+
+void printDiskStatFree(const char* cmd)
+{
+ DiskInfo* disk_info;
+ char *mntpnt = (char *)getMntPnt(cmd);
+
+ for (disk_info = first_ctnr(DiskStatList); disk_info; disk_info = next_ctnr(DiskStatList)) {
+ if (!strcmp(mntpnt, disk_info->mntpnt)) {
+ fprintf(CurrentClient, "%ld\n", disk_info->bfree);
+ }
+ }
+
+ fprintf(CurrentClient, "\n");
+}
+
+void printDiskStatFreeInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Free Blocks\t0\t-\tBlocks\n");
+}
+
+void printDiskStatPercent(const char* cmd)
+{
+ DiskInfo* disk_info;
+ char *mntpnt = (char *)getMntPnt(cmd);
+
+ for (disk_info = first_ctnr(DiskStatList); disk_info; disk_info = next_ctnr(DiskStatList)) {
+ if (!strcmp(mntpnt, disk_info->mntpnt)) {
+ fprintf(CurrentClient, "%d\n", disk_info->bused_percent);
+ }
+ }
+
+ fprintf(CurrentClient, "\n");
+}
+
+void printDiskStatPercentInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Used Blocks\t0\t100\t%%\n");
+}
diff --git a/ksysguard/ksysguardd/NetBSD/diskstat.h b/ksysguard/ksysguardd/NetBSD/diskstat.h
new file mode 100644
index 000000000..06f247837
--- /dev/null
+++ b/ksysguard/ksysguardd/NetBSD/diskstat.h
@@ -0,0 +1,40 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _diskstat_h_
+#define _diskstat_h_
+
+void initDiskStat(struct SensorModul* sm);
+void exitDiskStat(void);
+
+int updateDiskStat(void);
+void checkDiskStat(void);
+
+void printDiskStat(const char* cmd);
+void printDiskStatInfo(const char* cmd);
+
+void printDiskStatUsed(const char* cmd);
+void printDiskStatUsedInfo(const char* cmd);
+void printDiskStatFree(const char* cmd);
+void printDiskStatFreeInfo(const char* cmd);
+void printDiskStatPercent(const char* cmd);
+void printDiskStatPercentInfo(const char* cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/NetBSD/loadavg.c b/ksysguard/ksysguardd/NetBSD/loadavg.c
new file mode 100644
index 000000000..53eb9fc4e
--- /dev/null
+++ b/ksysguard/ksysguardd/NetBSD/loadavg.c
@@ -0,0 +1,96 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "Command.h"
+#include "ksysguardd.h"
+#include "loadavg.h"
+
+static double LoadAvg[3];
+
+/*
+================================ public part =================================
+*/
+
+void
+initLoadAvg(struct SensorModul* sm)
+{
+ if (updateLoadAvg() < 0)
+ return;
+
+ registerMonitor("cpu/loadavg1", "float", printLoadAvg1,
+ printLoadAvg1Info, sm);
+ registerMonitor("cpu/loadavg5", "float", printLoadAvg5,
+ printLoadAvg5Info, sm);
+ registerMonitor("cpu/loadavg15", "float", printLoadAvg15,
+ printLoadAvg15Info, sm);
+}
+
+void
+exitLoadAvg(void)
+{
+ removeMonitor("cpu/loadavg1");
+ removeMonitor("cpu/loadavg5");
+ removeMonitor("cpu/loadavg15");
+}
+
+int
+updateLoadAvg(void)
+{
+ return getloadavg(LoadAvg, 3);
+}
+
+void
+printLoadAvg1(const char* c)
+{
+ fprintf(CurrentClient, "%f\n", LoadAvg[0]);
+}
+
+void
+printLoadAvg1Info(const char* c)
+{
+ fprintf(CurrentClient, "Load average 1 min\t0\t0\t\n");
+}
+
+void
+printLoadAvg5(const char* c)
+{
+ fprintf(CurrentClient, "%f\n", LoadAvg[1]);
+}
+
+void
+printLoadAvg5Info(const char* c)
+{
+ fprintf(CurrentClient, "Load average 5 min\t0\t0\t\n");
+}
+
+void
+printLoadAvg15(const char* c)
+{
+ fprintf(CurrentClient, "%f\n", LoadAvg[2]);
+}
+
+void
+printLoadAvg15Info(const char* c)
+{
+ fprintf(CurrentClient, "Load average 15 min\t0\t0\t\n");
+}
diff --git a/ksysguard/ksysguardd/NetBSD/loadavg.h b/ksysguard/ksysguardd/NetBSD/loadavg.h
new file mode 100644
index 000000000..801e4ef8d
--- /dev/null
+++ b/ksysguard/ksysguardd/NetBSD/loadavg.h
@@ -0,0 +1,36 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _loadavg_h_
+#define _loadavg_h_
+
+void initLoadAvg(struct SensorModul* sm);
+void exitLoadAvg(void);
+
+int updateLoadAvg(void);
+
+void printLoadAvg1(const char*);
+void printLoadAvg1Info(const char*);
+void printLoadAvg5(const char*);
+void printLoadAvg5Info(const char*);
+void printLoadAvg15(const char*);
+void printLoadAvg15Info(const char*);
+
+#endif
diff --git a/ksysguard/ksysguardd/NetBSD/logfile.c b/ksysguard/ksysguardd/NetBSD/logfile.c
new file mode 100644
index 000000000..3b07ad8ac
--- /dev/null
+++ b/ksysguard/ksysguardd/NetBSD/logfile.c
@@ -0,0 +1,175 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Command.h"
+#include "ccont.h"
+#include "conf.h"
+#include "ksysguardd.h"
+#include "logfile.h"
+
+static CONTAINER LogFiles = 0;
+static unsigned long counter = 1;
+
+typedef struct {
+ char name[256];
+ FILE* fh;
+ unsigned long id;
+} LogFileEntry;
+
+extern CONTAINER LogFileList;
+
+/*
+================================ public part =================================
+*/
+
+void initLogFile(struct SensorModul* sm)
+{
+ char monitor[1024];
+ ConfigLogFile *entry;
+
+ registerCommand("logfile_register", registerLogFile);
+ registerCommand("logfile_unregister", unregisterLogFile);
+ registerCommand("logfile_registered", printRegistered);
+
+ for (entry = first_ctnr(LogFileList); entry; entry = next_ctnr(LogFileList))
+ {
+ FILE* fp;
+
+ /* register the log file if we can actually read the file. */
+ if ((fp = fopen(entry->path, "r")) != NULL)
+ {
+ fclose(fp);
+ snprintf(monitor, 1024, "logfiles/%s", entry->name);
+ registerMonitor(monitor, "logfile", printLogFile,
+ printLogFileInfo, sm);
+ }
+ }
+
+ LogFiles = new_ctnr();
+}
+
+void exitLogFile(void)
+{
+ destr_ctnr(LogFiles, free);
+}
+
+void printLogFile(const char* cmd)
+{
+ char line[1024];
+ unsigned long id;
+ int i;
+ char ch;
+ LogFileEntry *entry;
+
+ sscanf(cmd, "%*s %lu", &id);
+
+ for (entry = first_ctnr(LogFiles); entry; entry = next_ctnr(LogFiles)) {
+ if (entry->id == id) {
+ while (fgets(line, sizeof(line), entry->fh) != NULL) {
+ fprintf(CurrentClient, "%s", line);
+ }
+ clearerr(entry->fh);
+ }
+ }
+
+ fprintf(CurrentClient, "\n");
+}
+
+void printLogFileInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "LogFile\n");
+}
+
+void registerLogFile(const char* cmd)
+{
+ char name[257];
+ FILE* file;
+ LogFileEntry *entry;
+ ConfigLogFile *conf;
+
+ memset(name, 0, sizeof(name));
+ sscanf(cmd, "%*s %256s", name);
+
+ for (conf = first_ctnr(LogFileList); conf; conf = next_ctnr(LogFileList)) {
+ if (!strcmp(conf->name, name)) {
+ if ((file = fopen(conf->path, "r")) == NULL) {
+ print_error("fopen()");
+ fprintf(CurrentClient, "0\n");
+ return;
+ }
+
+ fseek(file, 0, SEEK_END);
+
+ if ((entry = (LogFileEntry *)malloc(sizeof(LogFileEntry))) == NULL) {
+ print_error("malloc()");
+ fprintf(CurrentClient, "0\n");
+ return;
+ }
+
+ entry->fh = file;
+ strlcpy(entry->name, conf->name, sizeof(entry->name));
+ entry->id = counter;
+
+ push_ctnr(LogFiles, entry);
+
+ fprintf(CurrentClient, "%lu\n", counter);
+ counter++;
+
+ return;
+ }
+ }
+
+ fprintf(CurrentClient, "0\n");
+}
+
+void unregisterLogFile(const char* cmd)
+{
+ unsigned long id;
+ LogFileEntry *entry;
+
+ sscanf(cmd, "%*s %lu", &id);
+
+ for (entry = first_ctnr(LogFiles); entry; entry = next_ctnr(LogFiles)) {
+ if (entry->id == id) {
+ fclose(entry->fh);
+ free(remove_ctnr(LogFiles));
+ fprintf(CurrentClient, "\n");
+ return;
+ }
+ }
+
+ fprintf(CurrentClient, "\n");
+}
+
+void printRegistered(const char* cmd)
+{
+ LogFileEntry *entry;
+
+ for (entry = first_ctnr(LogFiles); entry; entry = next_ctnr(LogFiles))
+ fprintf(CurrentClient, "%s:%lu\n", entry->name, entry->id);
+
+ fprintf(CurrentClient, "\n");
+}
diff --git a/ksysguard/ksysguardd/NetBSD/logfile.h b/ksysguard/ksysguardd/NetBSD/logfile.h
new file mode 100644
index 000000000..45ade9013
--- /dev/null
+++ b/ksysguard/ksysguardd/NetBSD/logfile.h
@@ -0,0 +1,36 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _logfile_h_
+#define _logfile_h_
+
+void initLogFile(struct SensorModul* sm);
+void exitLogFile(void);
+
+void printLogFile(const char* cmd);
+void printLogFileInfo(const char* cmd);
+
+void registerLogFile(const char* cmd);
+void unregisterLogFile(const char* cmd);
+
+/* debug command */
+void printRegistered(const char* cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/NetBSD/netdev.c b/ksysguard/ksysguardd/NetBSD/netdev.c
new file mode 100644
index 000000000..477acc40e
--- /dev/null
+++ b/ksysguard/ksysguardd/NetBSD/netdev.c
@@ -0,0 +1,304 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/socket.h>
+
+#include <net/route.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+
+#include <ifaddrs.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Command.h"
+#include "ksysguardd.h"
+#include "netdev.h"
+
+
+#define I_bytes 0
+#define I_packs 1
+#define I_errs 2
+#define I_mcasts 3
+#define I_lost 4
+
+typedef struct {
+ char name[32];
+ u_long recv[5], Drecv[5], sent[5], Dsent[5];
+} NetDevInfo;
+
+#define LEN(X) (sizeof(X)/sizeof(X[0]))
+
+#define MAXNETDEVS 64
+static NetDevInfo NetDevs[MAXNETDEVS], newval[MAXNETDEVS];
+static int NetDevCnt = 0;
+static struct SensorModul *NetDevSM;
+
+/* Read the system's traffic registers.
+ * Merely count the IFs if countp nonzero.
+ * Returns count of IFs read, or -1; the data are written into newval.
+ * Based on getifaddrs source; getifaddrs itself seems to
+ * compile incorrectly, omitting the traffic data. (It also
+ * does things this doesn't need, thus this is slightly more efficient.)
+ */
+static int readSys(int countp)
+{
+ size_t len;
+ char *bfr, *ptr;
+ struct rt_msghdr *rtm;
+ NetDevInfo *nv;
+ static int mib[] = {
+ /* see sysctl(3): */
+ CTL_NET,
+ PF_ROUTE,
+ 0, /* `currently always 0' */
+ 0, /* `may be set to 0 to select all address families' */
+ NET_RT_IFLIST,
+ 0 /* ignored but six levels are needed */
+ };
+
+ if (-1==sysctl(mib, LEN(mib), NULL, &len, NULL, 0))
+ return -1;
+ if (!(bfr = malloc(len)))
+ return -1;
+ if (-1==sysctl(mib, LEN(mib), bfr, &len, NULL, 0)) {
+ free(bfr);
+ return -1;
+ }
+ nv = newval;
+ for (ptr=bfr; ptr<bfr+len; ptr+=rtm->rtm_msglen) {
+ struct if_msghdr *ifm;
+
+ rtm = (void*)ptr; /* chg ptr type to router msg */
+
+ if (rtm->rtm_version != RTM_VERSION) {
+ continue;
+ }
+
+ if (rtm->rtm_type != RTM_IFINFO) {
+ continue;
+ }
+
+ ifm = (void*)rtm; /* chg ptr type to interface msg */
+ if (!(ifm->ifm_flags & IFF_UP)) {
+ continue;
+ }
+
+ if (!countp) {
+ /* a sdl is concat'd to the if msg */
+ struct sockaddr_dl *sdl = (void*)(ifm+1);
+
+ /* copy and terminate the name */
+ /*fixme: check for overruns */
+ memcpy(nv->name, sdl->sdl_data, sdl->sdl_nlen);
+ nv->name[sdl->sdl_nlen] = 0;
+
+ /* copy the data */
+ nv->recv[I_bytes] = ifm->ifm_data.ifi_ibytes;
+ nv->recv[I_packs] = ifm->ifm_data.ifi_ipackets;
+ nv->recv[I_errs] = ifm->ifm_data.ifi_ierrors;
+ nv->recv[I_mcasts] = ifm->ifm_data.ifi_imcasts;
+ nv->recv[I_lost] = ifm->ifm_data.ifi_iqdrops;
+ nv->sent[I_bytes] = ifm->ifm_data.ifi_obytes;
+ nv->sent[I_packs] = ifm->ifm_data.ifi_opackets;
+ nv->sent[I_errs] = ifm->ifm_data.ifi_oerrors;
+ nv->sent[I_mcasts] = ifm->ifm_data.ifi_omcasts;
+ nv->sent[I_lost] = ifm->ifm_data.ifi_collisions;
+ }
+
+ /*fixme: guard against buffer overrun */
+ nv++;
+ }
+ free(bfr);
+ return nv-newval;
+}
+
+
+/* ------------------------------ public part --------------------------- */
+
+static void prVal(const char*, int);
+void printNetDevRecv(const char *cmd) { prVal(cmd,0); }
+void printNetDevSent(const char *cmd) { prVal(cmd,1); }
+
+static void prInfo(const char*, int);
+void printNetDevRecvInfo(const char *cmd) { prInfo(cmd,0); }
+void printNetDevSentInfo(const char *cmd) { prInfo(cmd,1); }
+
+static struct {
+ char *label;
+ cmdExecutor read, inform;
+ struct {
+ char *label, *info;
+ int index;
+ } op[5];
+} opTable[] = {
+ {"receiver",
+ printNetDevRecv, printNetDevRecvInfo,
+ {{"data", "Received Data\t0\t0\tB/s\n", I_bytes},
+ {"packets", "Received Packets\t0\t0\tHz\n", I_packs},
+ {"errors", "Receiver Errors\t0\t0\tHz\n", I_errs},
+ {"multicast", "Received Multicast Packets\t0\t0\tHz\n", I_mcasts},
+ {"drops", "Receiver Drops\t0\t0\tHz\n", I_lost}}},
+ {"transmitter",
+ printNetDevSent, printNetDevSentInfo,
+ {{"data", "Sent Data\t0\t0\tB/s\n", I_bytes},
+ {"packets", "Sent Packets\t0\t0\tHz\n", I_packs},
+ {"errors", "Transmitter Errors\t0\t0\tHz\n", I_errs},
+ {"multicast", "Sent Multicast Packets\t0\t0\tHz\n", I_mcasts},
+ {"collisions", "Transmitter Collisions\t0\t0\tHz\n", I_lost}}}
+};
+
+
+static void prVal(const char *cmd, int N) {
+ char *p, *q, *r;
+ int i, d;
+
+ if (!(p=rindex(cmd, '/')))
+ return;
+ *p=0;
+ q=rindex(cmd, '/');
+ *q=0;
+ r=rindex(cmd, '/');
+ r++;
+ for (d=NetDevCnt; d--; )
+ if (!strcmp(r, NetDevs[d].name))
+ break;
+ *q=*p='/';
+
+ if (-1 == d) return;
+
+ p++;
+ for (i=0; i<LEN(opTable[0].op); i++)
+ if (!strcmp(p, opTable[N].op[i].label))
+ fprintf(CurrentClient, "%lu",
+ /*fixme: ugly and presumptuous */
+ (N?NetDevs[d].Dsent:NetDevs[d].Drecv)[opTable[N].op[i].index]);
+ fprintf(CurrentClient, "\n");
+}
+
+
+static void prInfo(const char *cmd, int N) {
+ char *p, *q;
+ int i;
+
+ if (!(p=rindex(cmd, '/'))) return;
+ p++;
+
+ q = p+strlen(p)-1;
+ if ('?' != *q) return;
+ *q=0;
+
+ for (i=0; i<LEN(opTable[0].op); i++)
+ if (!strcmp(p, opTable[N].op[i].label))
+ fputs(opTable[N].op[i].info, CurrentClient);
+ *q='?';
+}
+
+
+
+static void NDreg (int setp)
+{
+ int i;
+
+ for (i = 0; i<NetDevCnt; i++) {
+ int j;
+
+ for (j=0; j<LEN(opTable); j++) {
+ int k;
+
+ for (k=0; k<LEN(opTable[0].op); k++) {
+ char buffer[1024];
+
+ snprintf(buffer, sizeof(buffer),
+ "network/interfaces/%s/%s/%s",
+ NetDevs[i].name,
+ opTable[j].label,
+ opTable[j].op[k].label);
+
+ /* printf("%d %d %d %s\n",i,j,k,buffer); */
+
+ if (setp)
+ registerMonitor(buffer,
+ "integer",
+ opTable[j].read,
+ opTable[j].inform, NetDevSM);
+ else
+ removeMonitor(buffer);
+ }
+
+ }
+ }
+}
+
+void initNetDev(struct SensorModul* sm) {
+ int i;
+
+ NetDevSM = sm;
+
+ updateNetDev();
+
+ for (i=LEN(NetDevs); i--;) {
+ strcpy(NetDevs[i].name, newval[i].name);
+ }
+
+ NDreg(!0);
+}
+
+
+void exitNetDev(void) {
+ NDreg(0);
+}
+
+void updateNetDev(void) {
+ NetDevInfo *p, *q;
+ int n;
+
+ if (-1==(n = readSys(0)))
+ return;
+
+ NetDevCnt = n;
+ /*fixme: assumes the interfaces are in the same order each time */
+ for (p=NetDevs, q=newval; n--; p++, q++) {
+ int i;
+ /* calculate deltas */
+ for (i=0; i<5; i++) {
+ p->Drecv[i] = q->recv[i]-p->recv[i];
+ p->recv[i] = q->recv[i];
+ p->Dsent[i] = q->sent[i]-p->sent[i];
+ p->sent[i] = q->sent[i];
+
+ }
+ }
+}
+
+void checkNetDev(void) {
+ if (readSys(!0) != NetDevCnt) {
+ /* interface has been added or removed
+ so we do a reset */
+ exitNetDev();
+ initNetDev(NetDevSM);
+ }
+}
+
+
+/* eof */
diff --git a/ksysguard/ksysguardd/NetBSD/netdev.h b/ksysguard/ksysguardd/NetBSD/netdev.h
new file mode 100644
index 000000000..4287c9203
--- /dev/null
+++ b/ksysguard/ksysguardd/NetBSD/netdev.h
@@ -0,0 +1,35 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _netdev_h_
+#define _netdev_h_
+
+void initNetDev(struct SensorModul* sm);
+void exitNetDev(void);
+
+void updateNetDev(void);
+void checkNetDev(void);
+
+void printNetDevRecBytes(const char* cmd);
+void printNetDevRecBytesInfo(const char* cmd);
+void printNetDevSentBytes(const char* cmd);
+void printNetDevSentBytesInfo(const char* cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/OpenBSD/Makefile.am b/ksysguard/ksysguardd/OpenBSD/Makefile.am
new file mode 100644
index 000000000..78d97e293
--- /dev/null
+++ b/ksysguard/ksysguardd/OpenBSD/Makefile.am
@@ -0,0 +1,6 @@
+AM_CFLAGS = -Wall
+
+INCLUDES = -I$(srcdir)/../../CContLib -I$(srcdir)/..
+
+noinst_LIBRARIES = libksysguardd.a
+libksysguardd_a_SOURCES = cpu.c memory.c
diff --git a/ksysguard/ksysguardd/OpenBSD/cpu.c b/ksysguard/ksysguardd/OpenBSD/cpu.c
new file mode 100644
index 000000000..3d1535ffe
--- /dev/null
+++ b/ksysguard/ksysguardd/OpenBSD/cpu.c
@@ -0,0 +1,209 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/dkstat.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "cpu.h"
+#include "Command.h"
+#include "ksysguardd.h"
+
+long percentages(int cnt, int *out, long *new, long *old, long *diffs);
+
+unsigned long cp_time_offset;
+
+long cp_time[CPUSTATES];
+long cp_old[CPUSTATES];
+long cp_diff[CPUSTATES];
+int cpu_states[CPUSTATES];
+
+void
+initCpuInfo(struct SensorModul* sm)
+{
+ /* Total CPU load */
+ registerMonitor("cpu/user", "integer", printCPUUser,
+ printCPUUserInfo, sm);
+ registerMonitor("cpu/nice", "integer", printCPUNice,
+ printCPUNiceInfo, sm);
+ registerMonitor("cpu/sys", "integer", printCPUSys,
+ printCPUSysInfo, sm);
+ registerMonitor("cpu/idle", "integer", printCPUIdle,
+ printCPUIdleInfo, sm);
+ registerMonitor("cpu/interrupt", "integer", printCPUInterrupt,
+ printCPUInterruptInfo, sm);
+
+ updateCpuInfo();
+}
+
+void
+exitCpuInfo(void)
+{
+}
+
+int
+updateCpuInfo(void)
+{
+ static int cp_time_mib[] = {CTL_KERN, KERN_CPTIME};
+ size_t size;
+ size=sizeof(cp_time);
+ sysctl(cp_time_mib, 2, &cp_time, &size, NULL, 0);
+ percentages(CPUSTATES, cpu_states, cp_time, cp_old, cp_diff);
+ return (0);
+}
+
+void
+printCPUUser(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", cpu_states[CP_USER]/10);
+}
+
+void
+printCPUUserInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "CPU User Load\t0\t100\t%%\n");
+}
+
+void
+printCPUNice(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", cpu_states[CP_NICE]/10);
+}
+
+void
+printCPUNiceInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "CPU Nice Load\t0\t100\t%%\n");
+}
+
+void
+printCPUSys(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", cpu_states[CP_SYS]/10);
+}
+
+void
+printCPUSysInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "CPU System Load\t0\t100\t%%\n");
+}
+
+void
+printCPUIdle(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", cpu_states[CP_IDLE]/10);
+}
+
+void
+printCPUIdleInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "CPU Idle Load\t0\t100\t%%\n");
+}
+
+void
+printCPUInterrupt(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", cpu_states[CP_INTR]/10);
+}
+
+void
+printCPUInterruptInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "CPU Interrupt Load\t0\t100\t%%\n");
+}
+
+/* The part ripped from top... */
+/*
+ * Top users/processes display for Unix
+ * Version 3
+ *
+ * This program may be freely redistributed,
+ * but this entire comment MUST remain intact.
+ *
+ * Copyright (c) 1984, 1989, William LeFebvre, Rice University
+ * Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University
+ */
+
+/*
+ * percentages(cnt, out, new, old, diffs) - calculate percentage change
+ * between array "old" and "new", putting the percentages i "out".
+ * "cnt" is size of each array and "diffs" is used for scratch space.
+ * The array "old" is updated on each call.
+ * The routine assumes modulo arithmetic. This function is especially
+ * useful on BSD mchines for calculating cpu state percentages.
+ */
+
+long percentages(cnt, out, new, old, diffs)
+
+int cnt;
+int *out;
+register long *new;
+register long *old;
+long *diffs;
+
+{
+ register int i;
+ register long change;
+ register long total_change;
+ register long *dp;
+ long half_total;
+
+ /* initialization */
+ total_change = 0;
+ dp = diffs;
+
+ /* calculate changes for each state and the overall change */
+ for (i = 0; i < cnt; i++)
+ {
+ if ((change = *new - *old) < 0)
+ {
+ /* this only happens when the counter wraps */
+ change = (int)
+ ((unsigned long)*new-(unsigned long)*old);
+ }
+ total_change += (*dp++ = change);
+ *old++ = *new++;
+ }
+
+ /* avoid divide by zero potential */
+ if (total_change == 0)
+ {
+ total_change = 1;
+ }
+
+ /* calculate percentages based on overall change, rounding up */
+ half_total = total_change / 2l;
+
+ /* Do not divide by 0. Causes Floating point exception */
+ if(total_change) {
+ for (i = 0; i < cnt; i++)
+ {
+ *out++ = (int)((*diffs++ * 1000 + half_total) / total_change);
+ }
+ }
+
+ /* return the total in case the caller wants to use it */
+ return(total_change);
+}
diff --git a/ksysguard/ksysguardd/OpenBSD/cpu.h b/ksysguard/ksysguardd/OpenBSD/cpu.h
new file mode 100644
index 000000000..a1188cd82
--- /dev/null
+++ b/ksysguard/ksysguardd/OpenBSD/cpu.h
@@ -0,0 +1,51 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _cpuinfo_h_
+#define _cpuinfo_h_
+
+struct SensorModul;
+
+void initCpuInfo(struct SensorModul* sm);
+void exitCpuInfo(void);
+
+int updateCpuInfo(void);
+
+void printCPUUser(const char* cmd);
+void printCPUUserInfo(const char* cmd);
+void printCPUNice(const char* cmd);
+void printCPUNiceInfo(const char* cmd);
+void printCPUSys(const char* cmd);
+void printCPUSysInfo(const char* cmd);
+void printCPUIdle(const char* cmd);
+void printCPUIdleInfo(const char* cmd);
+void printCPUInterrupt(const char* cmd);
+void printCPUInterruptInfo(const char* cmd);
+void printCPUxUser(const char* cmd);
+void printCPUxUserInfo(const char* cmd);
+void printCPUxNice(const char* cmd);
+void printCPUxNiceInfo(const char* cmd);
+void printCPUxSys(const char* cmd);
+void printCPUxSysInfo(const char* cmd);
+void printCPUxIdle(const char* cmd);
+void printCPUxIdleInfo(const char* cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/OpenBSD/memory.c b/ksysguard/ksysguardd/OpenBSD/memory.c
new file mode 100644
index 000000000..aaf893268
--- /dev/null
+++ b/ksysguard/ksysguardd/OpenBSD/memory.c
@@ -0,0 +1,207 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+ Copyright (c) 1999-2000 Hans Petter Bieker <bieker@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/dkstat.h>
+#include <sys/swap.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "Command.h"
+#include "memory.h"
+#include "ksysguardd.h"
+
+static size_t Total = 0;
+static size_t MFree = 0;
+static size_t Active = 0;
+static size_t InActive = 0;
+static size_t STotal = 0;
+static size_t SFree = 0;
+static size_t SUsed = 0;
+static int pageshift = 0;
+
+/* define pagetok in terms of pageshift */
+#define pagetok(size) ((size) << pageshift)
+
+void swapmode(int *used, int *total);
+
+void
+initMemory(struct SensorModul* sm)
+{
+ int pagesize;
+ static int physmem_mib[] = { CTL_HW, HW_PHYSMEM };
+ size_t size;
+ /* get the page size with "getpagesize" and calculate pageshift from
+ * it */
+ pagesize = getpagesize();
+ pageshift = 0;
+ while (pagesize > 1) {
+ pageshift++;
+ pagesize >>= 1;
+ }
+ size = sizeof(Total);
+ sysctl(physmem_mib, 2, &Total, &size, NULL, 0);
+ Total /= 1024;
+ swapmode(&SUsed, &STotal);
+
+ registerMonitor("mem/physical/free", "integer", printMFree, printMFreeInfo, sm);
+ registerMonitor("mem/physical/active", "integer", printActive, printActiveInfo, sm);
+ registerMonitor("mem/physical/inactive", "integer", printInActive, printInActiveInfo, sm);
+ registerMonitor("mem/swap/free", "integer", printSwapFree, printSwapFreeInfo, sm);
+ registerMonitor("mem/swap/used", "integer", printSwapUsed, printSwapUsedInfo, sm);
+}
+
+void
+exitMemory(void)
+{
+}
+
+int
+updateMemory(void)
+{
+ static int vmtotal_mib[] = {CTL_VM, VM_METER};
+ size_t size;
+ struct vmtotal vmtotal;
+ size = sizeof(vmtotal);
+
+ if (sysctl(vmtotal_mib, 2, &vmtotal, &size, NULL, 0) < 0)
+ return -1;
+
+ MFree = pagetok(vmtotal.t_free);
+ MFree /= 1024;
+ Active = pagetok(vmtotal.t_arm);
+ Active /= 1024;
+ InActive = pagetok(vmtotal.t_rm);
+ InActive /= 1024;
+ InActive -= Active;
+
+ swapmode(&SUsed, &STotal);
+ SFree = STotal - SUsed;
+ return 0;
+}
+
+void
+printMFree(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", MFree);
+}
+
+void
+printMFreeInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Free Memory\t0\t%d\tKB\n", Total);
+}
+
+void
+printActive(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", Active);
+}
+
+void
+printActiveInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Active Memory\t0\t%d\tKB\n", Total);
+}
+
+void
+printInActive(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", InActive);
+}
+
+void
+printInActiveInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "InActive Memory\t0\t%d\tKB\n", Total);
+}
+
+void
+printSwapUsed(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", SUsed);
+}
+
+void
+printSwapUsedInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Used Swap Memory\t0\t%d\tKB\n", STotal);
+}
+
+void
+printSwapFree(const char* cmd)
+{
+ fprintf(CurrentClient, "%d\n", SFree);
+}
+
+void
+printSwapFreeInfo(const char* cmd)
+{
+ fprintf(CurrentClient, "Free Swap Memory\t0\t%d\tKB\n", STotal);
+}
+
+/*
+This function swapmode was originally written by Tobias
+Weingartner <weingart@openbsd.org>
+
+Taken from OpenBSD top command
+*/
+void
+swapmode (int *used, int *total)
+{
+ int nswap, rnswap, i;
+ struct swapent *swdev;
+
+ *total = *used = 0;
+
+ /* Number of swap devices */
+ nswap = swapctl(SWAP_NSWAP, 0, 0);
+ if (nswap == 0)
+ return;
+
+ swdev = (struct swapent *) malloc(nswap * sizeof(*swdev));
+ if (swdev == NULL)
+ return;
+
+ rnswap = swapctl(SWAP_STATS, swdev, nswap);
+ if (rnswap == -1) {
+ free(swdev);
+ return;
+ }
+
+ /* if rnswap != nswap, then what? */
+
+ /* Total things up */
+ for (i = 0; i < nswap; i++) {
+ if (swdev[i].se_flags & SWF_ENABLE) {
+ *used += (swdev[i].se_inuse / (1024 / DEV_BSIZE));
+ *total += (swdev[i].se_nblks / (1024 / DEV_BSIZE));
+ }
+ }
+
+ free(swdev);
+}
diff --git a/ksysguard/ksysguardd/OpenBSD/memory.h b/ksysguard/ksysguardd/OpenBSD/memory.h
new file mode 100644
index 000000000..9cb11373a
--- /dev/null
+++ b/ksysguard/ksysguardd/OpenBSD/memory.h
@@ -0,0 +1,43 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _memory_h_
+#define _memory_h_
+
+struct SensorModul;
+
+void initMemory(struct SensorModul* sm);
+void exitMemory(void);
+
+int updateMemory(void);
+
+void printMFree(const char* cmd);
+void printMFreeInfo(const char* cmd);
+void printActive(const char* cmd);
+void printActiveInfo(const char* cmd);
+void printInActive(const char* cmd);
+void printInActiveInfo(const char* cmd);
+void printSwapUsed(const char* cmd);
+void printSwapUsedInfo(const char* cmd);
+void printSwapFree(const char* cmd);
+void printSwapFreeInfo(const char* cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/PWUIDCache.c b/ksysguard/ksysguardd/PWUIDCache.c
new file mode 100644
index 000000000..b0140e0a7
--- /dev/null
+++ b/ksysguard/ksysguardd/PWUIDCache.c
@@ -0,0 +1,114 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2000 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <pwd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include "ccont.h"
+
+#include "PWUIDCache.h"
+
+/* Cached values become invalid after 5 minutes */
+#define TIMEOUT 300
+
+typedef struct {
+ uid_t uid;
+ char* uName;
+ time_t tStamp;
+} CachedPWUID;
+
+static CONTAINER UIDCache = 0;
+static time_t lastCleanup = 0;
+
+void PWUIDCache_cleanup( void* c );
+
+static int uidCmp( void* p1, void* p2 )
+{
+ return ( ((CachedPWUID*)p1)->uid - ((CachedPWUID*)p2)->uid );
+}
+
+void PWUIDCache_cleanup( void* c )
+{
+ if ( c ) {
+ if ( ((CachedPWUID*)c)->uName )
+ free ( ((CachedPWUID*)c)->uName );
+ free ( c );
+ }
+}
+
+void initPWUIDCache()
+{
+ UIDCache = new_ctnr();
+}
+
+void exitPWUIDCache()
+{
+ destr_ctnr( UIDCache, PWUIDCache_cleanup );
+}
+
+const char* getCachedPWUID( uid_t uid )
+{
+ CachedPWUID key;
+ CachedPWUID* entry = 0;
+ long idx;
+ time_t stamp;
+
+ stamp = time( 0 );
+ if ( stamp - lastCleanup > TIMEOUT ) {
+ /* Cleanup cache entries every TIMEOUT seconds so that we
+ * don't pile tons of unused entries, and to make sure that
+ * our entries are not outdated. */
+ for ( entry = first_ctnr( UIDCache ); entry; entry = next_ctnr( UIDCache ) ) {
+ /* If a cache entry has not been updated for TIMEOUT
+ * seconds the entry is removed. */
+ if ( stamp - entry->tStamp > TIMEOUT )
+ PWUIDCache_cleanup( remove_ctnr( UIDCache ) );
+ }
+
+ lastCleanup = stamp;
+ }
+
+ key.uid = uid;
+ if ( ( idx = search_ctnr( UIDCache, uidCmp, &key ) ) < 0 ) {
+ struct passwd* pwent;
+
+ /* User id is not yet known */
+ entry = (CachedPWUID*)malloc( sizeof( CachedPWUID ) );
+ entry->tStamp = stamp;
+ entry->uid = uid;
+
+ pwent = getpwuid( uid );
+ if ( pwent )
+ entry->uName = strdup( pwent->pw_name );
+ else
+ entry->uName = strdup( "?" );
+
+ push_ctnr( UIDCache, entry );
+ bsort_ctnr( UIDCache, uidCmp );
+ } else {
+ /* User is is already known */
+ entry = get_ctnr( UIDCache, idx );
+ }
+
+ return entry->uName;
+}
diff --git a/ksysguard/ksysguardd/PWUIDCache.h b/ksysguard/ksysguardd/PWUIDCache.h
new file mode 100644
index 000000000..ce28df0fc
--- /dev/null
+++ b/ksysguard/ksysguardd/PWUIDCache.h
@@ -0,0 +1,36 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2000 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <sys/types.h>
+
+#ifndef KSG_PWUIDCACHE_H
+#define KSG_PWUIDCACHE_H
+
+/**
+ getpwuid() can be fairly expensive on NIS or LDAP systems that do not
+ use chaching. This module implements a cache for uid to user name
+ mappings.
+ */
+void initPWUIDCache( void );
+void exitPWUIDCache( void );
+
+const char* getCachedPWUID( uid_t uid );
+
+#endif
diff --git a/ksysguard/ksysguardd/Porting-HOWTO b/ksysguard/ksysguardd/Porting-HOWTO
new file mode 100644
index 000000000..4576783bc
--- /dev/null
+++ b/ksysguard/ksysguardd/Porting-HOWTO
@@ -0,0 +1,133 @@
+This document describes the interface between ksysguard and
+ksysguardd. ksysguardd is started as a child of ksysguard, either
+directly or via a shell. Alternatively a ksysguardd can listen on a
+port and a single instance can then be used by multiple instances of
+ksysguard.
+
+This client/server design was chosen, because on some operating
+systems the back-end needs elevated permissions. Since C++ programs
+should NEVER have setgid/setuid permissions, a plain C back-end was
+needed. It also allowed for an easy network support using existing
+security mechanisms (ssh).
+
+ksysguard sends commands and ksysguardd answers to them. Each answer
+ends with the string "\nksysguardd> ". Error messages are enclosed in
+ESC '\033' characters. Therefor regular messages may never contain
+ESC. The set of commands that each ksysguardd implementation supports
+can be very different. There are only a very few mandatory command and
+a few recommended commands.
+
+The mandatory commands are 'monitors', 'test' and 'quit'.
+The recommended commands are:
+
+cpu/idle
+cpu/sys
+cpu/nice
+cpu/user
+mem/swap/free
+mem/swap/used
+mem/physical/cached
+mem/physical/buf
+mem/physical/application
+mem/physical/used
+mem/physical/free
+ps
+pscount
+
+Without these commands KSysGuard is not very helpful.
+
+The 'monitors' command returns the list of available sensors. The
+output looks like this:
+
+--------
+mem/physical/free integer
+ps table
+pscount integer
+ksysguardd>
+--------
+
+Sensor names can be hierarchical. Each level is separated by a
+/. ksysguard uses a tree widget in the SensorBrowser to display the
+commands in a tree. Every sensor name must be followed by the type of
+the sensor separated by a tab. Currently 4 different types of sensors
+are supported, integer, float, listview and table. The table sensor
+returns the information for the ProcessController widget. listview
+sensors use a generic table to display information. To find out more
+about a sensor an additional command must be implemented for each
+sensor that has a questionmark appended to the sensor name. It can be
+used to find out more about the sensor.
+
+--------
+ksysguardd> mem/physical/free?
+Free Memory 0 260708 KB
+ksysguardd>
+--------
+
+integer and float sensor return a short description, the minimum and
+maximum value and the unit. All fields are again separated by
+tabs. The minimum and maximum values can both be 0 to trigger the
+auto-range feature of the display.
+
+--------
+ksysguardd> ps?
+Name PID PPID UID GID Status User% System% Nice VmSize VmRss VmLib Login Command
+s d d d d S f f d d sksysguardd>
+--------
+
+This is the output of the ps? inquiry command. The ps command is the
+only recommended command. The answer to ps? consists of 2 lines. Both
+lines have the same number of fields each separated by a tab. The
+first line specifies the name of the columns and the second the type
+of the values in the column.
+
+d: integer value
+D: integer value that should be localized in the frontend
+f: floating point value
+s: string value
+S: string value that needs to be translated
+ Strings must be added to the ProcessList::columnDict dictionary.
+
+For the ProcessController to function properly the Name and PID
+columns are mandatory. All other columns are optional and their
+content may be implementation dependant. It is highly recommended not
+to deviate from the Linux implementation unless absolutely
+unavoidable, in order to provide a consistent interface across all
+platforms.
+
+The 'test' command can be used by the front-end to find out if a
+certain other command is supported by this version of ksysguardd. The
+command returns "1\n" if the command is supported and "0\n" if the
+command is not supported.
+
+The 'quit' command terminates ksysguardd.
+
+ksysguardd may support dynamic monitor sets. If a CPU is added or an
+interface disabled, monitors may be added or removed. To notify the
+front-end about this, you need to send the string "RECONFIGURE\n" over
+stderr. This causes the front-end to request the list of monitors
+again and adapt it's layout accordingly. If ksysguardd receives a
+command it doesn't know it has to reply with "UNKNOWN
+COMMAND\nksysguardd> ".
+
+ksysguardd does not handle native language support. In order to have a
+minimum installation (only a single file) on the monitored machine,
+all translation are handled by the front-end. Please see the files
+gui/ksgrd/SensorManger.cc and gui/SensorDisplayLib/ProcessTable.cc
+if you add new strings.
+
+/**
+ * Since I'm very much a C++ guy I've written some functions which
+ * provide a similar functionality as template classes for lists and
+ * arrays. The Linux implementation uses them. Feel free to use them for
+ * the ports as well if you like. The interface is described in
+ * CContLib/ccont.h. Unfortunately I still haven't found time to document
+ * it properly, but the use should be fairly obvious.
+ */
+
+Chris <cs@kde.org>
+
+Since the above mentioned CContLib was a little slow I reimplement it and
+wrote some docu stuff in the header file. If you need an example for use
+look at ksysguardd/Linux/diskstat.(h|c).
+
+Tobias <tokoe@kde.org>
diff --git a/ksysguard/ksysguardd/Solaris/LoadAvg.c b/ksysguard/ksysguardd/Solaris/LoadAvg.c
new file mode 100644
index 000000000..aea38a212
--- /dev/null
+++ b/ksysguard/ksysguardd/Solaris/LoadAvg.c
@@ -0,0 +1,120 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999, 2000 Chris Schlaeger <cs@kde.org>
+
+ Solaris support by Torsten Kasch <tk@Genetik.Uni-Bielefeld.DE>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include "config.h"
+
+#ifdef HAVE_KSTAT
+#include <kstat.h>
+#endif
+
+#include "ksysguardd.h"
+#include "Command.h"
+#include "LoadAvg.h"
+
+double loadavg1 = 0.0;
+double loadavg5 = 0.0;
+double loadavg15 = 0.0;
+
+void initLoadAvg( struct SensorModul* sm ) {
+#ifdef HAVE_KSTAT
+ registerMonitor( "cpu/loadavg1", "float",
+ printLoadAvg1, printLoadAvg1Info, sm );
+ registerMonitor( "cpu/loadavg5", "float",
+ printLoadAvg5, printLoadAvg5Info, sm );
+ registerMonitor( "cpu/loadavg15", "float",
+ printLoadAvg15, printLoadAvg15Info, sm );
+#endif
+}
+
+void exitLoadAvg( void ) {
+}
+
+int updateLoadAvg( void ) {
+
+#ifdef HAVE_KSTAT
+ kstat_ctl_t *kctl;
+ kstat_t *ksp;
+ kstat_named_t *kdata;
+
+ /*
+ * get a kstat handle and update the user's kstat chain
+ */
+ if( (kctl = kstat_open()) == NULL )
+ return( 0 );
+ while( kstat_chain_update( kctl ) != 0 )
+ ;
+
+ /*
+ * traverse the kstat chain to find the appropriate statistics
+ */
+ if( (ksp = kstat_lookup( kctl, "unix", 0, "system_misc" )) == NULL )
+ return( 0 );
+ if( kstat_read( kctl, ksp, NULL ) == -1 )
+ return( 0 );
+
+ /*
+ * lookup the data
+ */
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "avenrun_1min" );
+ if( kdata != NULL )
+ loadavg1 = LOAD( kdata->value.ui32 );
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "avenrun_5min" );
+ if( kdata != NULL )
+ loadavg5 = LOAD( kdata->value.ui32 );
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "avenrun_15min" );
+ if( kdata != NULL )
+ loadavg15 = LOAD( kdata->value.ui32 );
+
+ kstat_close( kctl );
+#endif /* ! HAVE_KSTAT */
+
+ return( 0 );
+}
+
+void printLoadAvg1Info( const char *cmd ) {
+ fprintf(CurrentClient, "avnrun 1min\t0\t0\n" );
+}
+
+void printLoadAvg1( const char *cmd ) {
+ fprintf(CurrentClient, "%f\n", loadavg1 );
+}
+
+void printLoadAvg5Info( const char *cmd ) {
+ fprintf(CurrentClient, "avnrun 5min\t0\t0\n" );
+}
+
+void printLoadAvg5( const char *cmd ) {
+ fprintf(CurrentClient, "%f\n", loadavg5 );
+}
+
+void printLoadAvg15Info( const char *cmd ) {
+ fprintf(CurrentClient, "avnrun 15min\t0\t0\n" );
+}
+
+void printLoadAvg15( const char *cmd ) {
+ fprintf(CurrentClient, "%f\n", loadavg15 );
+}
diff --git a/ksysguard/ksysguardd/Solaris/LoadAvg.h b/ksysguard/ksysguardd/Solaris/LoadAvg.h
new file mode 100644
index 000000000..eea8ad82e
--- /dev/null
+++ b/ksysguard/ksysguardd/Solaris/LoadAvg.h
@@ -0,0 +1,41 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ Solaris support by Torsten Kasch <tk@Genetik.Uni-Bielefeld.DE>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _LoadAvg_h_
+#define _LoadAvg_h_
+
+#define LOAD(a) ((double)(a) / (1 << 8 ))
+
+void initLoadAvg(struct SensorModul* sm);
+void exitLoadAvg(void);
+
+int updateLoadAvg(void);
+
+void printLoadAvg1( const char *cmd );
+void printLoadAvg1Info( const char *cmd );
+void printLoadAvg5( const char *cmd );
+void printLoadAvg5Info( const char *cmd );
+void printLoadAvg15( const char *cmd );
+void printLoadAvg15Info( const char *cmd );
+
+#endif /* _LoadAvg_h_ */
diff --git a/ksysguard/ksysguardd/Solaris/Makefile.am b/ksysguard/ksysguardd/Solaris/Makefile.am
new file mode 100644
index 000000000..f5dd51c96
--- /dev/null
+++ b/ksysguard/ksysguardd/Solaris/Makefile.am
@@ -0,0 +1,10 @@
+#
+#
+
+# Sun's C++ compiler doesn't support -Wall
+#AM_CFLAGS = -Wall
+
+INCLUDES = -I$(srcdir)/../../CContLib -I$(srcdir)/..
+
+noinst_LIBRARIES = libksysguardd.a
+libksysguardd_a_SOURCES = Memory.c LoadAvg.c ProcessList.c NetDev.c
diff --git a/ksysguard/ksysguardd/Solaris/Memory.c b/ksysguard/ksysguardd/Solaris/Memory.c
new file mode 100644
index 000000000..efc2f18ac
--- /dev/null
+++ b/ksysguard/ksysguardd/Solaris/Memory.c
@@ -0,0 +1,223 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999, 2000 Chris Schlaeger <cs@kde.org>
+
+ Solaris support by Torsten Kasch <tk@Genetik.Uni-Bielefeld.DE>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "config.h"
+
+/* Stop <sys/swap.h> from crapping out on 32-bit architectures. */
+
+#if !defined(_LP64) && _FILE_OFFSET_BITS == 64
+# undef _FILE_OFFSET_BITS
+# define _FILE_OFFSET_BITS 32
+#endif
+
+#include <sys/stat.h>
+#include <sys/swap.h>
+#include <vm/anon.h>
+
+#ifdef HAVE_KSTAT
+#include <kstat.h>
+#endif
+
+#include "ksysguardd.h"
+#include "Command.h"
+#include "Memory.h"
+
+static int Dirty = 1;
+static t_memsize totalmem = (t_memsize) 0;
+static t_memsize freemem = (t_memsize) 0;
+static long totalswap = 0L;
+static long freeswap = 0L;
+static struct anoninfo am_swap;
+
+/*
+ * this is borrowed from top's m_sunos5 module
+ * used by permission from William LeFebvre
+ */
+static int pageshift;
+static long (*p_pagetok) ();
+#define pagetok(size) ((*p_pagetok)(size))
+
+long pagetok_none( long size ) {
+ return( size );
+}
+
+long pagetok_left( long size ) {
+ return( size << pageshift );
+}
+
+long pagetok_right( long size ) {
+ return( size >> pageshift );
+}
+
+void initMemory( struct SensorModul* sm ) {
+
+ long i = sysconf( _SC_PAGESIZE );
+
+ pageshift = 0;
+ while( (i >>= 1) > 0 )
+ pageshift++;
+
+ /* calculate an amount to shift to K values */
+ /* remember that log base 2 of 1024 is 10 (i.e.: 2^10 = 1024) */
+ pageshift -= 10;
+
+ /* now determine which pageshift function is appropriate for the
+ result (have to because x << y is undefined for y < 0) */
+ if( pageshift > 0 ) {
+ /* this is the most likely */
+ p_pagetok = pagetok_left;
+ } else if( pageshift == 0 ) {
+ p_pagetok = pagetok_none;
+ } else {
+ p_pagetok = pagetok_right;
+ pageshift = -pageshift;
+ }
+
+#ifdef HAVE_KSTAT
+ registerMonitor( "mem/physical/free", "integer",
+ printMemFree, printMemFreeInfo, sm );
+ registerMonitor( "mem/physical/used", "integer",
+ printMemUsed, printMemUsedInfo, sm );
+#endif
+ registerMonitor( "mem/swap/free", "integer",
+ printSwapFree, printSwapFreeInfo, sm );
+ registerMonitor( "mem/swap/used", "integer",
+ printSwapUsed, printSwapUsedInfo, sm );
+}
+
+void exitMemory( void ) {
+}
+
+int updateMemory( void ) {
+
+ long swaptotal;
+ long swapfree;
+ long swapused;
+#ifdef HAVE_KSTAT
+ kstat_ctl_t *kctl;
+ kstat_t *ksp;
+ kstat_named_t *kdata;
+#endif /* HAVE_KSTAT */
+ swaptotal = swapused = swapfree = 0L;
+
+ /*
+ * Retrieve overall swap information from anonymous memory structure -
+ * which is the same way "swap -s" retrieves it's statistics.
+ *
+ * swapctl(SC_LIST, void *arg) does not return what we are looking for.
+ */
+
+ if (swapctl(SC_AINFO, &am_swap) == -1)
+ return(0);
+
+ swaptotal = am_swap.ani_max;
+ swapused = am_swap.ani_resv;
+ swapfree = swaptotal - swapused;
+
+ totalswap = pagetok(swaptotal);
+ freeswap = pagetok(swapfree);
+
+#ifdef HAVE_KSTAT
+ /*
+ * get a kstat handle and update the user's kstat chain
+ */
+ if( (kctl = kstat_open()) == NULL )
+ return( 0 );
+ while( kstat_chain_update( kctl ) != 0 )
+ ;
+
+ totalmem = pagetok( sysconf( _SC_PHYS_PAGES ));
+
+ /*
+ * traverse the kstat chain to find the appropriate statistics
+ */
+ if( (ksp = kstat_lookup( kctl, "unix", 0, "system_pages" )) == NULL )
+ return( 0 );
+ if( kstat_read( kctl, ksp, NULL ) == -1 )
+ return( 0 );
+
+ /*
+ * lookup the data
+ */
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "freemem" );
+ if( kdata != NULL )
+ freemem = pagetok( kdata->value.ui32 );
+
+ kstat_close( kctl );
+#endif /* ! HAVE_KSTAT */
+
+ Dirty = 0;
+
+ return( 0 );
+}
+
+void printMemFreeInfo( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "Free Memory\t0\t%ld\tKB\n", totalmem );
+}
+
+void printMemFree( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "%ld\n", freemem );
+}
+
+void printMemUsedInfo( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "Used Memory\t0\t%ld\tKB\n", totalmem );
+}
+
+void printMemUsed( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "%ld\n", totalmem - freemem );
+}
+
+void printSwapFreeInfo( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "Free Swap\t0\t%ld\tKB\n", totalswap );
+}
+
+void printSwapFree( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "%ld\n", freeswap );
+}
+
+void printSwapUsedInfo( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "Used Swap\t0\t%ld\tKB\n", totalswap );
+}
+
+void printSwapUsed( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "%ld\n", totalswap - freeswap );
+}
diff --git a/ksysguard/ksysguardd/Solaris/Memory.h b/ksysguard/ksysguardd/Solaris/Memory.h
new file mode 100644
index 000000000..7df6eb033
--- /dev/null
+++ b/ksysguard/ksysguardd/Solaris/Memory.h
@@ -0,0 +1,46 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ Solaris support by Torsten Kasch <tk@Genetik.Uni-Bielefeld.DE>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _Memory_h_
+#define _Memory_h_
+
+typedef unsigned long t_memsize;
+
+#define PAGETOK(a) ((( (t_memsize) sysconf( _SC_PAGESIZE )) / (t_memsize) 1024) * (t_memsize) (a))
+
+void initMemory(struct SensorModul* sm);
+void exitMemory(void);
+
+int updateMemory(void);
+
+void printMemFree( const char *cmd );
+void printMemFreeInfo( const char *cmd );
+void printMemUsed( const char *cmd );
+void printMemUsedInfo( const char *cmd );
+
+void printSwapFree( const char *cmd );
+void printSwapFreeInfo( const char *cmd );
+void printSwapUsed( const char *cmd );
+void printSwapUsedInfo( const char *cmd );
+
+#endif /* _Memory_h */
diff --git a/ksysguard/ksysguardd/Solaris/NetDev.c b/ksysguard/ksysguardd/Solaris/NetDev.c
new file mode 100644
index 000000000..89db266cb
--- /dev/null
+++ b/ksysguard/ksysguardd/Solaris/NetDev.c
@@ -0,0 +1,679 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999, 2000 Chris Schlaeger <cs@kde.org>
+
+ Solaris support by Torsten Kasch <tk@Genetik.Uni-Bielefeld.DE>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stropts.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <net/if.h>
+
+#include "config.h"
+
+#ifdef HAVE_KSTAT
+#include <kstat.h>
+#endif
+
+#include "ksysguardd.h"
+#include "Command.h"
+#include "NetDev.h"
+
+/*
+ * available network interface statistics through kstat(3):
+ *
+ * kstat name value
+ * ----------------------------------------------------------------------
+ * for the loopback interface(s) we can get
+ * ipackets # packets received
+ * opackets # packets sent
+ * in addition to those, for "real" interfaces:
+ * oerrors # xmit errors
+ * ierrors # recv errors
+ * macxmt_errors # xmit errors reported by hardware?
+ * macrcv_errors # recv errors reported by hardware?
+ * opackets64 same as opackets (64bit)
+ * ipackets64 same as ipackets (64bit)
+ * obytes # bytes sent
+ * rbytes # bytes received
+ * obytes64 same as obytes (64bit)
+ * rbytes64 same as ibytes (64bit)
+ * collisions # collisions
+ * multixmt # multicasts sent?
+ * multircv # multicasts received?
+ * brdcstxmt # broadcasts transmitted
+ * brdcstrcv # broadcasts received
+ * unknowns
+ * blocked
+ * ex_collisions
+ * defer_xmts
+ * align_errors
+ * fcs_errors
+ * oflo # overflow errors
+ * uflo # underflow errors
+ * runt_errors
+ * missed
+ * tx_late_collisions
+ * carrier_errors
+ * noxmtbuf
+ * norcvbuf
+ * xmt_badinterp
+ * rcv_badinterp
+ * intr # interrupts?
+ * xmtretry # xmit retries?
+ * ifspeed interface speed: 10000000 for 10BaseT
+ * duplex "half" or "full"
+ * media e.g. "PHY/MII"
+ * promisc promiscuous mode (e.g. "off")
+ * first_collisions
+ * multi_collisions
+ * sqe_errors
+ * toolong_errors
+ */
+
+typedef struct {
+ char *Name;
+ short flags;
+ unsigned long ipackets;
+ unsigned long OLDipackets;
+ unsigned long opackets;
+ unsigned long OLDopackets;
+ unsigned long ierrors;
+ unsigned long OLDierrors;
+ unsigned long oerrors;
+ unsigned long OLDoerrors;
+ unsigned long collisions;
+ unsigned long OLDcollisions;
+ unsigned long multixmt;
+ unsigned long OLDmultixmt;
+ unsigned long multircv;
+ unsigned long OLDmultircv;
+ unsigned long brdcstxmt;
+ unsigned long OLDbrdcstxmt;
+ unsigned long brdcstrcv;
+ unsigned long OLDbrdcstrcv;
+} NetDevInfo;
+
+
+#define NBUFFERS 64
+#define MAXNETDEVS 64
+static NetDevInfo IfInfo[MAXNETDEVS];
+
+static int NetDevCount;
+
+/*
+ * insertnetdev() -- insert device name & flags into our list
+ */
+int insertnetdev( const char *name, const short flags ) {
+
+ int i = 0;
+
+ /*
+ * interface "aliases" don't seem to have
+ * separate kstat statistics, so we skip them
+ */
+ if( strchr( name, (int) ':' ) != NULL )
+ return( 0 );
+
+ while( (i < NetDevCount) && (strcmp( IfInfo[i].Name, name ) != 0) ) {
+ if( strcmp( IfInfo[i].Name, name ) == 0 )
+ return( 0 );
+ i++;
+ }
+
+ /*
+ * init new slot
+ */
+ IfInfo[i].Name = strdup( name );
+ IfInfo[i].flags = flags;
+ IfInfo[i].ipackets = 0L;
+ IfInfo[i].OLDipackets = 0L;
+ IfInfo[i].opackets = 0L;
+ IfInfo[i].OLDopackets = 0L;
+ IfInfo[i].ierrors = 0L;
+ IfInfo[i].OLDierrors = 0L;
+ IfInfo[i].oerrors = 0L;
+ IfInfo[i].OLDoerrors = 0L;
+ IfInfo[i].collisions = 0L;
+ IfInfo[i].OLDcollisions = 0L;
+ IfInfo[i].multixmt = 0L;
+ IfInfo[i].OLDmultixmt = 0L;
+ IfInfo[i].multircv = 0L;
+ IfInfo[i].OLDmultircv = 0L;
+ IfInfo[i].brdcstxmt = 0L;
+ IfInfo[i].OLDbrdcstxmt = 0L;
+ IfInfo[i].brdcstrcv = 0L;
+ IfInfo[i].OLDbrdcstrcv = 0L;
+ NetDevCount = ++i;
+
+ /* XXX: need sanity checks! */
+ return( 0 );
+}
+
+/*
+ * getnetdevlist() -- get a list of all "up" interfaces
+ */
+int getnetdevlist( void ) {
+
+ int fd;
+ int buffsize;
+ int prevsize;
+ int prevCount;
+ struct ifconf ifc;
+ struct ifreq *ifr;
+
+ if( (fd = socket( PF_INET, SOCK_DGRAM, 0 )) < 0 ) {
+ return( -1 );
+ }
+
+ /*
+ * get the interface list via iotl( SIOCGIFCONF )
+ * the following algorithm based on ideas from W.R. Stevens'
+ * "UNIX Network Programming", Vol. 1:
+ * Since the ioctl may return 0, indicating success, even if the
+ * ifreq buffer was too small, we have to make sure, it didn't
+ * get truncated by comparing our initial size guess with the
+ * actual returned size.
+ */
+ prevsize = 0;
+ buffsize = NBUFFERS * sizeof( struct ifreq );
+ while( 1 ) {
+ if( (ifc.ifc_buf = malloc( buffsize )) == NULL )
+ return( -1 );
+
+ ifc.ifc_len = buffsize;
+ if( ioctl( fd, SIOCGIFCONF, &ifc ) < 0 ) {
+ if( errno != EINVAL || prevsize != 0 ) {
+ free( ifc.ifc_buf );
+ return( -1 );
+ }
+ } else {
+ if( ifc.ifc_len == prevsize )
+ /* success */
+ break;
+ prevsize = ifc.ifc_len;
+ }
+ /*
+ * initial buffer guessed too small, allocate a bigger one
+ */
+ free( ifc.ifc_buf );
+ buffsize = (NBUFFERS + 10) * sizeof( struct ifreq );
+ }
+
+ /*
+ * get the names for all interfaces which are configured "up"
+ * we're not interested in the ifc data (address), so we reuse the
+ * same structure (with ifc.len set) for the next ioctl()
+ */
+ prevCount = NetDevCount;
+ for( ifr = (struct ifreq *) ifc.ifc_buf;
+ ifr < (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
+ ifr++ ) {
+ if( ioctl( fd, SIOCGIFFLAGS, ifr ) < 0 ) {
+ free( ifc.ifc_buf );
+ return( -1 );
+ }
+ if( ifr->ifr_flags & IFF_UP )
+ insertnetdev( ifr->ifr_name, ifr->ifr_flags );
+ }
+ free( ifc.ifc_buf );
+ close( fd );
+
+ if( (prevCount > 0) && (prevCount != NetDevCount) ) {
+ print_error( "RECONFIGURE\n" );
+ prevCount = NetDevCount;
+ }
+
+ return( NetDevCount );
+}
+
+void initNetDev( struct SensorModul* sm ) {
+#ifdef HAVE_KSTAT
+ char mon[128];
+ int i;
+
+ getnetdevlist();
+ for( i = 0; i < NetDevCount; i++ ) {
+ sprintf( mon, "network/%s/ipackets", IfInfo[i].Name );
+ registerMonitor( mon, "integer",
+ printIPackets, printIPacketsInfo, sm );
+ sprintf( mon, "network/%s/opackets", IfInfo[i].Name );
+ registerMonitor( mon, "integer",
+ printOPackets, printOPacketsInfo, sm );
+ /*
+ * if this isn't a loopback interface,
+ * register additional monitors
+ */
+ if( ! (IfInfo[i].flags & IFF_LOOPBACK) ) {
+ /*
+ * recv errors
+ */
+ sprintf( mon, "network/%s/ierrors",
+ IfInfo[i].Name );
+ registerMonitor( mon, "integer",
+ printIErrors, printIErrorsInfo, sm );
+ /*
+ * xmit errors
+ */
+ sprintf( mon, "network/%s/oerrors",
+ IfInfo[i].Name );
+ registerMonitor( mon, "integer",
+ printOErrors, printOErrorsInfo, sm );
+ /*
+ * collisions
+ */
+ sprintf( mon, "network/%s/collisions",
+ IfInfo[i].Name );
+ registerMonitor( mon, "integer",
+ printCollisions, printCollisionsInfo, sm );
+ /*
+ * multicast xmits
+ */
+ sprintf( mon, "network/%s/multixmt",
+ IfInfo[i].Name );
+ registerMonitor( mon, "integer",
+ printMultiXmits, printMultiXmitsInfo, sm );
+ /*
+ * multicast recvs
+ */
+ sprintf( mon, "network/%s/multircv",
+ IfInfo[i].Name );
+ registerMonitor( mon, "integer",
+ printMultiRecvs, printMultiRecvsInfo, sm );
+ /*
+ * broadcast xmits
+ */
+ sprintf( mon, "network/%s/brdcstxmt",
+ IfInfo[i].Name );
+ registerMonitor( mon, "integer",
+ printBcastXmits, printBcastXmitsInfo, sm );
+ /*
+ * broadcast recvs
+ */
+ sprintf( mon, "network/%s/brdcstrcv",
+ IfInfo[i].Name );
+ registerMonitor( mon, "integer",
+ printBcastRecvs, printBcastRecvsInfo, sm );
+ }
+ }
+#endif
+}
+
+void exitNetDev( void ) {
+}
+
+int updateNetDev( void ) {
+
+#ifdef HAVE_KSTAT
+ kstat_ctl_t *kctl;
+ kstat_t *ksp;
+ kstat_named_t *kdata;
+ int i;
+
+ /*
+ * get a kstat handle and update the user's kstat chain
+ */
+ if( (kctl = kstat_open()) == NULL )
+ return( 0 );
+ while( kstat_chain_update( kctl ) != 0 )
+ ;
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ char *name;
+ char *ptr;
+
+ /*
+ * chop off the trailing interface no
+ */
+ name = strdup( IfInfo[i].Name );
+ ptr = name + strlen( name ) - 1;
+ while( (ptr > name) && isdigit( (int) *ptr ) ) {
+ *ptr = '\0';
+ ptr--;
+ }
+
+ /*
+ * traverse the kstat chain
+ * to find the appropriate statistics
+ */
+ if( (ksp = kstat_lookup( kctl,
+ name, 0, IfInfo[i].Name )) == NULL ) {
+ free( name );
+ return( 0 );
+ }
+ if( kstat_read( kctl, ksp, NULL ) == -1 ) {
+ free( name );
+ return( 0 );
+ }
+ free( name );
+
+ /*
+ * lookup & store the data
+ */
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "ipackets" );
+ if( kdata != NULL ) {
+ IfInfo[i].OLDipackets = IfInfo[i].ipackets;
+ IfInfo[i].ipackets = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "opackets" );
+ if( kdata != NULL ) {
+ IfInfo[i].OLDopackets = IfInfo[i].opackets;
+ IfInfo[i].opackets = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "ierrors" );
+ if( kdata != NULL ) {
+ IfInfo[i].OLDierrors = IfInfo[i].ierrors;
+ IfInfo[i].ierrors = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "oerrors" );
+ if( kdata != NULL ) {
+ IfInfo[i].OLDoerrors = IfInfo[i].oerrors;
+ IfInfo[i].oerrors = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "collisions" );
+ if( kdata != NULL ) {
+ IfInfo[i].OLDcollisions = IfInfo[i].collisions;
+ IfInfo[i].collisions = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "multixmt" );
+ if( kdata != NULL ) {
+ IfInfo[i].OLDmultixmt = IfInfo[i].multixmt;
+ IfInfo[i].multixmt = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "multircv" );
+ if( kdata != NULL ) {
+ IfInfo[i].OLDmultircv = IfInfo[i].multircv;
+ IfInfo[i].multircv = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "brdcstxmt" );
+ if( kdata != NULL ) {
+ IfInfo[i].OLDbrdcstxmt = IfInfo[i].brdcstxmt;
+ IfInfo[i].brdcstxmt = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "brdcstrcv" );
+ if( kdata != NULL ) {
+ IfInfo[i].OLDbrdcstrcv = IfInfo[i].brdcstrcv;
+ IfInfo[i].brdcstrcv = kdata->value.ul;
+ }
+ }
+
+ kstat_close( kctl );
+#endif /* ! HAVE_KSTAT */
+
+ return( 0 );
+}
+
+void printIPacketsInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Received Packets\t0\t0\tPackets\n" );
+}
+
+void printIPackets( const char *cmd ) {
+
+ char *cmdcopy = strdup( cmd );
+ char *name, *ptr;
+ int i;
+
+ ptr = strchr( cmdcopy, (int) '/' );
+ name = ++ptr;
+ ptr = strchr( name, (int) '/' );
+ *ptr = '\0';
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ if( (IfInfo[i].OLDipackets > 0)
+ && (strcmp( IfInfo[i].Name, name ) == 0) ) {
+ fprintf(CurrentClient, "%ld\n",
+ IfInfo[i].ipackets - IfInfo[i].OLDipackets);
+ free( cmdcopy );
+ return;
+ }
+ }
+ free( cmdcopy );
+ fprintf(CurrentClient, "0\n" );
+}
+
+void printOPacketsInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Transmitted Packets\t0\t0\tPackets\n" );
+}
+
+void printOPackets( const char *cmd ) {
+
+ char *cmdcopy = strdup( cmd );
+ char *name, *ptr;
+ int i;
+
+ ptr = strchr( cmdcopy, (int) '/' );
+ name = ++ptr;
+ ptr = strchr( name, (int) '/' );
+ *ptr = '\0';
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ if( (IfInfo[i].OLDopackets > 0)
+ && (strcmp( IfInfo[i].Name, name ) == 0) ) {
+ fprintf(CurrentClient, "%ld\n",
+ IfInfo[i].opackets - IfInfo[i].OLDopackets );
+ free( cmdcopy );
+ return;
+ }
+ }
+ free( cmdcopy );
+ fprintf(CurrentClient, "0\n" );
+}
+
+void printIErrorsInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Input Errors\t0\t0\tPackets\n" );
+}
+
+void printIErrors( const char *cmd ) {
+
+ char *cmdcopy = strdup( cmd );
+ char *name, *ptr;
+ int i;
+
+ ptr = strchr( cmdcopy, (int) '/' );
+ name = ++ptr;
+ ptr = strchr( name, (int) '/' );
+ *ptr = '\0';
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ if( (IfInfo[i].OLDierrors > 0)
+ && (strcmp( IfInfo[i].Name, name ) == 0) ) {
+ fprintf(CurrentClient, "%ld\n",
+ IfInfo[i].ierrors - IfInfo[i].OLDierrors );
+ free( cmdcopy );
+ return;
+ }
+ }
+ free( cmdcopy );
+ fprintf(CurrentClient, "0\n" );
+}
+
+void printOErrorsInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Output Errors\t0\t0\tPackets\n" );
+}
+
+void printOErrors( const char *cmd ) {
+
+ char *cmdcopy = strdup( cmd );
+ char *name, *ptr;
+ int i;
+
+ ptr = strchr( cmdcopy, (int) '/' );
+ name = ++ptr;
+ ptr = strchr( name, (int) '/' );
+ *ptr = '\0';
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ if( (IfInfo[i].OLDoerrors > 0)
+ && (strcmp( IfInfo[i].Name, name ) == 0) ) {
+ fprintf(CurrentClient, "%ld\n",
+ IfInfo[i].oerrors - IfInfo[i].OLDoerrors );
+ free( cmdcopy );
+ return;
+ }
+ }
+ free( cmdcopy );
+ fprintf(CurrentClient, "0\n" );
+}
+
+void printCollisionsInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Collisions\t0\t0\tPackets\n" );
+}
+
+void printCollisions( const char *cmd ) {
+
+ char *cmdcopy = strdup( cmd );
+ char *name, *ptr;
+ int i;
+
+ ptr = strchr( cmdcopy, (int) '/' );
+ name = ++ptr;
+ ptr = strchr( name, (int) '/' );
+ *ptr = '\0';
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ if( (IfInfo[i].OLDcollisions > 0)
+ && (strcmp( IfInfo[i].Name, name ) == 0) ) {
+ fprintf(CurrentClient, "%ld\n",
+ IfInfo[i].collisions - IfInfo[i].OLDcollisions );
+ free( cmdcopy );
+ return;
+ }
+ }
+ free( cmdcopy );
+ fprintf(CurrentClient, "0\n" );
+}
+
+void printMultiXmitsInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Multicasts Sent\t0\t0\tPackets\n" );
+}
+
+void printMultiXmits( const char *cmd ) {
+
+ char *cmdcopy = strdup( cmd );
+ char *name, *ptr;
+ int i;
+
+ ptr = strchr( cmdcopy, (int) '/' );
+ name = ++ptr;
+ ptr = strchr( name, (int) '/' );
+ *ptr = '\0';
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ if( (IfInfo[i].OLDmultixmt > 0)
+ && (strcmp( IfInfo[i].Name, name ) == 0) ) {
+ fprintf(CurrentClient, "%ld\n",
+ IfInfo[i].multixmt - IfInfo[i].OLDmultixmt );
+ free( cmdcopy );
+ return;
+ }
+ }
+ free( cmdcopy );
+ fprintf(CurrentClient, "0\n" );
+}
+
+void printMultiRecvsInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Multicasts Received\t0\t0\tPackets\n" );
+}
+
+void printMultiRecvs( const char *cmd ) {
+
+ char *cmdcopy = strdup( cmd );
+ char *name, *ptr;
+ int i;
+
+ ptr = strchr( cmdcopy, (int) '/' );
+ name = ++ptr;
+ ptr = strchr( name, (int) '/' );
+ *ptr = '\0';
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ if( (IfInfo[i].OLDmultircv > 0)
+ && (strcmp( IfInfo[i].Name, name ) == 0) ) {
+ fprintf(CurrentClient, "%ld\n",
+ IfInfo[i].multircv - IfInfo[i].OLDmultircv );
+ free( cmdcopy );
+ return;
+ }
+ }
+ free( cmdcopy );
+ fprintf(CurrentClient, "0\n" );
+}
+
+void printBcastXmitsInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Broadcasts Sent\t0\t0\tPackets\n" );
+}
+
+void printBcastXmits( const char *cmd ) {
+
+ char *cmdcopy = strdup( cmd );
+ char *name, *ptr;
+ int i;
+
+ ptr = strchr( cmdcopy, (int) '/' );
+ name = ++ptr;
+ ptr = strchr( name, (int) '/' );
+ *ptr = '\0';
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ if( (IfInfo[i].OLDbrdcstxmt > 0)
+ && (strcmp( IfInfo[i].Name, name ) == 0) ) {
+ fprintf(CurrentClient, "%ld\n",
+ IfInfo[i].brdcstxmt - IfInfo[i].OLDbrdcstxmt );
+ free( cmdcopy );
+ return;
+ }
+ }
+ free( cmdcopy );
+ fprintf(CurrentClient, "0\n" );
+}
+
+void printBcastRecvsInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Broadcasts Received\t0\t0\tPackets\n" );
+}
+
+void printBcastRecvs( const char *cmd ) {
+
+ char *cmdcopy = strdup( cmd );
+ char *name, *ptr;
+ int i;
+
+ ptr = strchr( cmdcopy, (int) '/' );
+ name = ++ptr;
+ ptr = strchr( name, (int) '/' );
+ *ptr = '\0';
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ if( (IfInfo[i].OLDbrdcstrcv > 0)
+ && (strcmp( IfInfo[i].Name, name ) == 0) ) {
+ fprintf(CurrentClient, "%ld\n",
+ IfInfo[i].brdcstrcv - IfInfo[i].OLDbrdcstrcv );
+ free( cmdcopy );
+ return;
+ }
+ }
+ free( cmdcopy );
+ fprintf(CurrentClient, "0\n" );
+}
diff --git a/ksysguard/ksysguardd/Solaris/NetDev.h b/ksysguard/ksysguardd/Solaris/NetDev.h
new file mode 100644
index 000000000..b6ff54448
--- /dev/null
+++ b/ksysguard/ksysguardd/Solaris/NetDev.h
@@ -0,0 +1,59 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ Solaris support by Torsten Kasch <tk@Genetik.Uni-Bielefeld.DE>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _NetDev_h_
+#define _NetDev_h_
+
+void initNetDev(struct SensorModul* sm);
+void exitNetDev(void);
+
+int updateNetDev(void);
+
+void printIPacketsInfo( const char *cmd );
+void printIPackets( const char *cmd );
+
+void printOPacketsInfo( const char *cmd );
+void printOPackets( const char *cmd );
+
+void printIErrorsInfo( const char *cmd );
+void printIErrors( const char *cmd );
+
+void printOErrorsInfo( const char *cmd );
+void printOErrors( const char *cmd );
+
+void printCollisionsInfo( const char *cmd );
+void printCollisions( const char *cmd );
+
+void printMultiXmitsInfo( const char *cmd );
+void printMultiXmits( const char *cmd );
+
+void printMultiRecvsInfo( const char *cmd );
+void printMultiRecvs( const char *cmd );
+
+void printBcastXmitsInfo( const char *cmd );
+void printBcastXmits( const char *cmd );
+
+void printBcastRecvsInfo( const char *cmd );
+void printBcastRecvs( const char *cmd );
+
+#endif /* _NetDev_h */
diff --git a/ksysguard/ksysguardd/Solaris/ProcessList.c b/ksysguard/ksysguardd/Solaris/ProcessList.c
new file mode 100644
index 000000000..771371b76
--- /dev/null
+++ b/ksysguard/ksysguardd/Solaris/ProcessList.c
@@ -0,0 +1,436 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999, 2000 Chris Schlaeger <cs@kde.org>
+
+ Solaris support by Torsten Kasch <tk@Genetik.Uni-Bielefeld.DE>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+/* Stop <sys/procfs.h> from crapping out on 32-bit architectures. */
+
+#if !defined(_LP64) && _FILE_OFFSET_BITS == 64
+# undef _FILE_OFFSET_BITS
+# define _FILE_OFFSET_BITS 32
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <pwd.h>
+#include <procfs.h>
+#include <sys/proc.h>
+#include <sys/resource.h>
+
+#include "ccont.h"
+#include "../../gui/SignalIDs.h"
+#include "ksysguardd.h"
+
+#include "Command.h"
+#include "ProcessList.h"
+
+#define BUFSIZE 1024
+
+typedef struct {
+ int alive; /* for "garbage collection" */
+ pid_t pid; /* process ID */
+ pid_t ppid; /* parent process ID */
+ uid_t uid; /* process owner (real UID) */
+ gid_t gid; /* process group (real GID) */
+ char *userName; /* process owner (name) */
+ int nThreads; /* # of threads in this process */
+ int Prio; /* scheduling priority */
+ size_t Size; /* total size of process image */
+ size_t RSSize; /* resident set size */
+ char *State; /* process state */
+ int Time; /* CPU time for the process */
+ double Load; /* CPU load in % */
+ char *Command; /* command name */
+ char *CmdLine; /* command line */
+} ProcessInfo;
+
+static CONTAINER ProcessList = 0;
+static unsigned ProcessCount = 0; /* # of processes */
+static DIR *procdir; /* handle for /proc */
+
+/*
+ * lwpStateName() -- return string representation of process state
+ */
+char *lwpStateName( lwpsinfo_t lwpinfo ) {
+
+ char result[8];
+ int processor;
+
+ switch( (int) lwpinfo.pr_state ) {
+ case SSLEEP:
+ sprintf( result, "%s", "sleep" );
+ break;
+ case SRUN:
+ sprintf( result, "%s", "run" );
+ break;
+ case SZOMB:
+ sprintf( result, "%s", "zombie" );
+ break;
+ case SSTOP:
+ sprintf( result, "%s", "stop" );
+ break;
+ case SIDL:
+ sprintf( result, "%s", "start" );
+ break;
+ case SONPROC:
+ processor = (int) lwpinfo.pr_onpro;
+ sprintf( result, "%s/%d", "cpu", processor );
+ break;
+ default:
+ sprintf( result, "%s", "???" );
+ break;
+ }
+
+ return( strdup( result ));
+}
+
+static void validateStr( char *string ) {
+
+ char *ptr = string;
+
+ /*
+ * remove all chars that might screw up communication
+ */
+ while( *ptr != '\0' ) {
+ if( *ptr == '\t' || *ptr == '\n' || *ptr == '\r' )
+ *ptr = ' ';
+ ptr++;
+ }
+ /*
+ * make sure there's at least one char
+ */
+ if( string[0] == '\0' )
+ strcpy( string, " " );
+}
+
+static int processCmp( void *p1, void *p2 ) {
+
+ return( ((ProcessInfo *) p1)->pid - ((ProcessInfo *) p2)->pid );
+}
+
+static ProcessInfo *findProcessInList( pid_t pid ) {
+
+ ProcessInfo key;
+ long index;
+
+ key.pid = pid;
+ if( (index = search_ctnr( ProcessList, processCmp, &key )) < 0 )
+ return( NULL );
+
+ return( get_ctnr( ProcessList, index ));
+}
+
+static int updateProcess( pid_t pid ) {
+
+ ProcessInfo *ps;
+ int fd;
+ char buf[BUFSIZE];
+ psinfo_t psinfo;
+ struct passwd *pw;
+
+ if( (ps = findProcessInList( pid )) == NULL ) {
+ if( (ps = (ProcessInfo *) malloc( sizeof( ProcessInfo )))
+ == NULL ) {
+ print_error( "cannot malloc()\n" );
+ return( -1 );
+ }
+ ps->pid = pid;
+ ps->userName = NULL;
+ ps->State = NULL;
+ ps->Command = NULL;
+ ps->CmdLine = NULL;
+ ps->alive = 0;
+
+ push_ctnr( ProcessList, ps );
+ bsort_ctnr( ProcessList, processCmp );
+ }
+
+ snprintf( buf, BUFSIZE - 1, "%s/%ld/psinfo", PROCDIR, pid );
+ if( (fd = open( buf, O_RDONLY )) < 0 ) {
+ return( -1 );
+ }
+
+ if( read( fd, &psinfo, sizeof( psinfo_t )) != sizeof( psinfo_t )) {
+ close( fd );
+ return( -1 );
+ }
+ close( fd );
+
+ ps->ppid = psinfo.pr_ppid;
+ ps->uid = psinfo.pr_uid;
+ ps->gid = psinfo.pr_gid;
+
+ pw = getpwuid( psinfo.pr_uid );
+ if( ps->userName != NULL )
+ free( ps->userName );
+ ps->userName = strdup( pw->pw_name );
+
+ if( ps->State != NULL )
+ free( ps->State );
+ ps->State = lwpStateName( psinfo.pr_lwp );
+
+ /*
+ * the following data is invalid for zombies, so...
+ */
+ if( (ps->nThreads = psinfo.pr_nlwp ) != 0 ) {
+ ps->Prio = psinfo.pr_lwp.pr_pri;
+ ps->Time = psinfo.pr_lwp.pr_time.tv_sec * 100
+ + psinfo.pr_lwp.pr_time.tv_nsec * 10000000;
+ ps->Load = (double) psinfo.pr_lwp.pr_pctcpu
+ / (double) 0x8000 * 100.0;
+ } else {
+ ps->Prio = 0;
+ ps->Time = 0;
+ ps->Load = 0.0;
+ }
+
+ ps->Size = psinfo.pr_size;
+ ps->RSSize = psinfo.pr_rssize;
+
+ if( ps->Command != NULL )
+ free( ps->Command );
+ ps->Command = strdup( psinfo.pr_fname );
+ if( ps->CmdLine != NULL )
+ free( ps->CmdLine );
+ ps->CmdLine = strdup( psinfo.pr_psargs );
+
+ validateStr( ps->Command );
+ validateStr( ps->CmdLine );
+
+ ps->alive = 1;
+
+ return( 0 );
+}
+
+static void cleanupProcessList( void ) {
+
+ ProcessInfo *ps;
+
+ ProcessCount = 0;
+ for( ps = first_ctnr( ProcessList ); ps; ps = next_ctnr( ProcessList )) {
+ if( ps->alive ) {
+ ps->alive = 0;
+ ProcessCount++;
+ } else {
+ free( remove_ctnr( ProcessList ));
+ }
+ }
+}
+
+void initProcessList( struct SensorModul* sm ) {
+
+ if( (procdir = opendir( PROCDIR )) == NULL ) {
+ print_error( "cannot open \"%s\" for reading\n", PROCDIR );
+ return;
+ }
+
+ ProcessList = new_ctnr();
+
+ /*
+ * register the supported monitors & commands
+ */
+ registerMonitor( "pscount", "integer",
+ printProcessCount, printProcessCountInfo, sm );
+ registerMonitor( "ps", "table",
+ printProcessList, printProcessListInfo, sm );
+
+ registerCommand( "kill", killProcess );
+ registerCommand( "setpriority", setPriority );
+}
+
+void exitProcessList( void ) {
+
+ destr_ctnr( ProcessList, free );
+}
+
+int updateProcessList( void ) {
+
+ struct dirent *de;
+
+ rewinddir( procdir );
+ while( (de = readdir( procdir )) != NULL ) {
+ /*
+ * skip '.' and '..'
+ */
+ if( de->d_name[0] == '.' )
+ continue;
+
+ /*
+ * fetch the process info and insert it into the info table
+ */
+ updateProcess( (pid_t) atol( de->d_name ));
+ }
+ cleanupProcessList();
+
+ return( 0 );
+}
+
+void printProcessListInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Name\tPID\tPPID\tGID\tStatus\tUser\tThreads"
+ "\tSize\tResident\t%% CPU\tPriority\tCommand\n" );
+ fprintf(CurrentClient, "s\td\td\td\ts\ts\td\tD\tD\tf\td\ts\n" );
+}
+
+void printProcessList( const char *cmd ) {
+
+ ProcessInfo *ps;
+
+ for( ps = first_ctnr( ProcessList ); ps; ps = next_ctnr( ProcessList )) {
+ fprintf(CurrentClient,
+ "%s\t%ld\t%ld\t%ld\t%s\t%s\t%d\t%d\t%d\t%.2f\t%d\t%s\n",
+ ps->Command,
+ (long) ps->pid,
+ (long) ps->ppid,
+ (long) ps->gid,
+ ps->State,
+ ps->userName,
+ ps->nThreads,
+ ps->Size,
+ ps->RSSize,
+ ps->Load,
+ ps->Prio,
+ ps->CmdLine);
+ }
+
+ fprintf(CurrentClient, "\n");
+}
+
+void printProcessCount( const char *cmd ) {
+ fprintf(CurrentClient, "%d\n", ProcessCount );
+}
+
+void printProcessCountInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Number of Processes\t0\t0\t\n" );
+}
+
+void killProcess( const char *cmd ) {
+
+ int sig, pid;
+
+ sscanf( cmd, "%*s %d %d", &pid, &sig );
+
+ switch( sig ) {
+ case MENU_ID_SIGABRT:
+ sig = SIGABRT;
+ break;
+ case MENU_ID_SIGALRM:
+ sig = SIGALRM;
+ break;
+ case MENU_ID_SIGCHLD:
+ sig = SIGCHLD;
+ break;
+ case MENU_ID_SIGCONT:
+ sig = SIGCONT;
+ break;
+ case MENU_ID_SIGFPE:
+ sig = SIGFPE;
+ break;
+ case MENU_ID_SIGHUP:
+ sig = SIGHUP;
+ break;
+ case MENU_ID_SIGILL:
+ sig = SIGILL;
+ break;
+ case MENU_ID_SIGINT:
+ sig = SIGINT;
+ break;
+ case MENU_ID_SIGKILL:
+ sig = SIGKILL;
+ break;
+ case MENU_ID_SIGPIPE:
+ sig = SIGPIPE;
+ break;
+ case MENU_ID_SIGQUIT:
+ sig = SIGQUIT;
+ break;
+ case MENU_ID_SIGSEGV:
+ sig = SIGSEGV;
+ break;
+ case MENU_ID_SIGSTOP:
+ sig = SIGSTOP;
+ break;
+ case MENU_ID_SIGTERM:
+ sig = SIGTERM;
+ break;
+ case MENU_ID_SIGTSTP:
+ sig = SIGTSTP;
+ break;
+ case MENU_ID_SIGTTIN:
+ sig = SIGTTIN;
+ break;
+ case MENU_ID_SIGTTOU:
+ sig = SIGTTOU;
+ break;
+ case MENU_ID_SIGUSR1:
+ sig = SIGUSR1;
+ break;
+ case MENU_ID_SIGUSR2:
+ sig = SIGUSR2;
+ break;
+ }
+ if( kill( (pid_t) pid, sig )) {
+ switch( errno ) {
+ case EINVAL:
+ fprintf(CurrentClient, "4\n" );
+ break;
+ case ESRCH:
+ fprintf(CurrentClient, "3\n" );
+ break;
+ case EPERM:
+ fprintf(CurrentClient, "2\n" );
+ break;
+ default:
+ fprintf(CurrentClient, "1\n" ); /* unknown error */
+ break;
+ }
+ } else
+ fprintf(CurrentClient, "0\n");
+}
+
+void setPriority( const char *cmd ) {
+ int pid, prio;
+
+ sscanf( cmd, "%*s %d %d", &pid, &prio );
+ if( setpriority( PRIO_PROCESS, pid, prio )) {
+ switch( errno ) {
+ case EINVAL:
+ fprintf(CurrentClient, "4\n" );
+ break;
+ case ESRCH:
+ fprintf(CurrentClient, "3\n" );
+ break;
+ case EPERM:
+ case EACCES:
+ fprintf(CurrentClient, "2\n" );
+ break;
+ default:
+ fprintf(CurrentClient, "1\n" ); /* unknown error */
+ break;
+ }
+ } else
+ fprintf(CurrentClient, "0\n");
+}
diff --git a/ksysguard/ksysguardd/Solaris/ProcessList.h b/ksysguard/ksysguardd/Solaris/ProcessList.h
new file mode 100644
index 000000000..90333f5b8
--- /dev/null
+++ b/ksysguard/ksysguardd/Solaris/ProcessList.h
@@ -0,0 +1,43 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ Solaris support by Torsten Kasch <tk@Genetik.Uni-Bielefeld.DE>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _ProcessList_H_
+#define _ProcessList_H_
+
+#define PROCDIR "/proc"
+
+void initProcessList(struct SensorModul* sm);
+void exitProcessList(void);
+
+int updateProcessList(void);
+
+void printProcessList(const char*);
+void printProcessListInfo(const char*);
+
+void printProcessCount(const char* cmd);
+void printProcessCountInfo(const char* cmd);
+
+void killProcess(const char* cmd);
+void setPriority(const char* cmd);
+
+#endif
diff --git a/ksysguard/ksysguardd/Tru64/LoadAvg.c b/ksysguard/ksysguardd/Tru64/LoadAvg.c
new file mode 100644
index 000000000..ddbe68e2d
--- /dev/null
+++ b/ksysguard/ksysguardd/Tru64/LoadAvg.c
@@ -0,0 +1,121 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999, 2000 Chris Schlaeger <cs@kde.org>
+
+ Solaris support by Torsten Kasch <tk@Genetik.Uni-Bielefeld.DE>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/swap.h>
+
+#include "config.h"
+
+#ifdef HAVE_KSTAT
+#include <kstat.h>
+#endif
+
+#include "ksysguardd.h"
+#include "Command.h"
+#include "LoadAvg.h"
+
+double loadavg1 = 0.0;
+double loadavg5 = 0.0;
+double loadavg15 = 0.0;
+
+void initLoadAvg( struct SensorModul* sm ) {
+#ifdef HAVE_KSTAT
+ registerMonitor( "cpu/loadavg1", "float",
+ printLoadAvg1, printLoadAvg1Info, sm );
+ registerMonitor( "cpu/loadavg5", "float",
+ printLoadAvg5, printLoadAvg5Info, sm );
+ registerMonitor( "cpu/loadavg15", "float",
+ printLoadAvg15, printLoadAvg15Info, sm );
+#endif
+}
+
+void exitLoadAvg( void ) {
+}
+
+int updateLoadAvg( void ) {
+
+#ifdef HAVE_KSTAT
+ kstat_ctl_t *kctl;
+ kstat_t *ksp;
+ kstat_named_t *kdata;
+
+ /*
+ * get a kstat handle and update the user's kstat chain
+ */
+ if( (kctl = kstat_open()) == NULL )
+ return( 0 );
+ while( kstat_chain_update( kctl ) != 0 )
+ ;
+
+ /*
+ * traverse the kstat chain to find the appropriate statistics
+ */
+ if( (ksp = kstat_lookup( kctl, "unix", 0, "system_misc" )) == NULL )
+ return( 0 );
+ if( kstat_read( kctl, ksp, NULL ) == -1 )
+ return( 0 );
+
+ /*
+ * lookup the data
+ */
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "avenrun_1min" );
+ if( kdata != NULL )
+ loadavg1 = LOAD( kdata->value.ui32 );
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "avenrun_5min" );
+ if( kdata != NULL )
+ loadavg5 = LOAD( kdata->value.ui32 );
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "avenrun_15min" );
+ if( kdata != NULL )
+ loadavg15 = LOAD( kdata->value.ui32 );
+
+ kstat_close( kctl );
+#endif /* ! HAVE_KSTAT */
+
+ return( 0 );
+}
+
+void printLoadAvg1Info( const char *cmd ) {
+ fprintf(CurrentClient, "avnrun 1min\t0\t0\n" );
+}
+
+void printLoadAvg1( const char *cmd ) {
+ fprintf(CurrentClient, "%f\n", loadavg1 );
+}
+
+void printLoadAvg5Info( const char *cmd ) {
+ fprintf(CurrentClient, "avnrun 5min\t0\t0\n" );
+}
+
+void printLoadAvg5( const char *cmd ) {
+ fprintf(CurrentClient, "%f\n", loadavg5 );
+}
+
+void printLoadAvg15Info( const char *cmd ) {
+ fprintf(CurrentClient, "avnrun 15min\t0\t0\n" );
+}
+
+void printLoadAvg15( const char *cmd ) {
+ fprintf(CurrentClient, "%f\n", loadavg15 );
+}
diff --git a/ksysguard/ksysguardd/Tru64/LoadAvg.h b/ksysguard/ksysguardd/Tru64/LoadAvg.h
new file mode 100644
index 000000000..eea8ad82e
--- /dev/null
+++ b/ksysguard/ksysguardd/Tru64/LoadAvg.h
@@ -0,0 +1,41 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ Solaris support by Torsten Kasch <tk@Genetik.Uni-Bielefeld.DE>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _LoadAvg_h_
+#define _LoadAvg_h_
+
+#define LOAD(a) ((double)(a) / (1 << 8 ))
+
+void initLoadAvg(struct SensorModul* sm);
+void exitLoadAvg(void);
+
+int updateLoadAvg(void);
+
+void printLoadAvg1( const char *cmd );
+void printLoadAvg1Info( const char *cmd );
+void printLoadAvg5( const char *cmd );
+void printLoadAvg5Info( const char *cmd );
+void printLoadAvg15( const char *cmd );
+void printLoadAvg15Info( const char *cmd );
+
+#endif /* _LoadAvg_h_ */
diff --git a/ksysguard/ksysguardd/Tru64/Makefile.am b/ksysguard/ksysguardd/Tru64/Makefile.am
new file mode 100644
index 000000000..95be0247b
--- /dev/null
+++ b/ksysguard/ksysguardd/Tru64/Makefile.am
@@ -0,0 +1,8 @@
+#
+#
+AM_CFLAGS = -Wall
+
+INCLUDES = -I$(srcdir)/../../CContLib -I..
+
+lib_LIBRARIES = libksysguardd.a
+libksysguardd_a_SOURCES = Memory.c LoadAvg.c NetDev.c
diff --git a/ksysguard/ksysguardd/Tru64/Memory.c b/ksysguard/ksysguardd/Tru64/Memory.c
new file mode 100644
index 000000000..3a9332064
--- /dev/null
+++ b/ksysguard/ksysguardd/Tru64/Memory.c
@@ -0,0 +1,237 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999, 2000 Chris Schlaeger <cs@kde.org>
+
+ Solaris support by Torsten Kasch <tk@Genetik.Uni-Bielefeld.DE>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/swap.h>
+
+#include "config.h"
+
+#ifdef HAVE_KSTAT
+#include <kstat.h>
+#endif
+
+#include "ksysguardd.h"
+#include "Command.h"
+#include "Memory.h"
+
+static int Dirty = 1;
+static t_memsize totalmem = (t_memsize) 0;
+static t_memsize freemem = (t_memsize) 0;
+static long totalswap = 0L;
+static long freeswap = 0L;
+
+/*
+ * this is borrowed from top's m_sunos5 module
+ * used by permission from William LeFebvre
+ */
+static int pageshift;
+static long (*p_pagetok) ();
+#define pagetok(size) ((*p_pagetok)(size))
+
+long pagetok_none( long size ) {
+ return( size );
+}
+
+long pagetok_left( long size ) {
+ return( size << pageshift );
+}
+
+long pagetok_right( long size ) {
+ return( size >> pageshift );
+}
+
+void initMemory( struct SensorModul* sm ) {
+
+ long i = sysconf( _SC_PAGESIZE );
+
+ pageshift = 0;
+ while( (i >>= 1) > 0 )
+ pageshift++;
+
+ /* calculate an amount to shift to K values */
+ /* remember that log base 2 of 1024 is 10 (i.e.: 2^10 = 1024) */
+ pageshift -= 10;
+
+ /* now determine which pageshift function is appropriate for the
+ result (have to because x << y is undefined for y < 0) */
+ if( pageshift > 0 ) {
+ /* this is the most likely */
+ p_pagetok = pagetok_left;
+ } else if( pageshift == 0 ) {
+ p_pagetok = pagetok_none;
+ } else {
+ p_pagetok = pagetok_right;
+ pageshift = -pageshift;
+ }
+
+#ifdef HAVE_KSTAT
+ registerMonitor( "mem/physical/free", "integer",
+ printMemFree, printMemFreeInfo, sm );
+ registerMonitor( "mem/physical/used", "integer",
+ printMemUsed, printMemUsedInfo, sm );
+#endif
+ registerMonitor( "mem/swap/free", "integer",
+ printSwapFree, printSwapFreeInfo, sm );
+ registerMonitor( "mem/swap/used", "integer",
+ printSwapUsed, printSwapUsedInfo, sm );
+}
+
+void exitMemory( void ) {
+}
+
+int updateMemory( void ) {
+
+ struct swaptable *swt;
+ struct swapent *ste;
+ int i;
+ int ndevs;
+ long swaptotal;
+ long swapfree;
+ char dummy[128];
+#ifdef HAVE_KSTAT
+ kstat_ctl_t *kctl;
+ kstat_t *ksp;
+ kstat_named_t *kdata;
+#endif /* HAVE_KSTAT */
+
+ if( (ndevs = swapctl( SC_GETNSWP, NULL )) < 1 )
+ return( 0 );
+ if( (swt = (struct swaptable *) malloc(
+ sizeof( int )
+ + ndevs * sizeof( struct swapent ))) == NULL )
+ return( 0 );
+
+ /*
+ * fill in the required fields and retrieve the info thru swapctl()
+ */
+ swt->swt_n = ndevs;
+ ste = &(swt->swt_ent[0]);
+ for( i = 0; i < ndevs; i++ ) {
+ /*
+ * since we'renot interested in the path(s),
+ * we'll re-use the same buffer
+ */
+ ste->ste_path = dummy;
+ ste++;
+ }
+ swapctl( SC_LIST, swt );
+
+ swaptotal = swapfree = 0L;
+
+ ste = &(swt->swt_ent[0]);
+ for( i = 0; i < ndevs; i++ ) {
+ if( (! (ste->ste_flags & ST_INDEL))
+ && (! (ste->ste_flags & ST_DOINGDEL)) ) {
+ swaptotal += ste->ste_pages;
+ swapfree += ste->ste_free;
+ }
+ ste++;
+ }
+ free( swt );
+
+ totalswap = pagetok( swaptotal );
+ freeswap = pagetok( swapfree );
+
+#ifdef HAVE_KSTAT
+ /*
+ * get a kstat handle and update the user's kstat chain
+ */
+ if( (kctl = kstat_open()) == NULL )
+ return( 0 );
+ while( kstat_chain_update( kctl ) != 0 )
+ ;
+
+ totalmem = pagetok( sysconf( _SC_PHYS_PAGES ));
+
+ /*
+ * traverse the kstat chain to find the appropriate statistics
+ */
+ if( (ksp = kstat_lookup( kctl, "unix", 0, "system_pages" )) == NULL )
+ return( 0 );
+ if( kstat_read( kctl, ksp, NULL ) == -1 )
+ return( 0 );
+
+ /*
+ * lookup the data
+ */
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "freemem" );
+ if( kdata != NULL )
+ freemem = pagetok( kdata->value.ui32 );
+
+ kstat_close( kctl );
+#endif /* ! HAVE_KSTAT */
+
+ Dirty = 0;
+
+ return( 0 );
+}
+
+void printMemFreeInfo( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "Free Memory\t0\t%ld\tKB\n", totalmem );
+}
+
+void printMemFree( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "%ld\n", freemem );
+}
+
+void printMemUsedInfo( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "Used Memory\t0\t%ld\tKB\n", totalmem );
+}
+
+void printMemUsed( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "%ld\n", totalmem - freemem );
+}
+
+void printSwapFreeInfo( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "Free Swap\t0\t%ld\tKB\n", totalswap );
+}
+
+void printSwapFree( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "%ld\n", freeswap );
+}
+
+void printSwapUsedInfo( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "Used Swap\t0\t%ld\tKB\n", totalswap );
+}
+
+void printSwapUsed( const char *cmd ) {
+ if( Dirty )
+ updateMemory();
+ fprintf(CurrentClient, "%ld\n", totalswap - freeswap );
+}
diff --git a/ksysguard/ksysguardd/Tru64/Memory.h b/ksysguard/ksysguardd/Tru64/Memory.h
new file mode 100644
index 000000000..7df6eb033
--- /dev/null
+++ b/ksysguard/ksysguardd/Tru64/Memory.h
@@ -0,0 +1,46 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ Solaris support by Torsten Kasch <tk@Genetik.Uni-Bielefeld.DE>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _Memory_h_
+#define _Memory_h_
+
+typedef unsigned long t_memsize;
+
+#define PAGETOK(a) ((( (t_memsize) sysconf( _SC_PAGESIZE )) / (t_memsize) 1024) * (t_memsize) (a))
+
+void initMemory(struct SensorModul* sm);
+void exitMemory(void);
+
+int updateMemory(void);
+
+void printMemFree( const char *cmd );
+void printMemFreeInfo( const char *cmd );
+void printMemUsed( const char *cmd );
+void printMemUsedInfo( const char *cmd );
+
+void printSwapFree( const char *cmd );
+void printSwapFreeInfo( const char *cmd );
+void printSwapUsed( const char *cmd );
+void printSwapUsedInfo( const char *cmd );
+
+#endif /* _Memory_h */
diff --git a/ksysguard/ksysguardd/Tru64/NetDev.c b/ksysguard/ksysguardd/Tru64/NetDev.c
new file mode 100644
index 000000000..0699b929a
--- /dev/null
+++ b/ksysguard/ksysguardd/Tru64/NetDev.c
@@ -0,0 +1,678 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999, 2000 Chris Schlaeger <cs@kde.org>
+
+ Solaris support by Torsten Kasch <tk@Genetik.Uni-Bielefeld.DE>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stropts.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+
+#include "config.h"
+
+#ifdef HAVE_KSTAT
+#include <kstat.h>
+#endif
+
+#include "ksysguardd.h"
+#include "Command.h"
+#include "NetDev.h"
+
+/*
+ * available network interface statistics through kstat(3):
+ *
+ * kstat name value
+ * ----------------------------------------------------------------------
+ * for the loopback interface(s) we can get
+ * ipackets # packets received
+ * opackets # packets sent
+ * in addition to those, for "real" interfaces:
+ * oerrors # xmit errors
+ * ierrors # recv errors
+ * macxmt_errors # xmit errors reported by hardware?
+ * macrcv_errors # recv errors reported by hardware?
+ * opackets64 same as opackets (64bit)
+ * ipackets64 same as ipackets (64bit)
+ * obytes # bytes sent
+ * rbytes # bytes received
+ * obytes64 same as obytes (64bit)
+ * rbytes64 same as ibytes (64bit)
+ * collisions # collisions
+ * multixmt # multicasts sent?
+ * multircv # multicasts received?
+ * brdcstxmt # broadcasts transmitted
+ * brdcstrcv # broadcasts received
+ * unknowns
+ * blocked
+ * ex_collisions
+ * defer_xmts
+ * align_errors
+ * fcs_errors
+ * oflo # overflow errors
+ * uflo # underflow errors
+ * runt_errors
+ * missed
+ * tx_late_collisions
+ * carrier_errors
+ * noxmtbuf
+ * norcvbuf
+ * xmt_badinterp
+ * rcv_badinterp
+ * intr # interrupts?
+ * xmtretry # xmit retries?
+ * ifspeed interface speed: 10000000 for 10BaseT
+ * duplex "half" or "full"
+ * media e.g. "PHY/MII"
+ * promisc promiscuous mode (e.g. "off")
+ * first_collisions
+ * multi_collisions
+ * sqe_errors
+ * toolong_errors
+ */
+
+typedef struct {
+ char *Name;
+ short flags;
+ unsigned long ipackets;
+ unsigned long OLDipackets;
+ unsigned long opackets;
+ unsigned long OLDopackets;
+ unsigned long ierrors;
+ unsigned long OLDierrors;
+ unsigned long oerrors;
+ unsigned long OLDoerrors;
+ unsigned long collisions;
+ unsigned long OLDcollisions;
+ unsigned long multixmt;
+ unsigned long OLDmultixmt;
+ unsigned long multircv;
+ unsigned long OLDmultircv;
+ unsigned long brdcstxmt;
+ unsigned long OLDbrdcstxmt;
+ unsigned long brdcstrcv;
+ unsigned long OLDbrdcstrcv;
+} NetDevInfo;
+
+
+#define NBUFFERS 64
+#define MAXNETDEVS 64
+static NetDevInfo IfInfo[MAXNETDEVS];
+
+static int NetDevCount;
+
+/*
+ * insertnetdev() -- insert device name & flags into our list
+ */
+int insertnetdev( const char *name, const short flags ) {
+
+ int i = 0;
+
+ /*
+ * interface "aliases" don't seem to have
+ * separate kstat statistics, so we skip them
+ */
+ if( strchr( name, (int) ':' ) != NULL )
+ return( 0 );
+
+ while( (i < NetDevCount) && (strcmp( IfInfo[i].Name, name ) != 0) ) {
+ if( strcmp( IfInfo[i].Name, name ) == 0 )
+ return( 0 );
+ i++;
+ }
+
+ /*
+ * init new slot
+ */
+ IfInfo[i].Name = strdup( name );
+ IfInfo[i].flags = flags;
+ IfInfo[i].ipackets = 0L;
+ IfInfo[i].OLDipackets = 0L;
+ IfInfo[i].opackets = 0L;
+ IfInfo[i].OLDopackets = 0L;
+ IfInfo[i].ierrors = 0L;
+ IfInfo[i].OLDierrors = 0L;
+ IfInfo[i].oerrors = 0L;
+ IfInfo[i].OLDoerrors = 0L;
+ IfInfo[i].collisions = 0L;
+ IfInfo[i].OLDcollisions = 0L;
+ IfInfo[i].multixmt = 0L;
+ IfInfo[i].OLDmultixmt = 0L;
+ IfInfo[i].multircv = 0L;
+ IfInfo[i].OLDmultircv = 0L;
+ IfInfo[i].brdcstxmt = 0L;
+ IfInfo[i].OLDbrdcstxmt = 0L;
+ IfInfo[i].brdcstrcv = 0L;
+ IfInfo[i].OLDbrdcstrcv = 0L;
+ NetDevCount = ++i;
+
+ /* XXX: need sanity checks! */
+ return( 0 );
+}
+
+/*
+ * getnetdevlist() -- get a list of all "up" interfaces
+ */
+int getnetdevlist( void ) {
+
+ int fd;
+ int buffsize;
+ int prevsize;
+ int prevCount;
+ struct ifconf ifc;
+ struct ifreq *ifr;
+
+ if( (fd = socket( PF_INET, SOCK_DGRAM, 0 )) < 0 ) {
+ return( -1 );
+ }
+
+ /*
+ * get the interface list via iotl( SIOCGIFCONF )
+ * the following algorithm based on ideas from W.R. Stevens'
+ * "UNIX Network Programming", Vol. 1:
+ * Since the ioctl may return 0, indicating success, even if the
+ * ifreq buffer was too small, we have to make sure, it didn't
+ * get truncated by comparing our initial size guess with the
+ * actual returned size.
+ */
+ prevsize = 0;
+ buffsize = NBUFFERS * sizeof( struct ifreq );
+ while( 1 ) {
+ if( (ifc.ifc_buf = malloc( buffsize )) == NULL )
+ return( -1 );
+
+ ifc.ifc_len = buffsize;
+ if( ioctl( fd, SIOCGIFCONF, &ifc ) < 0 ) {
+ if( errno != EINVAL || prevsize != 0 ) {
+ free( ifc.ifc_buf );
+ return( -1 );
+ }
+ } else {
+ if( ifc.ifc_len == prevsize )
+ /* success */
+ break;
+ prevsize = ifc.ifc_len;
+ }
+ /*
+ * initial buffer guessed too small, allocate a bigger one
+ */
+ free( ifc.ifc_buf );
+ buffsize = (NBUFFERS + 10) * sizeof( struct ifreq );
+ }
+
+ /*
+ * get the names for all interfaces which are configured "up"
+ * we're not interested in the ifc data (address), so we reuse the
+ * same structure (with ifc.len set) for the next ioctl()
+ */
+ prevCount = NetDevCount;
+ for( ifr = (struct ifreq *) ifc.ifc_buf;
+ ifr < (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
+ ifr++ ) {
+ if( ioctl( fd, SIOCGIFFLAGS, ifr ) < 0 ) {
+ free( ifc.ifc_buf );
+ return( -1 );
+ }
+ if( ifr->ifr_flags & IFF_UP )
+ insertnetdev( ifr->ifr_name, ifr->ifr_flags );
+ }
+ free( ifc.ifc_buf );
+ close( fd );
+
+ if( (prevCount > 0) && (prevCount != NetDevCount) ) {
+ print_error( "RECONFIGURE\n" );
+ prevCount = NetDevCount;
+ }
+
+ return( NetDevCount );
+}
+
+void initNetDev( struct SensorModul* sm ) {
+#ifdef HAVE_KSTAT
+ char mon[128];
+ int i;
+
+ getnetdevlist();
+ for( i = 0; i < NetDevCount; i++ ) {
+ sprintf( mon, "network/%s/ipackets", IfInfo[i].Name );
+ registerMonitor( mon, "integer",
+ printIPackets, printIPacketsInfo, sm );
+ sprintf( mon, "network/%s/opackets", IfInfo[i].Name );
+ registerMonitor( mon, "integer",
+ printOPackets, printOPacketsInfo, sm );
+ /*
+ * if this isn't a loopback interface,
+ * register additional monitors
+ */
+ if( ! (IfInfo[i].flags & IFF_LOOPBACK) ) {
+ /*
+ * recv errors
+ */
+ sprintf( mon, "network/%s/ierrors",
+ IfInfo[i].Name );
+ registerMonitor( mon, "integer",
+ printIErrors, printIErrorsInfo, sm );
+ /*
+ * xmit errors
+ */
+ sprintf( mon, "network/%s/oerrors",
+ IfInfo[i].Name );
+ registerMonitor( mon, "integer",
+ printOErrors, printOErrorsInfo, sm );
+ /*
+ * collisions
+ */
+ sprintf( mon, "network/%s/collisions",
+ IfInfo[i].Name );
+ registerMonitor( mon, "integer",
+ printCollisions, printCollisionsInfo, sm );
+ /*
+ * multicast xmits
+ */
+ sprintf( mon, "network/%s/multixmt",
+ IfInfo[i].Name );
+ registerMonitor( mon, "integer",
+ printMultiXmits, printMultiXmitsInfo, sm );
+ /*
+ * multicast recvs
+ */
+ sprintf( mon, "network/%s/multircv",
+ IfInfo[i].Name );
+ registerMonitor( mon, "integer",
+ printMultiRecvs, printMultiRecvsInfo, sm );
+ /*
+ * broadcast xmits
+ */
+ sprintf( mon, "network/%s/brdcstxmt",
+ IfInfo[i].Name );
+ registerMonitor( mon, "integer",
+ printBcastXmits, printBcastXmitsInfo, sm );
+ /*
+ * broadcast recvs
+ */
+ sprintf( mon, "network/%s/brdcstrcv",
+ IfInfo[i].Name );
+ registerMonitor( mon, "integer",
+ printBcastRecvs, printBcastRecvsInfo, sm );
+ }
+ }
+#endif
+}
+
+void exitNetDev( void ) {
+}
+
+int updateNetDev( void ) {
+
+#ifdef HAVE_KSTAT
+ kstat_ctl_t *kctl;
+ kstat_t *ksp;
+ kstat_named_t *kdata;
+ int i;
+
+ /*
+ * get a kstat handle and update the user's kstat chain
+ */
+ if( (kctl = kstat_open()) == NULL )
+ return( 0 );
+ while( kstat_chain_update( kctl ) != 0 )
+ ;
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ char *name;
+ char *ptr;
+
+ /*
+ * chop off the trailing interface no
+ */
+ name = strdup( IfInfo[i].Name );
+ ptr = name + strlen( name ) - 1;
+ while( (ptr > name) && isdigit( (int) *ptr ) ) {
+ *ptr = '\0';
+ ptr--;
+ }
+
+ /*
+ * traverse the kstat chain
+ * to find the appropriate statistics
+ */
+ if( (ksp = kstat_lookup( kctl,
+ name, 0, IfInfo[i].Name )) == NULL ) {
+ free( name );
+ return( 0 );
+ }
+ if( kstat_read( kctl, ksp, NULL ) == -1 ) {
+ free( name );
+ return( 0 );
+ }
+ free( name );
+
+ /*
+ * lookup & store the data
+ */
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "ipackets" );
+ if( kdata != NULL ) {
+ IfInfo[i].OLDipackets = IfInfo[i].ipackets;
+ IfInfo[i].ipackets = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "opackets" );
+ if( kdata != NULL ) {
+ IfInfo[i].OLDopackets = IfInfo[i].opackets;
+ IfInfo[i].opackets = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "ierrors" );
+ if( kdata != NULL ) {
+ IfInfo[i].OLDierrors = IfInfo[i].ierrors;
+ IfInfo[i].ierrors = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "oerrors" );
+ if( kdata != NULL ) {
+ IfInfo[i].OLDoerrors = IfInfo[i].oerrors;
+ IfInfo[i].oerrors = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "collisions" );
+ if( kdata != NULL ) {
+ IfInfo[i].OLDcollisions = IfInfo[i].collisions;
+ IfInfo[i].collisions = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "multixmt" );
+ if( kdata != NULL ) {
+ IfInfo[i].OLDmultixmt = IfInfo[i].multixmt;
+ IfInfo[i].multixmt = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "multircv" );
+ if( kdata != NULL ) {
+ IfInfo[i].OLDmultircv = IfInfo[i].multircv;
+ IfInfo[i].multircv = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "brdcstxmt" );
+ if( kdata != NULL ) {
+ IfInfo[i].OLDbrdcstxmt = IfInfo[i].brdcstxmt;
+ IfInfo[i].brdcstxmt = kdata->value.ul;
+ }
+ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "brdcstrcv" );
+ if( kdata != NULL ) {
+ IfInfo[i].OLDbrdcstrcv = IfInfo[i].brdcstrcv;
+ IfInfo[i].brdcstrcv = kdata->value.ul;
+ }
+ }
+
+ kstat_close( kctl );
+#endif /* ! HAVE_KSTAT */
+
+ return( 0 );
+}
+
+void printIPacketsInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Received Packets\t0\t0\tPackets\n" );
+}
+
+void printIPackets( const char *cmd ) {
+
+ char *cmdcopy = strdup( cmd );
+ char *name, *ptr;
+ int i;
+
+ ptr = strchr( cmdcopy, (int) '/' );
+ name = ++ptr;
+ ptr = strchr( name, (int) '/' );
+ *ptr = '\0';
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ if( (IfInfo[i].OLDipackets > 0)
+ && (strcmp( IfInfo[i].Name, name ) == 0) ) {
+ fprintf(CurrentClient, "%ld\n",
+ IfInfo[i].ipackets - IfInfo[i].OLDipackets);
+ free( cmdcopy );
+ return;
+ }
+ }
+ free( cmdcopy );
+ fprintf(CurrentClient, "0\n" );
+}
+
+void printOPacketsInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Transmitted Packets\t0\t0\tPackets\n" );
+}
+
+void printOPackets( const char *cmd ) {
+
+ char *cmdcopy = strdup( cmd );
+ char *name, *ptr;
+ int i;
+
+ ptr = strchr( cmdcopy, (int) '/' );
+ name = ++ptr;
+ ptr = strchr( name, (int) '/' );
+ *ptr = '\0';
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ if( (IfInfo[i].OLDopackets > 0)
+ && (strcmp( IfInfo[i].Name, name ) == 0) ) {
+ fprintf(CurrentClient, "%ld\n",
+ IfInfo[i].opackets - IfInfo[i].OLDopackets );
+ free( cmdcopy );
+ return;
+ }
+ }
+ free( cmdcopy );
+ fprintf(CurrentClient, "0\n" );
+}
+
+void printIErrorsInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Input Errors\t0\t0\tPackets\n" );
+}
+
+void printIErrors( const char *cmd ) {
+
+ char *cmdcopy = strdup( cmd );
+ char *name, *ptr;
+ int i;
+
+ ptr = strchr( cmdcopy, (int) '/' );
+ name = ++ptr;
+ ptr = strchr( name, (int) '/' );
+ *ptr = '\0';
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ if( (IfInfo[i].OLDierrors > 0)
+ && (strcmp( IfInfo[i].Name, name ) == 0) ) {
+ fprintf(CurrentClient, "%ld\n",
+ IfInfo[i].ierrors - IfInfo[i].OLDierrors );
+ free( cmdcopy );
+ return;
+ }
+ }
+ free( cmdcopy );
+ fprintf(CurrentClient, "0\n" );
+}
+
+void printOErrorsInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Output Errors\t0\t0\tPackets\n" );
+}
+
+void printOErrors( const char *cmd ) {
+
+ char *cmdcopy = strdup( cmd );
+ char *name, *ptr;
+ int i;
+
+ ptr = strchr( cmdcopy, (int) '/' );
+ name = ++ptr;
+ ptr = strchr( name, (int) '/' );
+ *ptr = '\0';
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ if( (IfInfo[i].OLDoerrors > 0)
+ && (strcmp( IfInfo[i].Name, name ) == 0) ) {
+ fprintf(CurrentClient, "%ld\n",
+ IfInfo[i].oerrors - IfInfo[i].OLDoerrors );
+ free( cmdcopy );
+ return;
+ }
+ }
+ free( cmdcopy );
+ fprintf(CurrentClient, "0\n" );
+}
+
+void printCollisionsInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Collisions\t0\t0\tPackets\n" );
+}
+
+void printCollisions( const char *cmd ) {
+
+ char *cmdcopy = strdup( cmd );
+ char *name, *ptr;
+ int i;
+
+ ptr = strchr( cmdcopy, (int) '/' );
+ name = ++ptr;
+ ptr = strchr( name, (int) '/' );
+ *ptr = '\0';
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ if( (IfInfo[i].OLDcollisions > 0)
+ && (strcmp( IfInfo[i].Name, name ) == 0) ) {
+ fprintf(CurrentClient, "%ld\n",
+ IfInfo[i].collisions - IfInfo[i].OLDcollisions );
+ free( cmdcopy );
+ return;
+ }
+ }
+ free( cmdcopy );
+ fprintf(CurrentClient, "0\n" );
+}
+
+void printMultiXmitsInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Multicasts Sent\t0\t0\tPackets\n" );
+}
+
+void printMultiXmits( const char *cmd ) {
+
+ char *cmdcopy = strdup( cmd );
+ char *name, *ptr;
+ int i;
+
+ ptr = strchr( cmdcopy, (int) '/' );
+ name = ++ptr;
+ ptr = strchr( name, (int) '/' );
+ *ptr = '\0';
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ if( (IfInfo[i].OLDmultixmt > 0)
+ && (strcmp( IfInfo[i].Name, name ) == 0) ) {
+ fprintf(CurrentClient, "%ld\n",
+ IfInfo[i].multixmt - IfInfo[i].OLDmultixmt );
+ free( cmdcopy );
+ return;
+ }
+ }
+ free( cmdcopy );
+ fprintf(CurrentClient, "0\n" );
+}
+
+void printMultiRecvsInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Multicasts Received\t0\t0\tPackets\n" );
+}
+
+void printMultiRecvs( const char *cmd ) {
+
+ char *cmdcopy = strdup( cmd );
+ char *name, *ptr;
+ int i;
+
+ ptr = strchr( cmdcopy, (int) '/' );
+ name = ++ptr;
+ ptr = strchr( name, (int) '/' );
+ *ptr = '\0';
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ if( (IfInfo[i].OLDmultircv > 0)
+ && (strcmp( IfInfo[i].Name, name ) == 0) ) {
+ fprintf(CurrentClient, "%ld\n",
+ IfInfo[i].multircv - IfInfo[i].OLDmultircv );
+ free( cmdcopy );
+ return;
+ }
+ }
+ free( cmdcopy );
+ fprintf(CurrentClient, "0\n" );
+}
+
+void printBcastXmitsInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Broadcasts Sent\t0\t0\tPackets\n" );
+}
+
+void printBcastXmits( const char *cmd ) {
+
+ char *cmdcopy = strdup( cmd );
+ char *name, *ptr;
+ int i;
+
+ ptr = strchr( cmdcopy, (int) '/' );
+ name = ++ptr;
+ ptr = strchr( name, (int) '/' );
+ *ptr = '\0';
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ if( (IfInfo[i].OLDbrdcstxmt > 0)
+ && (strcmp( IfInfo[i].Name, name ) == 0) ) {
+ fprintf(CurrentClient, "%ld\n",
+ IfInfo[i].brdcstxmt - IfInfo[i].OLDbrdcstxmt );
+ free( cmdcopy );
+ return;
+ }
+ }
+ free( cmdcopy );
+ fprintf(CurrentClient, "0\n" );
+}
+
+void printBcastRecvsInfo( const char *cmd ) {
+ fprintf(CurrentClient, "Broadcasts Received\t0\t0\tPackets\n" );
+}
+
+void printBcastRecvs( const char *cmd ) {
+
+ char *cmdcopy = strdup( cmd );
+ char *name, *ptr;
+ int i;
+
+ ptr = strchr( cmdcopy, (int) '/' );
+ name = ++ptr;
+ ptr = strchr( name, (int) '/' );
+ *ptr = '\0';
+
+ for( i = 0; i < NetDevCount; i++ ) {
+ if( (IfInfo[i].OLDbrdcstrcv > 0)
+ && (strcmp( IfInfo[i].Name, name ) == 0) ) {
+ fprintf(CurrentClient, "%ld\n",
+ IfInfo[i].brdcstrcv - IfInfo[i].OLDbrdcstrcv );
+ free( cmdcopy );
+ return;
+ }
+ }
+ free( cmdcopy );
+ fprintf(CurrentClient, "0\n" );
+}
diff --git a/ksysguard/ksysguardd/Tru64/NetDev.h b/ksysguard/ksysguardd/Tru64/NetDev.h
new file mode 100644
index 000000000..b6ff54448
--- /dev/null
+++ b/ksysguard/ksysguardd/Tru64/NetDev.h
@@ -0,0 +1,59 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 Chris Schlaeger <cs@kde.org>
+
+ Solaris support by Torsten Kasch <tk@Genetik.Uni-Bielefeld.DE>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _NetDev_h_
+#define _NetDev_h_
+
+void initNetDev(struct SensorModul* sm);
+void exitNetDev(void);
+
+int updateNetDev(void);
+
+void printIPacketsInfo( const char *cmd );
+void printIPackets( const char *cmd );
+
+void printOPacketsInfo( const char *cmd );
+void printOPackets( const char *cmd );
+
+void printIErrorsInfo( const char *cmd );
+void printIErrors( const char *cmd );
+
+void printOErrorsInfo( const char *cmd );
+void printOErrors( const char *cmd );
+
+void printCollisionsInfo( const char *cmd );
+void printCollisions( const char *cmd );
+
+void printMultiXmitsInfo( const char *cmd );
+void printMultiXmits( const char *cmd );
+
+void printMultiRecvsInfo( const char *cmd );
+void printMultiRecvs( const char *cmd );
+
+void printBcastXmitsInfo( const char *cmd );
+void printBcastXmits( const char *cmd );
+
+void printBcastRecvsInfo( const char *cmd );
+void printBcastRecvs( const char *cmd );
+
+#endif /* _NetDev_h */
diff --git a/ksysguard/ksysguardd/conf.c b/ksysguard/ksysguardd/conf.c
new file mode 100644
index 000000000..1d857137b
--- /dev/null
+++ b/ksysguard/ksysguardd/conf.c
@@ -0,0 +1,137 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Command.h"
+
+#include "conf.h"
+
+CONTAINER LogFileList = 0;
+CONTAINER SensorList = 0;
+char* RegisterDomain = 0;
+
+void LogFileList_cleanup( void *ptr );
+void freeConfigFile( void );
+
+void LogFileList_cleanup( void *ptr )
+{
+ if ( ptr ) {
+ if ( ((ConfigLogFile*)ptr)->name )
+ free( ((ConfigLogFile*)ptr)->name );
+
+ free( ptr );
+ }
+}
+
+void freeConfigFile( void )
+{
+ destr_ctnr( LogFileList, LogFileList_cleanup );
+ destr_ctnr( SensorList, free );
+}
+
+void parseConfigFile( const char *filename )
+{
+ FILE* config;
+ char line[ 2048 ];
+ char *begin, *token, *tmp;
+ ConfigLogFile *confLog;
+
+ LogFileList = new_ctnr();
+ SensorList = new_ctnr();
+
+ if ( ( config = fopen( filename, "r" ) ) == NULL ) {
+ log_error( "can't open config file '%s'", filename );
+
+ /**
+ If we can't open a config file we have to add the
+ available sensors manually
+ */
+ push_ctnr( SensorList, strdup( "ProcessList" ) );
+ push_ctnr( SensorList, strdup( "Memory" ) );
+ push_ctnr( SensorList, strdup( "Stat" ) );
+ push_ctnr( SensorList, strdup( "NetDev" ) );
+ push_ctnr( SensorList, strdup( "NetStat" ) );
+ push_ctnr( SensorList, strdup( "Apm" ) );
+ push_ctnr( SensorList, strdup( "Acpi" ) );
+ push_ctnr( SensorList, strdup( "CpuInfo" ) );
+ push_ctnr( SensorList, strdup( "LoadAvg" ) );
+ push_ctnr( SensorList, strdup( "LmSensors" ) );
+ push_ctnr( SensorList, strdup( "DiskStat" ) );
+ push_ctnr( SensorList, strdup( "LogFile" ) );
+ push_ctnr( SensorList, strdup( "DellLaptop" ) );
+
+ return;
+ }
+
+ while ( fgets( line, sizeof( line ), config ) != NULL ) {
+ if ( ( line[ 0 ] == '#') || ( strlen( line ) == 0 ) )
+ continue;
+
+ if ( strchr( line, '#' ) )
+ *( strchr( line, '#' ) ) = '\0';
+
+ if ( line[ strlen( line ) - 1 ] == '\n' )
+ line[ strlen( line ) - 1 ] = '\0';
+
+ if ( !strncmp( line, "RegisterDomain",14) && (begin = strchr( line, '=' )) ) RegisterDomain=strdup(begin+1);
+
+ if ( !strncmp( line, "LogFiles", 8 ) && (begin = strchr( line, '=' )) ) {
+ begin++;
+
+ for ( token = strtok( begin, "," ); token; token = strtok( NULL, "," ) ) {
+ if ( ( confLog = (ConfigLogFile *)malloc( sizeof( ConfigLogFile ) ) ) == NULL ) {
+ log_error( "malloc() no free memory avail" );
+ continue;
+ }
+ confLog->name = strdup( token );
+ tmp = strchr( confLog->name, ':' );
+ *tmp = '\0';
+ confLog->path = tmp;
+ confLog->path++;
+
+ push_ctnr( LogFileList, confLog );
+ }
+ }
+
+ if ( !strncmp( line, "Sensors", 7 ) && (begin = strchr( line, '=' )) ) {
+ begin++;
+
+ for ( token = strtok( begin, ","); token; token = strtok( NULL, "," ) )
+ push_ctnr( SensorList, strdup( token ) );
+ }
+ }
+
+ fclose( config );
+}
+
+int sensorAvailable( const char *sensor )
+{
+ char* name;
+
+ for ( name = first_ctnr( SensorList ); name; name = next_ctnr( SensorList ) ) {
+ if ( !strcmp( name, sensor ) )
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/ksysguard/ksysguardd/conf.h b/ksysguard/ksysguardd/conf.h
new file mode 100644
index 000000000..40be01ea8
--- /dev/null
+++ b/ksysguard/ksysguardd/conf.h
@@ -0,0 +1,38 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include "ccont.h"
+
+#ifndef KSG_CONF_H
+#define KSG_CONF_H
+
+typedef struct {
+ char *name;
+ char *path;
+} ConfigLogFile;
+
+extern char* RegisterDomain;
+
+void parseConfigFile( const char *filename );
+void freeConfigFile();
+
+int sensorAvailable( const char* sensor );
+
+#endif
diff --git a/ksysguard/ksysguardd/configure.in.in b/ksysguard/ksysguardd/configure.in.in
new file mode 100644
index 000000000..9a2f748a1
--- /dev/null
+++ b/ksysguard/ksysguardd/configure.in.in
@@ -0,0 +1,45 @@
+#MIN_CONFIG
+
+AC_ARG_ENABLE(dnssd, [ --disable-dnssd don't require libdns_sd (browsing and publishing DNS-SD services will not be possible) ], with_dnssd=$enableval, with_dnssd=yes)
+if test "$with_dnssd" = "yes"; then
+AC_MSG_CHECKING(for DNS-SD support)
+save_dnssdtest_LIBS="$LIBS"
+save_dnssdtest_LDFLAGS="$LDFLAGS"
+save_dnssdtest_CPPFLAGS="$CPPFLAGS"
+LDFLAGS="$all_libraries $LDFLAGS"
+CPPFLAGS="$CPPFLAGS $all_includes"
+case $host_os in
+ darwin*) LIBS="" ;;
+ *) LIBS="-ldns_sd" ;;
+esac
+have_libdns_sd="no"
+AC_TRY_LINK( [
+ #include <dns_sd.h>
+ ],[
+ DNSServiceRefDeallocate( (DNSServiceRef) 0);
+ TXTRecordDeallocate( (TXTRecordRef*) 0);
+ ],[
+ AC_DEFINE(HAVE_DNSSD,1,[Define if dns-sd is available])
+ case $host_os in
+ darwin*) LIB_DNSSD="" ;;
+ *) LIB_DNSSD="-ldns_sd" ;;
+ esac
+ have_libdns_sd="yes"
+ AC_MSG_RESULT(yes)
+ ],[
+ AC_MSG_RESULT(no)
+ LIB_DNSSD=""
+])
+CPPFLAGS=$save_dnssdtest_CPPFLAGS
+LDFLAGS=$save_dnssdtest_LDFLAGS
+LIBS=$save_dnssdtest_LIBS
+fi
+
+case $host_os in
+ dragonfly*) LIB_KINFO="-lkinfo" ;;
+ *) LIB_KINFO="" ;;
+esac
+
+AC_SUBST(LIB_DNSSD)
+AC_SUBST(LIB_KINFO)
+AM_CONDITIONAL(HAVE_DNSSD, test "$have_libdns_sd" = "yes")
diff --git a/ksysguard/ksysguardd/ksysguardd.c b/ksysguard/ksysguardd/ksysguardd.c
new file mode 100644
index 000000000..faea19492
--- /dev/null
+++ b/ksysguard/ksysguardd/ksysguardd.c
@@ -0,0 +1,633 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 - 2003 Chris Schlaeger <cs@kde.org>
+ Tobias Koenig <tokoe@kde.org>
+
+ Solaris support by Torsten Kasch <tk@Genetik.Uni-Bielefeld.DE>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <config.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+#include <../version.h>
+#ifdef HAVE_DNSSD
+#include <dns_sd.h>
+#endif
+#include "modules.h"
+
+#include "ksysguardd.h"
+
+#define CMDBUFSIZE 128
+#define MAX_CLIENTS 100
+
+typedef struct {
+ int socket;
+ FILE* out;
+} ClientInfo;
+
+static int ServerSocket;
+static ClientInfo ClientList[ MAX_CLIENTS ];
+static int SocketPort = -1;
+static unsigned char BindToAllInterfaces = 0;
+static int CurrentSocket;
+static const char *LockFile = "/var/run/ksysguardd.pid";
+static const char *ConfigFile = KSYSGUARDDRCFILE;
+#ifdef HAVE_DNSSD
+static int ServiceSocket = -1;
+static DNSServiceRef Ref;
+#endif
+
+void signalHandler( int sig );
+void makeDaemon( void );
+void resetClientList( void );
+int addClient( int client );
+int delClient( int client );
+int createServerSocket( void );
+#ifdef HAVE_DNSSD
+void publish_callback (DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name,
+ const char*, const char*, void *context);
+#endif
+
+/**
+ This variable is set to 1 if a module requests that the daemon should
+ be terminated.
+ */
+int QuitApp = 0;
+
+/**
+ This variable indicates whether we are running as daemon or (1) or if
+ we were have a controlling shell.
+ */
+int RunAsDaemon = 0;
+
+/**
+ This pointer is used by all modules. It contains the file pointer of
+ the currently served client. This is stdout for non-daemon mode.
+ */
+FILE* CurrentClient = 0;
+
+static int processArguments( int argc, char* argv[] )
+{
+ int option;
+
+ opterr = 0;
+ while ( ( option = getopt( argc, argv, "-p:f:dih" ) ) != EOF ) {
+ switch ( tolower( option ) ) {
+ case 'p':
+ SocketPort = atoi( optarg );
+ break;
+ case 'f':
+ ConfigFile = strdup( optarg );
+ break;
+ case 'd':
+ RunAsDaemon = 1;
+ break;
+ case 'i':
+ BindToAllInterfaces = 1;
+ break;
+ case '?':
+ case 'h':
+ default:
+ fprintf(stderr, "Usage: %s [-d] [-i] [-p port]\n", argv[ 0 ] );
+ return -1;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static void printWelcome( FILE* out )
+{
+ fprintf( out, "ksysguardd %s\n"
+ "(c) 1999, 2000, 2001, 2002 Chris Schlaeger <cs@kde.org> and\n"
+ "(c) 2001 Tobias Koenig <tokoe@kde.org>\n"
+ "This program is part of the KDE Project and licensed under\n"
+ "the GNU GPL version 2. See http://www.kde.org for details.\n",
+ KSYSGUARD_VERSION );
+
+ fflush( out );
+}
+
+static int createLockFile()
+{
+ FILE *file;
+
+ if ( ( file = fopen( LockFile, "w+" ) ) != NULL ) {
+ struct flock lock;
+ lock.l_type = F_WRLCK;
+ lock.l_whence = 0;
+ lock.l_start = 0;
+ lock.l_len = 0;
+ lock.l_pid = -1;
+ if ( fcntl( fileno( file ), F_SETLK, &lock ) < 0 ) {
+ if ( ( errno == EACCES ) || ( errno == EAGAIN ) ) {
+ log_error( "ksysguardd is running already" );
+ fprintf( stderr, "ksysguardd is running already\n" );
+ fclose( file );
+ return -1;
+ }
+ }
+
+ fseek( file, 0, SEEK_SET );
+ fprintf( file, "%d\n", getpid() );
+ fflush( file );
+ ftruncate( fileno( file ), ftell( file ) );
+ } else {
+ log_error( "Cannot create lockfile '%s'", LockFile );
+ fprintf( stderr, "Cannot create lockfile '%s'\n", LockFile );
+ return -2;
+ }
+
+ /**
+ We abandon 'file' here on purpose. It's needed nowhere else, but we
+ have to keep the file open and locked. The kernel will remove the
+ lock when the process terminates and the runlevel scripts has to
+ remove the pid file.
+ */
+ return 0;
+}
+
+void signalHandler( int sig )
+{
+ switch ( sig ) {
+ case SIGQUIT:
+ case SIGTERM:
+#ifdef HAVE_DNSSD
+ if ( ServiceSocket != -1 ) DNSServiceRefDeallocate(Ref);
+#endif
+ exit( 0 );
+ break;
+ }
+}
+
+static void installSignalHandler( void )
+{
+ struct sigaction Action;
+
+ Action.sa_handler = signalHandler;
+ sigemptyset( &Action.sa_mask );
+ /* make sure that interrupted system calls are restarted. */
+ Action.sa_flags = SA_RESTART;
+ sigaction( SIGTERM, &Action, 0 );
+ sigaction( SIGQUIT, &Action, 0 );
+}
+
+static void dropPrivileges( void )
+{
+ struct passwd *pwd;
+
+ if ( ( pwd = getpwnam( "nobody" ) ) != NULL ) {
+ if ( !setgid(pwd->pw_gid) )
+ setuid(pwd->pw_uid);
+ if (!geteuid() && getuid() != pwd->pw_uid)
+ _exit(1);
+ }
+ else {
+ log_error( "User 'nobody' does not exist." );
+ /**
+ We exit here to avoid becoming vulnerable just because
+ user nobody does not exist.
+ */
+ _exit(1);
+ }
+}
+
+void makeDaemon( void )
+{
+ int fd = -1;
+ switch ( fork() ) {
+ case -1:
+ log_error( "fork() failed" );
+ break;
+ case 0:
+ setsid();
+ chdir( "/" );
+ umask( 0 );
+ if ( createLockFile() < 0 )
+ _exit( 1 );
+
+ dropPrivileges();
+ installSignalHandler();
+
+ fd = open("/dev/null", O_RDWR, 0);
+ if (fd != -1) {
+ dup2(fd, STDIN_FILENO);
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDERR_FILENO);
+ close (fd);
+ }
+ break;
+ default:
+ exit( 0 );
+ }
+}
+
+static int readCommand( int fd, char* cmdBuf, size_t len )
+{
+ unsigned int i;
+ char c;
+ for ( i = 0; i < len; ++i )
+ {
+ int result = read( fd, &c, 1 );
+ if (result < 0)
+ return -1; /* Error */
+
+ if (result == 0) {
+ if (i == 0)
+ return -1; /* Connection lost */
+
+ break; /* End of data */
+ }
+
+ if (c == '\n')
+ break; /* End of line */
+
+ cmdBuf[ i ] = c;
+ }
+ cmdBuf[i] = '\0';
+
+ return i;
+}
+
+void resetClientList( void )
+{
+ int i;
+
+ for ( i = 0; i < MAX_CLIENTS; i++ ) {
+ ClientList[ i ].socket = -1;
+ ClientList[ i ].out = 0;
+ }
+}
+
+/**
+ addClient adds a new client to the ClientList.
+ */
+int addClient( int client )
+{
+ int i;
+ FILE* out;
+
+ for ( i = 0; i < MAX_CLIENTS; i++ ) {
+ if ( ClientList[ i ].socket == -1 ) {
+ ClientList[ i ].socket = client;
+ if ( ( out = fdopen( client, "w+" ) ) == NULL ) {
+ log_error( "fdopen()" );
+ return -1;
+ }
+ /* We use unbuffered IO */
+ fcntl( fileno( out ), F_SETFL, O_NDELAY );
+ ClientList[ i ].out = out;
+ printWelcome( out );
+ fprintf( out, "ksysguardd> " );
+ fflush( out );
+
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+/**
+ delClient removes a client from the ClientList.
+ */
+int delClient( int client )
+{
+ int i;
+
+ for ( i = 0; i < MAX_CLIENTS; i++ ) {
+ if ( ClientList[i].socket == client ) {
+ fclose( ClientList[ i ].out );
+ ClientList[ i ].out = 0;
+ close( ClientList[ i ].socket );
+ ClientList[ i ].socket = -1;
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+#ifdef HAVE_DNSSD
+void publish_callback (DNSServiceRef ref, DNSServiceFlags f, DNSServiceErrorType errorCode, const char *name,
+ const char* type, const char* domain, void *context)
+{
+ if (errorCode != kDNSServiceErr_NoError) log_error("Publishing DNS-SD service failed with error %i",errorCode);
+}
+#endif
+
+
+int createServerSocket()
+{
+ int i = 1;
+ int newSocket;
+ struct sockaddr_in s_in;
+ struct servent *service;
+
+ if ( ( newSocket = socket( PF_INET, SOCK_STREAM, 0 ) ) < 0 ) {
+ log_error( "socket()" );
+ return -1;
+ }
+
+ setsockopt( newSocket, SOL_SOCKET, SO_REUSEADDR, &i, sizeof( i ) );
+
+ /**
+ The -p command line option always overrides the default or the
+ service entry.
+ */
+ if ( SocketPort == -1 ) {
+ if ( ( service = getservbyname( "ksysguardd", "tcp" ) ) == NULL ) {
+ /**
+ No entry in service directory and no command line request,
+ so we take the build-in default (the offical IANA port).
+ */
+ SocketPort = PORT_NUMBER;
+ } else
+ SocketPort = htons( service->s_port );
+ }
+
+ memset( &s_in, 0, sizeof( struct sockaddr_in ) );
+ s_in.sin_family = AF_INET;
+ if ( BindToAllInterfaces )
+ s_in.sin_addr.s_addr = htonl( INADDR_ANY );
+ else
+ s_in.sin_addr.s_addr = htonl( INADDR_LOOPBACK );
+ s_in.sin_port = htons( SocketPort );
+
+ if ( bind( newSocket, (struct sockaddr*)&s_in, sizeof( s_in ) ) < 0 ) {
+ log_error( "Cannot bind to port %d", SocketPort );
+ return -1;
+ }
+
+ if ( listen( newSocket, 5 ) < 0 ) {
+ log_error( "listen()" );
+ return -1;
+ }
+
+#ifdef HAVE_DNSSD
+ if ( BindToAllInterfaces )
+ if (DNSServiceRegister(&Ref, 0, 0, 0, "_ksysguard._tcp", RegisterDomain ?
+ RegisterDomain : "local.",NULL, htons(SocketPort), 0, 0, publish_callback, 0) == kDNSServiceErr_NoError)
+ ServiceSocket = DNSServiceRefSockFD(Ref);
+#endif
+
+ return newSocket;
+}
+
+static int setupSelect( fd_set* fds )
+{
+ int highestFD = ServerSocket;
+ FD_ZERO( fds );
+ /**
+ Fill the filedescriptor array with all relevant descriptors. If we
+ not in daemon mode we only need to watch stdin.
+ */
+ if ( RunAsDaemon ) {
+ int i;
+ FD_SET( ServerSocket, fds );
+#ifdef HAVE_DNSSD
+ if ( ServiceSocket != -1 ) {
+ FD_SET( ServiceSocket, fds );
+ if ( highestFD < ServiceSocket) highestFD = ServiceSocket;
+ }
+#endif
+
+ for ( i = 0; i < MAX_CLIENTS; i++ ) {
+ if ( ClientList[ i ].socket != -1 ) {
+ FD_SET( ClientList[ i ].socket, fds );
+ if ( highestFD < ClientList[ i ].socket )
+ highestFD = ClientList[ i ].socket;
+ }
+ }
+ } else {
+ FD_SET( STDIN_FILENO, fds );
+ if ( highestFD < STDIN_FILENO )
+ highestFD = STDIN_FILENO;
+ }
+
+ return highestFD;
+}
+
+static void checkModules()
+{
+ struct SensorModul *entry;
+
+ for ( entry = SensorModulList; entry->configName != NULL; entry++ )
+ if ( entry->checkCommand != NULL && entry->available )
+ entry->checkCommand();
+}
+
+static void handleTimerEvent( struct timeval* tv, struct timeval* last )
+{
+ struct timeval now;
+ gettimeofday( &now, NULL );
+ /* Check if the last event was really TIMERINTERVAL seconds ago */
+ if ( now.tv_sec - last->tv_sec >= TIMERINTERVAL ) {
+ /* If so, update all sensors and save current time to last. */
+ checkModules();
+ *last = now;
+ }
+ /**
+ Set tv so that the next timer event will be generated in
+ TIMERINTERVAL seconds.
+ */
+ tv->tv_usec = last->tv_usec - now.tv_usec;
+ if ( tv->tv_usec < 0 ) {
+ tv->tv_usec += 1000000;
+ tv->tv_sec = last->tv_sec + TIMERINTERVAL - 1 - now.tv_sec;
+ } else
+ tv->tv_sec = last->tv_sec + TIMERINTERVAL - now.tv_sec;
+}
+
+static void handleSocketTraffic( int socketNo, const fd_set* fds )
+{
+ char cmdBuf[ CMDBUFSIZE ];
+
+ if ( RunAsDaemon ) {
+ int i;
+
+ if ( FD_ISSET( socketNo, fds ) ) {
+ int clientsocket;
+ struct sockaddr addr;
+ kde_socklen_t addr_len = sizeof( struct sockaddr );
+
+ /* a new connection */
+ if ( ( clientsocket = accept( socketNo, &addr, &addr_len ) ) < 0 ) {
+ log_error( "accept()" );
+ exit( 1 );
+ } else
+ addClient( clientsocket );
+ }
+
+#ifdef HAVE_DNSSD
+ if ( ServiceSocket != -1 && FD_ISSET( ServiceSocket, fds )) DNSServiceProcessResult(Ref);
+#endif
+
+ for ( i = 0; i < MAX_CLIENTS; i++ ) {
+ if ( ClientList[ i ].socket != -1 ) {
+ CurrentSocket = ClientList[ i ].socket;
+ if ( FD_ISSET( ClientList[ i ].socket, fds ) ) {
+ ssize_t cnt;
+ if ( ( cnt = readCommand( CurrentSocket, cmdBuf, sizeof( cmdBuf ) - 1 ) ) <= 0 )
+ delClient( CurrentSocket );
+ else {
+ cmdBuf[ cnt ] = '\0';
+ if ( strncmp( cmdBuf, "quit", 4 ) == 0 )
+ delClient( CurrentSocket );
+ else {
+ CurrentClient = ClientList[ i ].out;
+ fflush( stdout );
+ executeCommand( cmdBuf );
+ fprintf( CurrentClient, "ksysguardd> " );
+ fflush( CurrentClient );
+ }
+ }
+ }
+ }
+ }
+ } else if ( FD_ISSET( STDIN_FILENO, fds ) ) {
+ if (readCommand( STDIN_FILENO, cmdBuf, sizeof( cmdBuf ) ) < 0) {
+ exit(0);
+ }
+ executeCommand( cmdBuf );
+ printf( "ksysguardd> " );
+ fflush( stdout );
+ }
+}
+
+static void initModules()
+{
+ struct SensorModul *entry;
+
+ /* initialize all sensors */
+ initCommand();
+
+ for ( entry = SensorModulList; entry->configName != NULL; entry++ ) {
+ if ( entry->initCommand != NULL && sensorAvailable( entry->configName ) ) {
+ entry->available = 1;
+ entry->initCommand( entry );
+ }
+ }
+
+ ReconfigureFlag = 0;
+}
+
+static void exitModules()
+{
+ struct SensorModul *entry;
+
+ for ( entry = SensorModulList; entry->configName != NULL; entry++ ) {
+ if ( entry->exitCommand != NULL && entry->available )
+ entry->exitCommand();
+ }
+
+ exitCommand();
+}
+
+/*
+================================ public part =================================
+*/
+
+int main( int argc, char* argv[] )
+{
+ fd_set fds;
+ struct timeval tv;
+ struct timeval last;
+
+#ifdef OSTYPE_FreeBSD
+ /**
+ If we are not root or the executable does not belong to the
+ kmem group, ksysguardd will crash because of permission problems
+ for opening /dev/kmem
+ */
+ struct group* grentry = NULL;
+
+ if ( geteuid() != 0 ) {
+ grentry = getgrnam( "kmem" );
+ if ( grentry == NULL ) {
+ fprintf( stderr, "the group kmem is missing on your system\n" );
+ return -1;
+ }
+
+ if ( getegid() != grentry->gr_gid ) {
+ fprintf( stderr, "ksysguardd can't be started because of permission conflicts!\n"
+ "Start the program as user 'root' or change its group to 'kmem' and set the sgid-bit\n" );
+ return -1;
+ }
+
+ endgrent();
+ }
+#endif
+
+ printWelcome( stdout );
+
+ if ( processArguments( argc, argv ) < 0 )
+ return -1;
+
+ parseConfigFile( ConfigFile );
+
+ initModules();
+
+ if ( RunAsDaemon ) {
+ makeDaemon();
+
+ if ( ( ServerSocket = createServerSocket() ) < 0 )
+ return -1;
+ resetClientList();
+ } else {
+ fprintf( stdout, "ksysguardd> " );
+ fflush( stdout );
+ CurrentClient = stdout;
+ ServerSocket = 0;
+ }
+
+ tv.tv_sec = TIMERINTERVAL;
+ tv.tv_usec = 0;
+ gettimeofday( &last, NULL );
+
+ while ( !QuitApp ) {
+ int highestFD = setupSelect( &fds );
+ /* wait for communication or timeouts */
+ if ( select( highestFD + 1, &fds, NULL, NULL, &tv ) >= 0 ) {
+ handleTimerEvent( &tv, &last );
+ handleSocketTraffic( ServerSocket, &fds );
+ }
+ }
+
+ exitModules();
+
+ freeConfigFile();
+
+ return 0;
+}
diff --git a/ksysguard/ksysguardd/ksysguardd.h b/ksysguard/ksysguardd/ksysguardd.h
new file mode 100644
index 000000000..10184acd0
--- /dev/null
+++ b/ksysguard/ksysguardd/ksysguardd.h
@@ -0,0 +1,52 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999-2001 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KSG_KSYSGUARDD_H
+#define KSG_KSYSGUARDD_H
+
+#include <stdio.h>
+#include <time.h>
+
+/* This is the official ksysguardd port assigned by IANA. */
+#define PORT_NUMBER 3112
+
+/* Timer interval for checking modules */
+#define TIMERINTERVAL 1
+
+/* Timer interval for update modules */
+#define UPDATEINTERVAL 1
+
+extern int RunAsDaemon;
+extern int QuitApp;
+
+/* This pointer give you access to the client which made the request */
+extern FILE* CurrentClient;
+
+struct SensorModul {
+ const char *configName;
+ void (*initCommand)( struct SensorModul* );
+ void (*exitCommand)( void );
+ int (*updateCommand)( void );
+ void (*checkCommand)( void );
+ int available;
+ time_t time;
+};
+
+#endif
diff --git a/ksysguard/ksysguardd/modules.h b/ksysguard/ksysguardd/modules.h
new file mode 100644
index 000000000..5c214c7f0
--- /dev/null
+++ b/ksysguard/ksysguardd/modules.h
@@ -0,0 +1,151 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 2001 Tobias Koenig <tokoe@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KSG_MODULES_H
+#define KSG_MODULES_H
+
+#include "Command.h"
+#include "conf.h"
+#include "ksysguardd.h"
+
+#ifdef OSTYPE_Linux
+#include "Memory.h"
+#include "ProcessList.h"
+#include "acpi.h"
+#include "apm.h"
+#include "cpuinfo.h"
+#include "diskstat.h"
+#include "i8k.h"
+#include "lmsensors.h"
+#include "loadavg.h"
+#include "logfile.h"
+#include "netdev.h"
+#include "netstat.h"
+#include "stat.h"
+#endif /* OSTYPE_Linux */
+
+#ifdef OSTYPE_FreeBSD
+#include <grp.h>
+#include "CPU.h"
+#include "Memory.h"
+#include "ProcessList.h"
+#ifdef __i386__
+#include "apm.h"
+#endif
+#include "diskstat.h"
+#include "loadavg.h"
+#include "logfile.h"
+#include "netdev.h"
+#endif /* OSTYPE_FreeBSD */
+
+#ifdef OSTYPE_Solaris
+#include "LoadAvg.h"
+#include "Memory.h"
+#include "NetDev.h"
+#include "ProcessList.h"
+#endif /* OSTYPE_Solaris */
+
+#ifdef OSTYPE_Irix
+#include "LoadAvg.h"
+#include "Memory.h"
+#include "NetDev.h"
+#include "ProcessList.h"
+#include "cpu.h"
+#endif /* OSTYPE_Irix */
+
+#ifdef OSTYPE_Tru64
+#include "LoadAvg.h"
+#include "Memory.h"
+#include "NetDev.h"
+#endif /* OSTYPE_Tru64 */
+
+#ifdef OSTYPE_OpenBSD
+#include "cpu.h"
+#include "memory.h"
+#endif /* OSTYPE_OpenBSD */
+
+typedef void (*VSFunc)( struct SensorModul* );
+#define NULLVSFUNC ((VSFunc) 0)
+typedef void (*VVFunc)( void );
+#define NULLVVFUNC ((VVFunc) 0)
+typedef int (*IVFunc)( void );
+#define NULLIVFUNC ((IVFunc) 0)
+#define NULLTIME ((time_t) 0)
+
+struct SensorModul SensorModulList[] = {
+#ifdef OSTYPE_Linux
+ { "ProcessList", initProcessList, exitProcessList, updateProcessList, NULLVVFUNC, 0, NULLTIME },
+ { "Memory", initMemory, exitMemory, updateMemory, NULLVVFUNC, 0, NULLTIME },
+ { "Stat", initStat, exitStat, updateStat, NULLVVFUNC, 0, NULLTIME },
+ { "NetDev", initNetDev, exitNetDev, updateNetDev, NULLVVFUNC, 0, NULLTIME },
+ { "NetStat", initNetStat, exitNetStat, NULLIVFUNC, NULLVVFUNC, 0, NULLTIME },
+ { "Apm", initApm, exitApm, updateApm, NULLVVFUNC, 0, NULLTIME },
+ { "Acpi", initAcpi, exitAcpi, updateAcpi, NULLVVFUNC, 0, NULLTIME },
+ { "CpuInfo", initCpuInfo, exitCpuInfo, updateCpuInfo, NULLVVFUNC, 0, NULLTIME },
+ { "LoadAvg", initLoadAvg, exitLoadAvg, updateLoadAvg, NULLVVFUNC, 0, NULLTIME },
+ { "LmSensors", initLmSensors, exitLmSensors, NULLIVFUNC, NULLVVFUNC, 0, NULLTIME },
+ { "DiskStat", initDiskStat, exitDiskStat, updateDiskStat, checkDiskStat, 0, NULLTIME },
+ { "LogFile", initLogFile, exitLogFile, NULLIVFUNC, NULLVVFUNC, 0, NULLTIME },
+ { "DellLaptop", initI8k, exitI8k, updateI8k, NULLVVFUNC, 0, NULLTIME },
+#endif /* OSTYPE_Linux */
+
+#ifdef OSTYPE_FreeBSD
+ { "CpuInfo", initCpuInfo, exitCpuInfo, updateCpuInfo, NULLVVFUNC, 0, NULLTIME },
+ { "Memory", initMemory, exitMemory, updateMemory, NULLVVFUNC, 0, NULLTIME },
+ { "ProcessList", initProcessList, exitProcessList, updateProcessList, NULLVVFUNC, 0, NULLTIME },
+#ifdef __i386__
+ { "Apm", initApm, exitApm, updateApm, NULLVVFUNC, 0, NULLTIME },
+#endif
+ { "DiskStat", initDiskStat, exitDiskStat, updateDiskStat, checkDiskStat, 0, NULLTIME },
+ { "LoadAvg", initLoadAvg, exitLoadAvg, updateLoadAvg, NULLVVFUNC, 0, NULLTIME },
+ { "LogFile", initLogFile, exitLogFile, NULLIVFUNC, NULLVVFUNC, 0, NULLTIME },
+ { "NetDev", initNetDev, exitNetDev, updateNetDev, checkNetDev, 0, NULLTIME },
+#endif /* OSTYPE_FreeBSD */
+
+#ifdef OSTYPE_Solaris
+ { "LoadAvg", initLoadAvg, exitLoadAvg, updateLoadAvg, NULLVVFUNC, 0, NULLTIME },
+ { "Memory", initMemory, exitMemory, updateMemory, NULLVVFUNC, 0, NULLTIME },
+ { "NetDev", initNetDev, exitNetDev, updateNetDev, NULLVVFUNC, 0, NULLTIME },
+ { "ProcessList", initProcessList, exitProcessList, updateProcessList, NULLVVFUNC, 0, NULLTIME },
+#endif /* OSTYPE_Solaris */
+
+#ifdef OSTYPE_Irix
+ { "CpuInfo", initCpuInfo, exitCpuInfo, updateCpuInfo, NULLVVFUNC, 0, NULLTIME },
+ { "LoadAvg", initLoadAvg, exitLoadAvg, updateLoadAvg, NULLVVFUNC, 0, NULLTIME },
+ { "Memory", initMemory, exitMemory, updateMemory, NULLVVFUNC, 0, NULLTIME },
+ { "NetDev", initNetDev, exitNetDev, updateNetDev, NULLVVFUNC, 0, NULLTIME },
+ { "ProcessList", initProcessList, exitProcessList, updateProcessList, NULLVVFUNC, 0, NULLTIME },
+#endif /* OSTYPE_Irix */
+
+#ifdef OSTYPE_Tru64
+ { "LoadAvg", initLoadAvg, exitLoadAvg, updateLoadAvg, NULLVVFUNC, 0, NULLTIME },
+ { "Memory", initMemory, exitMemory, updateMemory, NULLVVFUNC, 0, NULLTIME },
+ { "NetDev", initNetDev, exitNetDev, updateNetDev, NULLVVFUNC, 0, NULLTIME },
+#endif /* OSTYPE_Tru64 */
+
+#ifdef OSTYPE_OpenBSD
+ { "CpuInfo", initCpuInfo, exitCpuInfo, updateCpuInfo, NULLVVFUNC, 0, NULLTIME },
+ { "Memory", initMemory, exitMemory, updateMemory, NULLVVFUNC, 0, NULLTIME },
+#endif /* OSTYPE_OpenBSD */
+
+ { NULL, NULLVSFUNC, NULLVVFUNC, NULLIVFUNC, NULLVVFUNC, 0, NULLTIME }
+};
+
+#endif