2009-10-11 20:11:09 +00:00
// vim:ts=8:expandtab
# include <stdlib.h>
# include <limits.h>
# include <stdio.h>
# include <string.h>
2012-03-25 18:55:55 +00:00
# include <yajl/yajl_gen.h>
2012-04-08 12:05:47 +00:00
# include <yajl/yajl_version.h>
2009-10-11 20:11:09 +00:00
# include "i3status.h"
2012-11-14 01:29:55 +00:00
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
2009-10-11 20:11:09 +00:00
# include <err.h>
# include <sys/types.h>
# include <sys/sysctl.h>
# define TZ_ZEROC 2732
# define TZ_KELVTOC(x) (((x) - TZ_ZEROC) / 10), abs(((x) - TZ_ZEROC) % 10)
2013-03-19 18:08:35 +00:00
# define TZ_AVG(x) ((x) - TZ_ZEROC) / 10
2009-10-11 20:11:09 +00:00
# endif
2012-04-29 14:59:39 +00:00
# if defined(__OpenBSD__)
# include <sys/param.h>
# include <sys/types.h>
# include <sys/sysctl.h>
# include <sys/sensors.h>
# include <errno.h>
# include <err.h>
2012-10-10 07:57:32 +00:00
# define MUKTOC(v) ((v - 273150000) / 1000000.0)
2012-04-29 14:59:39 +00:00
# endif
2013-10-06 21:18:53 +00:00
# if defined(__NetBSD__)
# include <fcntl.h>
# include <prop/proplib.h>
# include <sys/envsys.h>
# define MUKTOC(v) ((v - 273150000) / 1000000.0)
# endif
2009-10-11 20:11:09 +00:00
static char * thermal_zone ;
/*
* Reads the CPU temperature from / sys / class / thermal / thermal_zone0 / temp and
* returns the temperature in degree celcius .
*
*/
2012-10-10 07:57:32 +00:00
void print_cpu_temperature_info ( yajl_gen json_gen , char * buffer , int zone , const char * path , const char * format , int max_threshold ) {
2013-02-28 13:15:22 +00:00
char * outwalk = buffer ;
2011-07-24 21:17:34 +00:00
# ifdef THERMAL_ZONE
2009-10-11 20:11:09 +00:00
const char * walk ;
2013-01-13 12:23:43 +00:00
bool colorful_output = false ;
2009-10-11 20:11:09 +00:00
2013-10-24 17:19:21 +00:00
if ( thermal_zone = = NULL ) {
if ( path = = NULL )
asprintf ( & thermal_zone , THERMAL_ZONE , zone ) ;
else
asprintf ( & thermal_zone , path , zone ) ;
}
2012-05-04 03:34:13 +00:00
path = thermal_zone ;
2009-10-11 20:11:09 +00:00
2012-03-25 18:55:55 +00:00
INSTANCE ( path ) ;
2012-02-16 23:29:29 +00:00
2009-10-11 20:11:09 +00:00
for ( walk = format ; * walk ! = ' \0 ' ; walk + + ) {
if ( * walk ! = ' % ' ) {
2012-03-25 18:55:55 +00:00
* ( outwalk + + ) = * walk ;
2009-10-11 20:11:09 +00:00
continue ;
}
if ( BEGINS_WITH ( walk + 1 , " degrees " ) ) {
# if defined(LINUX)
2013-01-28 10:37:23 +00:00
static char buf [ 16 ] ;
2009-10-11 20:11:09 +00:00
long int temp ;
2011-01-06 17:22:46 +00:00
if ( ! slurp ( path , buf , sizeof ( buf ) ) )
2011-08-25 21:24:06 +00:00
goto error ;
2009-10-11 20:11:09 +00:00
temp = strtol ( buf , NULL , 10 ) ;
if ( temp = = LONG_MIN | | temp = = LONG_MAX | | temp < = 0 )
2012-03-25 18:55:55 +00:00
* ( outwalk + + ) = ' ? ' ;
2012-10-16 08:52:57 +00:00
else {
if ( ( temp / 1000 ) > = max_threshold ) {
START_COLOR ( " color_bad " ) ;
colorful_output = true ;
}
2012-03-25 18:55:55 +00:00
outwalk + = sprintf ( outwalk , " %ld " , ( temp / 1000 ) ) ;
2013-01-13 12:23:43 +00:00
if ( colorful_output ) {
2012-10-16 08:52:57 +00:00
END_COLOR ;
2013-01-13 12:23:43 +00:00
colorful_output = false ;
}
2012-10-16 08:52:57 +00:00
}
2012-11-14 01:29:55 +00:00
# elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
2009-10-11 20:11:09 +00:00
int sysctl_rslt ;
size_t sysctl_size = sizeof ( sysctl_rslt ) ;
2011-08-25 21:24:06 +00:00
if ( sysctlbyname ( path , & sysctl_rslt , & sysctl_size , NULL , 0 ) )
goto error ;
2009-10-11 20:11:09 +00:00
2013-03-19 18:08:35 +00:00
if ( TZ_AVG ( sysctl_rslt ) > = max_threshold ) {
START_COLOR ( " color_bad " ) ;
colorful_output = true ;
}
2012-03-25 18:55:55 +00:00
outwalk + = sprintf ( outwalk , " %d.%d " , TZ_KELVTOC ( sysctl_rslt ) ) ;
2013-03-19 18:08:35 +00:00
if ( colorful_output ) {
END_COLOR ;
colorful_output = false ;
}
2012-04-29 14:59:39 +00:00
# elif defined(__OpenBSD__)
2013-01-28 10:37:23 +00:00
struct sensordev sensordev ;
struct sensor sensor ;
size_t sdlen , slen ;
int dev , numt , mib [ 5 ] = { CTL_HW , HW_SENSORS , 0 , 0 , 0 } ;
2012-04-29 14:59:39 +00:00
2013-01-28 10:37:23 +00:00
sdlen = sizeof ( sensordev ) ;
slen = sizeof ( sensor ) ;
2012-04-29 14:59:39 +00:00
2013-01-28 10:37:23 +00:00
for ( dev = 0 ; ; dev + + ) {
mib [ 2 ] = dev ;
if ( sysctl ( mib , 3 , & sensordev , & sdlen , NULL , 0 ) = = - 1 ) {
if ( errno = = ENXIO )
continue ;
if ( errno = = ENOENT )
break ;
goto error ;
}
/* 'path' is the node within the full path (defaults to acpitz0). */
if ( strncmp ( sensordev . xname , path , strlen ( path ) ) = = 0 ) {
mib [ 3 ] = SENSOR_TEMP ;
/* Limit to temo0, but should retrieve from a full path... */
for ( numt = 0 ; numt < 1 /*sensordev.maxnumt[SENSOR_TEMP]*/ ; numt + + ) {
mib [ 4 ] = numt ;
if ( sysctl ( mib , 5 , & sensor , & slen , NULL , 0 ) = = - 1 ) {
if ( errno ! = ENOENT ) {
warn ( " sysctl " ) ;
continue ;
}
}
if ( ( int ) MUKTOC ( sensor . value ) > = max_threshold ) {
START_COLOR ( " color_bad " ) ;
colorful_output = true ;
}
2012-10-10 07:57:32 +00:00
2013-01-28 10:37:23 +00:00
outwalk + = sprintf ( outwalk , " %.2f " , MUKTOC ( sensor . value ) ) ;
2012-10-10 07:57:32 +00:00
2013-01-28 10:37:23 +00:00
if ( colorful_output ) {
END_COLOR ;
2013-01-13 12:23:43 +00:00
colorful_output = false ;
}
2013-01-28 10:37:23 +00:00
}
}
}
2013-10-06 21:18:53 +00:00
# elif defined(__NetBSD__)
int fd , rval ;
bool err = false ;
prop_dictionary_t dict ;
prop_array_t array ;
prop_object_iterator_t iter ;
prop_object_iterator_t iter2 ;
prop_object_t obj , obj2 , obj3 ;
fd = open ( " /dev/sysmon " , O_RDONLY ) ;
if ( fd = = - 1 )
goto error ;
rval = prop_dictionary_recv_ioctl ( fd , ENVSYS_GETDICTIONARY , & dict ) ;
if ( rval = = - 1 ) {
err = true ;
goto error_netbsd1 ;
}
/* No drivers registered? */
if ( prop_dictionary_count ( dict ) = = 0 ) {
err = true ;
goto error_netbsd2 ;
}
/* print sensors for all devices registered */
iter = prop_dictionary_iterator ( dict ) ;
if ( iter = = NULL ) {
err = true ;
goto error_netbsd2 ;
}
/* iterate over the dictionary returned by the kernel */
while ( ( obj = prop_object_iterator_next ( iter ) ) ! = NULL ) {
array = prop_dictionary_get_keysym ( dict , obj ) ;
if ( prop_object_type ( array ) ! = PROP_TYPE_ARRAY ) {
err = true ;
goto error_netbsd3 ;
}
iter2 = prop_array_iterator ( array ) ;
if ( ! iter2 ) {
err = true ;
goto error_netbsd3 ;
}
/* iterate over the array of dictionaries */
while ( ( obj2 = prop_object_iterator_next ( iter2 ) ) ! = NULL ) {
obj3 = prop_dictionary_get ( obj2 , " description " ) ;
if ( obj3 & &
strcmp ( path , prop_string_cstring_nocopy ( obj3 ) ) = = 0 )
{
obj3 = prop_dictionary_get ( obj2 , " cur-value " ) ;
float temp = MUKTOC ( prop_number_integer_value ( obj3 ) ) ;
if ( ( int ) temp > = max_threshold ) {
START_COLOR ( " color_bad " ) ;
colorful_output = true ;
}
outwalk + = sprintf ( outwalk , " %.2f " , temp ) ;
if ( colorful_output ) {
END_COLOR ;
colorful_output = false ;
}
break ;
}
}
prop_object_iterator_release ( iter2 ) ;
}
error_netbsd3 :
prop_object_iterator_release ( iter ) ;
error_netbsd2 :
prop_object_release ( dict ) ;
error_netbsd1 :
close ( fd ) ;
if ( err ) goto error ;
2009-10-11 20:11:09 +00:00
# endif
2013-10-06 21:18:53 +00:00
2009-10-11 20:11:09 +00:00
walk + = strlen ( " degrees " ) ;
}
}
2012-03-25 18:55:55 +00:00
OUTPUT_FULL_TEXT ( buffer ) ;
2011-08-25 21:24:06 +00:00
return ;
error :
2011-07-24 21:17:34 +00:00
# endif
2012-05-09 16:56:57 +00:00
OUTPUT_FULL_TEXT ( " cant read temp " ) ;
2012-05-09 16:39:41 +00:00
( void ) fputs ( " i3status: Cannot read temperature. Verify that you have a thermal zone in /sys/class/thermal or disable the cpu_temperature module in your i3status config. \n " , stderr ) ;
2009-10-11 20:11:09 +00:00
}