diff options
Diffstat (limited to 'ksysguard/ksysguardd/Linux/lmsensors.c')
-rw-r--r-- | ksysguard/ksysguardd/Linux/lmsensors.c | 309 |
1 files changed, 309 insertions, 0 deletions
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 |