"Fossies" - the Fresh Open Source Software Archive

Member "xosview-1.23/linux/lmstemp.cc" (11 Jul 2020, 12200 Bytes) of package /linux/misc/xosview-1.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "lmstemp.cc" see the Fossies "Dox" file reference documentation.

    1 //
    2 //  Copyright (c) 2000, 2006 by Leopold Toetsch <lt@toetsch.at>
    3 //
    4 //  Read temperature entries from /proc/sys/dev/sensors/*/*
    5 //  and display actual and high temperature
    6 //  if actual >= high, actual temp changes color to indicate alarm
    7 //
    8 //  File based on btrymeter.* by
    9 //  Copyright (c) 1997 by Mike Romberg ( mike.romberg@noaa.gov )
   10 //
   11 //  This file may be distributed under terms of the GPL
   12 //
   13 //
   14 //
   15 #include "lmstemp.h"
   16 #include <stdio.h>
   17 #include <stdlib.h>
   18 #include <string.h>
   19 #include <math.h>
   20 #include <sys/types.h>
   21 #include <sys/stat.h>
   22 #include <dirent.h>
   23 #include <iostream>
   24 #include <string>
   25 #include <fstream>
   26 
   27 static const char PROC_SENSORS[] = "/proc/sys/dev/sensors";
   28 static const char SYS_SENSORS[]  = "/sys/class/hwmon";
   29 
   30 
   31 LmsTemp::LmsTemp( XOSView *parent, const char *name, const char *tempfile,
   32                   const char *highfile, const char *lowfile, const char *label,
   33                   const char *caption, unsigned int nbr )
   34   : SensorFieldMeter( parent, label, caption, 1, 1, 0 ){
   35   _nbr = nbr;
   36   _scale = 1.0;
   37   _isproc = _name_found = _temp_found = _high_found = _low_found = false;
   38 
   39   // Check if high is given as value
   40   if ( highfile && sscanf(highfile, "%lf", &high_) > 0 ) {
   41     has_high_ = _high_found = true;
   42     highfile = NULL;
   43   }
   44   // Check if low is given as value
   45   if ( lowfile && sscanf(lowfile, "%lf", &low_) > 0 ) {
   46     has_low_ = _low_found = true;
   47     lowfile = NULL;
   48   }
   49 
   50   if ( !checksensors(name, tempfile, highfile, lowfile) ) {
   51     if ( !_name_found &&
   52          (( !_temp_found && tempfile[0] != '/' ) ||
   53           ( !_high_found && (highfile && highfile[0] != '/') ) ||
   54           ( !_low_found && (lowfile && lowfile[0] != '/') )) )
   55       std::cerr << label << " : No sensor named " << name << " was found in "
   56                 << SYS_SENSORS << "." << std::endl;
   57     else {
   58       if (!_temp_found && tempfile[0] != '/') {
   59         std::cerr << label << " : Could not find file " << tempfile << "{,_input}";
   60         if (name)
   61           std::cerr << " under " << name << " in " << SYS_SENSORS;
   62         else
   63           std::cerr << " under " << PROC_SENSORS << " or " << SYS_SENSORS;
   64         std::cerr << "." << std::endl;
   65       }
   66       if (!_high_found && highfile && highfile[0] != '/') {
   67         std::cerr << label << " : Could not find file " << highfile;
   68         if (name)
   69           std::cerr << " under " << name << " in " << SYS_SENSORS;
   70         else
   71           std::cerr << " under " << SYS_SENSORS;
   72         std::cerr << "." << std::endl;
   73       }
   74       if (!_low_found && lowfile && lowfile[0] != '/') {
   75         std::cerr << label << " : Could not find file " << lowfile;
   76         if (name)
   77           std::cerr << " under " << name << " in " << SYS_SENSORS;
   78         else
   79           std::cerr << " under " << SYS_SENSORS;
   80         std::cerr << "." << std::endl;
   81       }
   82     }
   83     parent_->done(1);
   84   }
   85 }
   86 
   87 LmsTemp::~LmsTemp( void ){
   88 }
   89 
   90 bool LmsTemp::checksensors( const char *name, const char *tempfile,
   91                             const char *highfile, const char *lowfile ) {
   92 // Logic:
   93 //  0) tempfile must always be found, highfile and lowfile only if given
   94 //  1) absolute path in any filename must match as is
   95 //  2) if name is given, only files in that sysfs node can match
   96 //  3) any filename matches as is
   97 //  4) tempfile + "_input" matches and tempfile + "_max" and/or
   98 //     tempfile + "_min" matches
   99   DIR *dir;
  100   struct dirent *ent;
  101   struct stat buf;
  102   std::string dirname, f, f2, n;
  103 
  104   /* First, check if absolute paths were given. */
  105   if (tempfile[0] == '/') {
  106     if ( stat(tempfile, &buf) == 0 && S_ISREG(buf.st_mode) ) {
  107       _tempfile = tempfile;
  108       _temp_found = true;
  109     }
  110     else
  111       std::cerr << title() << " : Could not find file " << tempfile << "." << std::endl;
  112   }
  113   if (highfile && highfile[0] == '/') {
  114     if ( stat(highfile, &buf) == 0 && S_ISREG(buf.st_mode) ) {
  115       _highfile = highfile;
  116       _high_found = true;
  117     }
  118     else
  119       std::cerr << title() << " : Could not find file " << highfile << "." << std::endl;
  120   }
  121   if (lowfile && lowfile[0] == '/') {
  122     if ( stat(lowfile, &buf) == 0 && S_ISREG(buf.st_mode) ) {
  123       _lowfile = lowfile;
  124       _low_found = true;
  125     }
  126     else
  127       std::cerr << title() << " : Could not find file " << lowfile << "." << std::endl;
  128   }
  129 
  130   if ( _temp_found && (_high_found || !highfile) && (_low_found || !lowfile) ) {
  131     _isproc = ( strncmp(_tempfile.c_str(), "/proc", 5) ? false : true );
  132     return true;
  133   }
  134 
  135   /* Then, try to find the given file. */
  136   /* Try /proc first. */
  137   if ( (dir = opendir(PROC_SENSORS)) ) {
  138     while ( !_temp_found && (ent = readdir(dir)) ) {
  139       if ( !strncmp(ent->d_name, ".", 1) ||
  140            !strncmp(ent->d_name, "..", 2) )
  141         continue;
  142 
  143       dirname = PROC_SENSORS;
  144       dirname += '/'; dirname += ent->d_name;
  145       if ( stat(dirname.c_str(), &buf) == 0 && S_ISDIR(buf.st_mode) ) {
  146         f = dirname + '/' + tempfile;
  147         if ( stat(f.c_str(), &buf) == 0 && S_ISREG(buf.st_mode) ) {
  148           _temp_found = true;
  149           _tempfile = f;
  150           _isproc = true;
  151         }
  152       }
  153     }
  154     closedir(dir);
  155     if (_temp_found)
  156       return true;
  157   }
  158 
  159   /* Next, try /sys. */
  160   if ( !(dir = opendir(SYS_SENSORS)) )
  161     return false;
  162 
  163   while ( !(_temp_found && (_high_found || !highfile) && (_low_found || !lowfile) ) &&
  164            (ent = readdir(dir)) ) {
  165     if ( !strncmp(ent->d_name, ".", 1) ||
  166          !strncmp(ent->d_name, "..", 2) )
  167       continue;
  168 
  169     // Try every node under /sys/class/hwmon
  170     dirname = SYS_SENSORS;
  171     dirname += '/'; dirname += ent->d_name;
  172 
  173     int i = 0;
  174     do {
  175       if ( stat(dirname.c_str(), &buf) == 0 && S_ISDIR(buf.st_mode) ) {
  176         // Try to get the sensor's name
  177         f = dirname + "/name";
  178         std::ifstream namefile( f.c_str() );
  179         if ( namefile.good() ) {
  180           namefile >> n;
  181           namefile.close();
  182         }
  183         if (!name || n == name) {
  184           // Either no name was given, or the name matches.
  185           // Check if the files exist here.
  186           _name_found = true;
  187           if (highfile && !_high_found) {
  188             f = dirname + '/' + highfile;
  189             if ( stat(f.c_str(), &buf) == 0 && S_ISREG(buf.st_mode) ) {
  190               _high_found = true;
  191               _highfile = f;
  192             }
  193           }
  194           if (lowfile && !_low_found) {
  195             f = dirname + '/' + lowfile;
  196             if ( stat(f.c_str(), &buf) == 0 && S_ISREG(buf.st_mode) ) {
  197               _low_found = true;
  198               _lowfile = f;
  199             }
  200           }
  201           f = dirname + '/' + tempfile;
  202           if ( stat(f.c_str(), &buf) == 0 && S_ISREG(buf.st_mode) ) {
  203             _temp_found = true;
  204             _tempfile = f;
  205           }
  206           else {
  207             f2 = f + "_input";
  208             if ( stat(f2.c_str(), &buf) == 0 && S_ISREG(buf.st_mode) ) {
  209               _temp_found = true;
  210               _tempfile = f2;
  211               f2 = f + "_max";
  212               if ( !_high_found && !highfile &&
  213                    stat(f2.c_str(), &buf) == 0 && S_ISREG(buf.st_mode) ) {
  214                 _high_found = true;
  215                 _highfile = f2;
  216               }
  217               f2 = f + "_min";
  218               if ( !_low_found && !lowfile &&
  219                    stat(f2.c_str(), &buf) == 0 && S_ISREG(buf.st_mode) ) {
  220                 _low_found = true;
  221                 _lowfile = f2;
  222               }
  223             }
  224           }
  225         }
  226       }
  227 
  228       // Some /sys sensors have the files in subdirectory /device
  229       dirname += "/device";
  230     } while ( ++i < 2 && !( _temp_found && (_high_found || !highfile) &&
  231                            (_low_found || !lowfile) ) );
  232   }
  233   closedir(dir);
  234   // No highfile or lowfile is OK.
  235   if (!highfile)
  236     _high_found = true;
  237   if (!lowfile)
  238     _low_found = true;
  239 
  240   return (_temp_found & _high_found & _low_found);
  241 }
  242 
  243 /* Adapted from libsensors. */
  244 void LmsTemp::determineScale( void ){
  245   char type[16], subtype[32];
  246   int n;
  247   std::string basename = _tempfile.substr(_tempfile.find_last_of('/') + 1);
  248   if ( sscanf(basename.c_str(), "%[a-z]%d_%s", type, &n, subtype) == 3 ) {
  249     if (( !strncmp(type, "in", strlen(type)) &&
  250           !strncmp(subtype, "input", strlen(subtype)) ) ||
  251         ( !strncmp(type, "temp", strlen(type)) &&
  252           !strncmp(subtype, "input", strlen(subtype)) ) ||
  253         ( !strncmp(type, "temp", strlen(type)) &&
  254           !strncmp(subtype, "offset", strlen(subtype)) ) ||
  255         ( !strncmp(type, "curr", strlen(type)) &&
  256           !strncmp(subtype, "input", strlen(subtype)) ) ||
  257         ( !strncmp(type, "power", strlen(type)) &&
  258           !strncmp(subtype, "average_interval", strlen(subtype)) ) ||
  259         ( !strncmp(type, "cpu", strlen(type)) &&
  260           !strncmp(subtype, "vid", strlen(subtype)) )) {
  261       _scale = 1000.0;
  262       return;
  263     }
  264     if (( !strncmp(type, "power", strlen(type)) &&
  265           !strncmp(subtype, "average", strlen(subtype)) ) ||
  266         ( !strncmp(type, "energy", strlen(type)) &&
  267           !strncmp(subtype, "input", strlen(subtype)) )) {
  268       _scale = 1000000.0;
  269       return;
  270     }
  271   }
  272   _scale = 1.0;
  273 }
  274 
  275 void LmsTemp::determineUnit( void ){
  276   char type[16], subtype[32];
  277   int n;
  278   std::string basename = _tempfile.substr(_tempfile.find_last_of('/') + 1);
  279   if ( sscanf(basename.c_str(), "%[a-z]%d_%s", type, &n, subtype) == 3 ) {
  280     if ( !strncmp(type, "temp", strlen(type)) )
  281       strcpy(unit_, "\260C");
  282     else if ( !strncmp(type, "in", strlen(type)) ||
  283               !strncmp(subtype, "vid", strlen(type)) )
  284       strcpy(unit_, "V");
  285     else if ( !strncmp(type, "fan", strlen(type)) )
  286       strcpy(unit_, "RPM");
  287     else if ( !strncmp(type, "power", strlen(type)) ) {
  288       if ( strncmp(subtype, "average_interval", strlen(type)) )
  289         strcpy(unit_, "s");
  290       else
  291         strcpy(unit_, "W");
  292     }
  293     else if ( !strncmp(type, "energy", strlen(type)) )
  294       strcpy(unit_, "J");
  295     else if ( !strncmp(type, "curr", strlen(type)) )
  296       strcpy(unit_, "A");
  297     else if ( !strncmp(type, "humidity", strlen(type)) )
  298       strcpy(unit_, "%");
  299   }
  300 }
  301 
  302 void LmsTemp::checkResources( void ){
  303   SensorFieldMeter::checkResources();
  304 
  305   char s[32];
  306   const char *tmp = NULL;
  307   actcolor_  = parent_->allocColor( parent_->getResource( "lmstempActColor" ) );
  308   highcolor_ = parent_->allocColor( parent_->getResource( "lmstempHighColor" ) );
  309   lowcolor_  = parent_->allocColor( parent_->getResource( "lmstempLowColor" ) );
  310   setfieldcolor( 0, actcolor_ );
  311   setfieldcolor( 1, parent_->getResource( "lmstempIdleColor") );
  312   setfieldcolor( 2, highcolor_ );
  313   tmp = parent_->getResourceOrUseDefault( "lmstempHighest", "0" );
  314   snprintf(s, 32, "lmstempHighest%d", _nbr);
  315   total_ = fabs( atof( parent_->getResourceOrUseDefault(s, tmp) ) );
  316   priority_ = atoi( parent_->getResource( "lmstempPriority" ) );
  317   tmp = parent_->getResource( "lmstempUsedFormat" );
  318   snprintf(s, 32, "lmstempUsedFormat%d", _nbr);
  319   SetUsedFormat( parent_->getResourceOrUseDefault(s, tmp) );
  320 
  321   if ( !_highfile.empty() )
  322     has_high_ = true;
  323   if ( !_lowfile.empty() )
  324     has_low_ = true;
  325 
  326   if (!has_high_)
  327     high_ = total_;
  328   if (!has_low_)
  329     low_ = 0;
  330 
  331   determineScale();
  332   determineUnit();
  333   updateLegend();
  334 }
  335 
  336 void LmsTemp::checkevent( void ){
  337   getlmstemp();
  338 
  339   drawfields();
  340 }
  341 
  342 void LmsTemp::getlmstemp( void ){
  343   double high = high_, low = low_;
  344 
  345   std::ifstream tempfile( _tempfile.c_str() );
  346   if (!tempfile) {
  347     std::cerr << "Can not open file : " << _tempfile << std::endl;
  348     parent_->done(1);
  349     return;
  350   }
  351 
  352   if (_isproc)
  353     tempfile >> high >> low >> fields_[0];
  354   else {
  355     tempfile >> fields_[0];
  356     fields_[0] /= _scale;
  357     if ( !_highfile.empty() ) {
  358       std::ifstream highfile( _highfile.c_str() );
  359       if (!highfile) {
  360         std::cerr << "Can not open file : " << _highfile << std::endl;
  361         parent_->done(1);
  362         return;
  363       }
  364       highfile >> high;
  365       high /= _scale;
  366     }
  367     if ( !_lowfile.empty() ) {
  368       std::ifstream lowfile( _lowfile.c_str() );
  369       if (!lowfile) {
  370         std::cerr << "Can not open file : " << _lowfile << std::endl;
  371         parent_->done(1);
  372         return;
  373       }
  374       lowfile >> low;
  375       low /= _scale;
  376     }
  377   }
  378 
  379   checkFields(low, high);
  380 }