diff --git a/ksysguardd/Command.c b/ksysguardd/Command.c index 0f5dd3fa..13b73ae5 100644 --- a/ksysguardd/Command.c +++ b/ksysguardd/Command.c @@ -1,328 +1,328 @@ /* KSysGuard, the KDE System Guard Copyright (c) 1999 - 2001 Chris Schlaeger 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. */ -#define _POSIX_C_SOURCE 200809L /* sig.*set */ +#define _XOPEN_SOURCE 700 /* gettimeofday, and implies POSIX.1-2008's sig.*set */ #include #include #include #include #include #include #include #include "ccont.h" #include "ksysguardd.h" #include "Command.h" typedef struct { char* command; cmdExecutor ex; char* type; int isMonitor; int isLegacy; 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 output( const char *fmt, ...) { if( !CurrentClient ) return; va_list az; va_start( az, fmt ); if(vfprintf(CurrentClient, fmt, az) < 0) { fprintf(stderr, "Error talking to client. Exiting\n."); exit(EXIT_FAILURE); } va_end( az ); } 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 ) output( "\033%s\033", errmsg ); } void log_error( const char *fmt, ... ) { static int maxLogs = 0; if(maxLogs++ > 10) return; 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 ) ); if(!cmd || !(cmd->command = (char*)malloc( strlen( command ) + 1 ))) { print_error("Out of memory"); free(cmd); return; } 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 ( cmd->command && strcmp( cmd->command, command ) == 0 ) { remove_ctnr( CommandList ); free( cmd->command ); if ( cmd->type ) free( cmd->type ); free( cmd ); } } ReconfigureFlag = 1; } void registerAnyMonitor( const char* command, const char* type, cmdExecutor ex, cmdExecutor iq, struct SensorModul* sm, int isLegacy ) { /* 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 ) ); if(!cmd || !(cmd->command = (char*)malloc( strlen( command ) + 1 ))) { print_error("Out of memory"); free(cmd); return; } strcpy( cmd->command, command ); cmd->ex = ex; cmd->type = (char*)malloc( strlen( type ) + 1 ); if(!cmd->type ) { print_error("Out of memory"); free(cmd); return; } strcpy( cmd->type, type ); cmd->isMonitor = 1; cmd->isLegacy = isLegacy; cmd->sm = sm; push_ctnr( CommandList, cmd ); cmd = (Command*)malloc( sizeof( Command ) ); if(!cmd ) { print_error("Out of memory"); return; } cmd->command = (char*)malloc( strlen( command ) + 2 ); if(!cmd->command ) { print_error("Out of memory"); free(cmd); return; } 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 registerMonitor( const char* command, const char* type, cmdExecutor ex, cmdExecutor iq, struct SensorModul* sm ) { int legacyFlag = 0; registerAnyMonitor( command, type, ex, iq, sm, legacyFlag ); } void registerLegacyMonitor( const char* command, const char* type, cmdExecutor ex, cmdExecutor iq, struct SensorModul* sm ) { int legacyFlag = 1; registerAnyMonitor( command, type, ex, iq, sm, legacyFlag ); } void removeMonitor( const char* command ) { char* buf; removeCommand( command ); buf = (char*)malloc( strlen( command ) + 2 ); if(!buf ) { print_error("Out of memory"); return; } strcpy( buf, command ); strcat( buf, "?" ); removeCommand( buf ); free( buf ); } void executeCommand( const char* command ) { Command* cmd; int i = 0; while(command[i] != 0 && command[i] != ' ' && command[i] != '\t' ) i++; if( i <= 0 ) return; /* No command give at all */ int lengthOfCommand = i; for ( cmd = first_ctnr( CommandList ); cmd; cmd = next_ctnr( CommandList ) ) { if ( strncmp( cmd->command, command, lengthOfCommand ) == 0 && cmd->command[lengthOfCommand] == 0) { if ( cmd->isMonitor && cmd->sm->updateCommand != NULL) { struct timeval currentTime; gettimeofday(¤tTime,NULL); unsigned long long timeCentiSeconds = (unsigned long long)currentTime.tv_sec * 10 + currentTime.tv_usec / 100000; if ( timeCentiSeconds - cmd->sm->timeCentiSeconds >= UPDATEINTERVAL ) { cmd->sm->timeCentiSeconds = timeCentiSeconds; cmd->sm->updateCommand(); } } (*(cmd->ex))( command ); if ( ReconfigureFlag ) { ReconfigureFlag = 0; print_error( "RECONFIGURE" ); } fflush( CurrentClient ); return; } } if ( CurrentClient ) { output( "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 && !cmd->isLegacy ) output( "%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 ) { output( "1\n" ); fflush( CurrentClient ); return; } } output( "0\n" ); fflush( CurrentClient ); } void exQuit( const char* cmd ) { (void)cmd; QuitApp = 1; }