[BACK]Return to check_hw_sensors CVS log [TXT][DIR] Up to [local] / nagios / check_hw_sensors

Diff for /nagios/check_hw_sensors/check_hw_sensors between version 1.31 and 1.43

version 1.31, 2009/11/10 18:24:56 version 1.43, 2010/04/27 19:43:40
Line 1 
Line 1 
 #!/usr/bin/perl -T  #!/usr/bin/perl -T
 # $RedRiver: check_hw_sensors,v 1.30 2009/11/09 23:13:04 andrew Exp $  # $RedRiver: check_hw_sensors,v 1.41 2009/11/12 18:53:52 andrew Exp $
 ########################################################################  ########################################################################
 # check_hw_sensors *** A nagios check for OpenBSD sysctl hw.sensors  # check_hw_sensors *** A nagios check for OpenBSD sysctl hw.sensors
 #  #
Line 8 
Line 8 
 use strict;  use strict;
 use warnings;  use warnings;
   
 %ENV = ();  local %ENV = ();
   
 use constant NAGIOS_OUTPUT => 1;  use POSIX;
   use Config;
   use Getopt::Long;
   use List::Util qw/ first /;
   
 my $License = <<'EOL';  my $NAGIOS_OUTPUT = 1;
   
   our $VERSION = q{$Revision$}; $VERSION =~ s/^\D+([\d\.]+)\D+$/v$1/xms;
   
   my $LICENSE = <<'EOL';
 Copyright (c) 2009 Andrew Fresh <andrew@afresh1.com>  Copyright (c) 2009 Andrew Fresh <andrew@afresh1.com>
 Permission to use, copy, modify, and distribute this software for any  Permission to use, copy, modify, and distribute this software for any
 purpose with or without fee is hereby granted, provided that the above  purpose with or without fee is hereby granted, provided that the above
Line 27 
Line 34 
 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 EOL  EOL
   
 use POSIX;  my $PROGNAME       = 'check_hw_sensors';
 use Config;  
 use lib "/usr/local/libexec/nagios";  
 use utils qw($TIMEOUT %ERRORS &support);  
   
 use Getopt::Long;  
 Getopt::Long::Configure('bundling');  
   
 my $PROGNAME = "check_hw_sensors";  
   
 my $SYSCTL         = '/sbin/sysctl';  my $SYSCTL         = '/sbin/sysctl';
 my $GETCAP         = '/usr/bin/getcap';  my $GETCAP         = '/usr/bin/getcap';
 my $BASE           = 'hw.sensors';  my $BASE           = 'hw.sensors';
 my $DEFAULT_CONFIG = '/etc/sensorsd.conf';  my $DEFAULT_CONFIG = '/etc/sensorsd.conf';
 my $OSVer          = $Config{'osvers'} || 0;  
   
   my $PREFIX;
   
   BEGIN {
       ## no critic 'warnings'
       no warnings 'uninitialized';
       $PREFIX = "${PREFIX}" || '/usr/local';    # Magic for OpenBSD ports tree
   }
   use lib $PREFIX . '/libexec/nagios';
   use utils qw($TIMEOUT %ERRORS &support);
   
   $SIG{'ALRM'} = sub {
       print "ERROR: $PROGNAME timeout\n";
       exit $ERRORS{'UNKNOWN'};
   };
   alarm $TIMEOUT;
   
   Getopt::Long::Configure('bundling');
   
   my $OSVer = $Config{'osvers'} || 0;
   
 my $state = 'UNKNOWN';    # tells whether the it is warning, critical, or OK  my $state = 'UNKNOWN';    # tells whether the it is warning, critical, or OK
 my %states;               # This stores the count of states;  
 my $opt_V;  my $opt_V;
 my $opt_h;  my $opt_h;
 my $ignore_status;  my $IGNORE_STATUS;
 my $filename;  my $FILENAME;
 my $sensor;  my $SENSOR;
 my $warning;  my $WARNING;
 my $critical;  my $CRITICAL;
   
 my $CHECK_SENSOR = $BASE;  
 my %CHECKS;  
 my %SENSORS;  
   
 #Option checking  #Option checking
 my $status = GetOptions(  my $getopt_status = GetOptions(
     "version|V"       => \$opt_V,      'version|V'       => \$opt_V,
     "help|h"          => \$opt_h,      'help|h'          => \$opt_h,
     "ignore-status|i" => \$ignore_status,      'ignore-status|i' => \$IGNORE_STATUS,
     "filename|f:s"    => \$filename,      'filename|f:s'    => \$FILENAME,
     "sensor|s=s"      => \$sensor,      'sensor|s=s'      => \$SENSOR,
     "warning|w=s"     => \$warning,      'warning|w=s'     => \$WARNING,
     "critical|c=s"    => \$critical,      'critical|c=s'    => \$CRITICAL,
 );  );
   
   if ( $getopt_status == 0 ) {
       print_help();
       exit $ERRORS{'OK'};
   }
   
   if ($opt_V) {
       print_revision( $PROGNAME, $VERSION );
       exit $ERRORS{'OK'};
   }
   
   if ($opt_h) {
       print_help();
       exit $ERRORS{'OK'};
   }
   
 # set the default this way so it only happens if someone typed -f or --filename  # set the default this way so it only happens if someone typed -f or --filename
 $filename = $DEFAULT_CONFIG if ( defined $filename && $filename eq '' );  if ( defined $FILENAME && $FILENAME eq q{} ) {
       $FILENAME = $DEFAULT_CONFIG;
   }
   
 # Stuff is output in this file by print_sensor()  # Stuff is output in this file by print_sensor()
 # http://www.openbsd.org/cgi-bin/cvsweb/src/sbin/sysctl/sysctl.c  # http://www.openbsd.org/cgi-bin/cvsweb/src/sbin/sysctl/sysctl.c
 my @Type_Map = (  my @TYPE_MAP = (
     {   type  => 'temp',      {   type  => 'temp',
         regex => qr/\sdegC$/,          regex => qr/\sdegC$/xms,
     },      },
     {   type  => 'fanrpm',      {   type  => 'fanrpm',
         regex => qr/\sRPM$/,          regex => qr/\sRPM$/xms,
     },      },
     {   type  => 'volts_dc',      {   type  => 'volts_dc',
         regex => qr/\sV\sDC$/,          regex => qr/\sV\sDC$/xms,
     },      },
     {   type  => 'amps',      {   type  => 'amps',
         regex => qr/\sA$/,          regex => qr/\sA$/xms,
     },      },
     {   type  => 'watthour',      {   type  => 'watthour',
         regex => qr/\sWh$/,          regex => qr/\sWh$/xms,
     },      },
     {   type  => 'amphour',      {   type  => 'amphour',
         regex => qr/\sAh$/,          regex => qr/\sAh$/xms,
     },      },
     {   type  => 'indicator',      {   type  => 'indicator',
         regex => qr/^(On|Off)$/,          regex => qr/^(On|Off)$/xms,
     },      },
     {   type  => 'integer',      {   type  => 'integer',
         regex => qr/\sraw$/,          regex => qr/\sraw$/xms,
     },      },
     {   type  => 'percent',      {   type  => 'percent',
         regex => qr/\s\%$/,          regex => qr/\d\%$/xms,
     },      },
     {   type  => 'lux',      {   type  => 'lux',
         regex => qr/\slx$/,          regex => qr/\slx$/xms,
     },      },
     {   type  => 'drive',      {   type  => 'drive',
         regex => qr/^drive\s/,          regex => qr/^drive\s/xms,
     },      },
     {   type  => 'timedelta',      {   type  => 'timedelta',
         regex => qr/\ssecs$/,          regex => qr/\ssecs$/xms,
     },      },
       # These below are newer than TYPE_MAP is ever used, so really, useless
       {   type  => 'humidity',
           regex => qr/\d\%$/xms,
       },
       {   type  => 'frequency',
           regex => qr/\s Hz$/xms,
       },
       {   type  => 'angle',
           regex => qr/\s degrees$/xms,
       },
 );  );
   
 if ( $status == 0 ) {  my $CHECK_SENSOR = $BASE;
     print_help();  my %CHECKS;
     exit $ERRORS{'OK'};  if ( defined $SENSOR ) {
 }      if ( $SENSOR !~ /^$BASE/xms ) {
           $SENSOR = join q{.}, $BASE, $SENSOR;
       }
       $CHECK_SENSOR = $SENSOR;
   
 if ($opt_V) {      if ($WARNING)  { $CHECKS{$SENSOR}{'warn'} = $WARNING; }
     print_revision( $PROGNAME, '$Revision$ ' );      if ($CRITICAL) { $CHECKS{$SENSOR}{'crit'} = $CRITICAL; }
     exit $ERRORS{'OK'};  
 }  }
   elsif ( defined $FILENAME ) {
 if ($opt_h) {      %CHECKS = read_file($FILENAME);
     print_help();  
     exit $ERRORS{'OK'};  
 }  }
   
 if ( defined $sensor ) {  my @SENSORS = read_sensors($CHECK_SENSOR);
     if ( $sensor !~ /^$BASE/ ) {  my %STATES = check_sensors( \@SENSORS, \%CHECKS,
         $sensor = $BASE . '.' . $sensor;      { IGNORE_STATUS => $IGNORE_STATUS } );
     }  
     $CHECK_SENSOR = $sensor;  
   
     $CHECKS{$sensor}{'warn'} = $warning  if defined $warning;  my $have_results = 0;
     $CHECKS{$sensor}{'crit'} = $critical if defined $critical;  $state = 'OK';
   foreach
       my $error ( reverse sort { $ERRORS{$a} <=> $ERRORS{$b} } keys %ERRORS )
   {
       if ( exists $STATES{$error} ) {
           $have_results++;
           $state = $error if $ERRORS{$state} < $ERRORS{$error};
   
           if ($NAGIOS_OUTPUT) {
               print $error . ' (' . scalar( @{ $STATES{$error} } ) . ')';
               if ( $error ne 'OK' ) {
                   print '<br>';
                   print map {" - $_<br>"} @{ $STATES{$error} };
               }
           }
           else {
               print $error . ' (' . scalar( @{ $STATES{$error} } ) . "):\n";
               foreach ( @{ $STATES{$error} } ) {
                   print "   $_\n";
               }
           }
       }
 }  }
 elsif ( defined $filename ) {  if ( $have_results == 0 ) {
     %CHECKS = parse_file($filename);      print "No results found\n";
 }  }
   exit $ERRORS{$state};
   
 open my $sysctl, "-|", $SYSCTL, $CHECK_SENSOR  sub read_sensors {
     or die "Couldn't open sysctl: $!";      my ($sensor) = @_;
 while (<$sysctl>) {      my @S;
       open my $sysctl, q{-|}, $SYSCTL, $sensor
           or die "Couldn't open sysctl: $!\n";
       while (<$sysctl>) {
           chomp;
           push @S, parse_sensor($_);
       }
       ## no critic 'die'
       close $sysctl
           or die $!
           ? "Error closing sysctl pipe: $!\n"
           : "Exit status $? from sysctl\n";
   
     #while (<>) {      return @S;
     chomp;  }
     my ( $id, $output ) = split /=/;  
     my @s = split /\./,   $id;  
     my @o = split /,\s*/, $output;  
   
   sub parse_sensor {
       my ($sensor) = @_;
   
       ## no critic 'literal'
       my ( $id, $output ) = split /=/xms, $sensor;
       my @s = split /\./xms,   $id;
       my @o = split /,\s*/xms, $output;
   
     my ( $type, $source, $descr, $data, $status );      my ( $type, $source, $descr, $data, $status );
   
     $source = $o[0];      $source = $o[0];
Line 158 
Line 232 
   
     if ( $OSVer >= 4.1 ) {      if ( $OSVer >= 4.1 ) {
         $data = $o[0];          $data = $o[0];
         if ( $data =~ s/\s+\((.*)\).*$// ) {          if ( $data =~ s/\s+\((.*)\).*$//xms ) {
             $descr = $1;              $descr = $1;
         }          }
         $status = $o[1];          $status = $o[1];
         ( $source, $type ) = $id =~ /([^\.]+)\.([^\.]+?)\d+$/;          ( $source, $type ) = $id =~ /([^\.]+)\.([^\.]+?)\d+$/xms;
     }      }
     elsif ( $OSVer >= 4.0 ) {      elsif ( $OSVer >= 4.0 ) {
         $data   = $o[2];          $data   = $o[2];
         $status = $o[3];          $status = $o[3];
         foreach my $t (@Type_Map) {          foreach my $t (@TYPE_MAP) {
             if ( $data =~ /$t->{'regex'}/ ) {              if ( $data =~ /$t->{'regex'}/xms ) {
                 $type = $t->{'type'};                  $type = $t->{'type'};
                 last;                  last;
             }              }
Line 182 
Line 256 
   
     $type ||= 'unknown';      $type ||= 'unknown';
   
     $SENSORS{$id} = {      return {
         id          => $id,          id          => $id,
         output      => $output,          output      => $output,
         source      => $source,          source      => $source,
Line 191 
Line 265 
         type        => $type,          type        => $type,
         data        => $data,          data        => $data,
     };      };
   
 }  }
 close $sysctl;  
   
 sub as_if_numeric {  sub read_file {
     my $_a = $a;  
     my $_b = $b;  
     $_a =~ s/\D//g;  
     $_b =~ s/\D//g;  
     $_a <=> $_b;  
 }  
   
 foreach my $s ( sort as_if_numeric keys %SENSORS ) {  
     my ( $r, $data );  
     if ( exists $CHECKS{$s} ) {  
         $r = check_sensor( $SENSORS{$s}, $CHECKS{$s} );  
         $data = $s . '=' . $SENSORS{$s}{'output'};  
     }  
     elsif ( !$ignore_status ) {  
         $r    = check_sensor( $SENSORS{$s} );  
         $data = $s . '=' . $SENSORS{$s}{'output'};  
     }  
     else {  
   
         # ignore this sensor  
     }  
     next unless defined $r;  
     push @{ $states{$r} }, $data;  
 }  
   
 $state = 'OK';  
 my $have_results = 0;  
 foreach my $error ( sort { $ERRORS{$a} <=> $ERRORS{$b} } keys %ERRORS ) {  
     if ( exists $states{$error} ) {  
         $have_results++;  
         $state = $error;  
     }  
 }  
 foreach my $error ( sort { $ERRORS{$b} <=> $ERRORS{$a} } keys %ERRORS ) {  
     if ( exists $states{$error} ) {  
         if (NAGIOS_OUTPUT) {  
             print "$error (" . scalar( @{ $states{$error} } ) . ")";  
             if ( $error ne 'OK' ) {  
                 print '<br>';  
                 print map {" - $_<br>"} @{ $states{$error} };  
             }  
         }  
         else {  
             print "$error (" . scalar( @{ $states{$error} } ) . "):\n";  
             foreach ( @{ $states{$error} } ) {  
                 print "   $_\n";  
             }  
         }  
     }  
 }  
 if ( $have_results == 0 ) {  
     print "No results found\n";  
 }  
 exit $ERRORS{$state};  
   
 sub parse_file {  
     my $filename = shift;      my $filename = shift;
     my %contents;      my %contents;
   
     die "file '$filename' does not exist." unless -e $filename;      die "file '$filename' does not exist.\n" if !-e $filename;
   
     open my $fh, '-|', $GETCAP, '-a', '-f', $filename      open my $fh, q{-|}, $GETCAP, q{-a}, q{-f}, $filename
         or die "Couldn't open FILE '$GETCAP -a -f $filename': $!";          or die "Couldn't open '$GETCAP -a -f $filename': $!\n";
     while (<$fh>) {      while (<$fh>) {
         chomp;          chomp;
         my ( $key, @c ) = split /\:/;          my ( $s, @c ) = split /\:/xms;
         foreach (@c) {          $contents{$s} = parse_line(@c);
             my ( $k, $v ) = split /\=/;  
             if ( lc($k) eq 'ignore' ) {  
                 $contents{$key}{'IGNORE'} = 1;  
             }  
             elsif ( lc($k) eq 'status' ) {  
                 $contents{$key}{'STATUS'} = 1;  
             }  
             else {  
                 $contents{$key}{$k} = $v;  
             }  
         }  
     }      }
     close $fh;      ## no critic 'die'
       close $fh
           or die $!
           ? "Error closing getcap pipe: $!\n"
           : "Exit status $? from getcap\n";
   
     return %contents;      return %contents;
 }  }
   
   sub parse_line {
       my (@c) = @_;
       my %c;
       foreach (@c) {
           my ( $k, $v ) = split /\=/xms;
           if    ( lc($k) eq 'ignore' ) { $c{'IGNORE'} = 1; }
           elsif ( lc($k) eq 'status' ) { $c{'STATUS'} = 1; }
           else                         { $c{$k}       = $v; }
       }
       return \%c;
   }
   
 sub parse_check {  sub parse_check {
     my $check = shift;      my $check = shift;
   
     return unless $check;      return          if !$check;
     return if $check->{'STATUS'};      return 'STATUS' if $check->{'STATUS'};
     return 'IGNORE' if $check->{'IGNORE'};      return 'IGNORE' if $check->{'IGNORE'};
   
     foreach my $code ( 'crit', 'warn' ) {      foreach my $code ( 'crit', 'warn' ) {
         if ( defined $check->{$code} && $check->{$code} =~ /:/ ) {          if ( defined $check->{$code} && $check->{$code} =~ /:/xms ) {
             if ( my ( $low, $high ) = split /:/, $check->{$code} ) {              if ( my ( $low, $high ) = split /:/xms, $check->{$code} ) {
                 $check->{ $code . '.low' }  = $low  if length $low;                  $check->{ $code . '.low' }  = $low  if length $low;
                 $check->{ $code . '.high' } = $high if length $high;                  $check->{ $code . '.high' } = $high if length $high;
             }              }
             delete $check->{$code};              delete $check->{$code};
         }          }
   
         foreach my $severity ( 'low', 'high' ) {          foreach my $direction ( 'low', 'high' ) {
             if ( defined $check->{$severity} ) {              my $c = $code . q{.} . $direction;
                 $check->{ $code . '.' . $severity } = $check->{$severity}              if ( defined $check->{$direction} ) {
                     if !defined $check->{ $code . '.' . $severity };                  $check->{$c} ||= $check->{$direction};
             }              }
   
               if ( defined $check->{$c} ) {
                   my $old = $check->{$c};
                   $check->{$c} =~ s/[^\d\.]//gxms;
                   if ( !length $check->{$c} ) {
                       warn "INVALID CHECK ($old)\n";
                       delete $check->{$c};
                   }
               }
         }          }
         no warnings 'uninitialized';  
         $check->{$code} = [ split /,\s*/, $check->{$code} ];          if ( defined $check->{$code} ) {
               $check->{$code} = [ split /,\s*/xms, $check->{$code} ];
           }
           else {
               $check->{$code} = [];
           }
     }      }
   
     return $check;      return $check;
 }  }
   
   sub check_sensors {
       my ( $S, $C, $O ) = @_;
   
       my %states;
       foreach my $sensor ( @{$S} ) {
           my ( $r, $data );
           if ( exists $C->{ $sensor->{id} } ) {
               $r = check_sensor( $sensor, $C->{ $sensor->{id} } );
               $data = $sensor->{id} . q{=} . $sensor->{output};
           }
           elsif ( $sensor->{status} && !$O->{IGNORE_STATUS} ) {
               $r = check_sensor( $sensor, { STATUS => 1 } );
               $data = $sensor->{id} . q{=} . $sensor->{output};
           }
           else {
   
               # ignore this sensor, theoretically you could do the check and
               # that would show unknown sensors.
           }
           if ( defined $r ) {
               push @{ $states{$r} }, $data;
           }
       }
   
       return %states;
   }
   
 sub check_sensor {  sub check_sensor {
     my $sensor = shift;      my ( $sensor, $check ) = @_;
     my $check  = shift;  
     my $result = 'UNKNOWN';      my $result = 'UNKNOWN';
     my %errors = (  
         'warn' => 'WARNING',  
         'crit' => 'CRITICAL',  
     );  
   
     return $result unless ref $sensor eq 'HASH';      return $result if ref $sensor ne 'HASH';
     $check = parse_check($check) if $check;      $check = parse_check($check) if $check;
   
     if ( !$check ) {      if ( !$check ) { return $result; }
       elsif ( $check eq 'STATUS' ) {
   
         # It looks like doing this should be safe, from          # It looks like returning $sensor->{status} should be safe, from
         # src/sbin/sysctl/sysctl.c          # src/sbin/sysctl/sysctl.c
         return $sensor->{'status'} if $sensor->{'status'};          return ( $sensor->{'status'} || $result );
       }
       elsif ( $check eq 'IGNORE' ) { return; }
   
         return;      my $type = $sensor->{'type'};
       if (first { $type eq $_ }
           qw(
           fan fanrpm
           volt volts_dc
           amps watthour amphour
           integer raw percent
           lux temp timedelta
           humidity frequency angle
           )
           )
       {
           $result = check_sensor_numeric( $sensor->{'data'}, $check );
     }      }
     elsif ( $check eq 'IGNORE' ) {      elsif ( first { $type eq $_ } qw( drive indicator ) ) {
         return;          my $data = $sensor->{'data'};
           $data =~ s/^drive\s+//xms;
           $result = check_sensor_list( $data, $check );
     }      }
       else {
           warn "Unknown Sensor Type: $sensor->{id} = $type\n";
       }
   
     $result = 'OK';      return $result;
     foreach my $code ( 'warn', 'crit' ) {  }
         if (   $sensor->{'type'} eq 'fan'  
             || $sensor->{'type'} eq 'fanrpm'  
             || $sensor->{'type'} eq 'volt'  
             || $sensor->{'type'} eq 'volts_dc'  
             || $sensor->{'type'} eq 'amps'  
             || $sensor->{'type'} eq 'watthour'  
             || $sensor->{'type'} eq 'amphour'  
             || $sensor->{'type'} eq 'integer'  
             || $sensor->{'type'} eq 'raw'  
             || $sensor->{'type'} eq 'percent'  
             || $sensor->{'type'} eq 'lux'  
             || $sensor->{'type'} eq 'timedelta' )  
         {  
             my $data = $sensor->{'data'};  
             $data =~ s/[^\d\.]//g;  
             if ( !length $data ) {  
                 warn  
                     "INVALID DATA ($sensor->{'data'}) for '$sensor->{'id'}'\n";  
                 next;  
             }  
   
             if (   defined $check->{ $code . ".low" }  sub check_sensor_numeric {
                 || defined $check->{ $code . ".high" } )      my ( $data, $check ) = @_;
             {  
                 if ( defined $check->{ $code . ".low" } ) {  
                     my $c = $check->{ $code . ".low" };  
                     $c =~ s/[^\d\.]//g;  
   
                     if ( !length $c ) {      my $result = 'UNKNOWN';
                         warn "INVALID CHECK ("      my %errors = (
                             . $check->{ $code . ".low" }          'warn' => 'WARNING',
                             . ") for '$sensor->{'id'}:$code.low'\n";          'crit' => 'CRITICAL',
                         next;      );
                     }  
   
                     $result = $errors{$code}      $data =~ s/[^\d\.]//gxms;
                         if ( $c >= $data );      if ( !length $data ) {
                 }          warn "INVALID DATA ($data)\n";
                 if ( defined $check->{ $code . ".high" } ) {          return $result;
                     my $c = $check->{ $code . ".high" };      }
                     $c =~ s/[^\d\.]//g;  
                     if ( !length $c ) {  
                         warn "INVALID CHECK ("  
                             . $check->{ $code . ".high" }  
                             . ") for '$sensor->{'id'}:$code.high'\n";  
                         next;  
                     }  
   
                     $result = $errors{$code}      foreach my $code ( 'warn', 'crit' ) {
                         if ( $c <= $data );          if (   defined $check->{ $code . '.low' }
                 }              || defined $check->{ $code . '.high' } )
           {
               if ((   defined $check->{ $code . '.low' }
                       && $check->{ $code . '.low' } >= $data
                   )
                   || ( defined $check->{ $code . '.high' }
                       && $check->{ $code . '.high' } <= $data )
                   )
               {
                   $result = $errors{$code};
             }              }
             elsif ( @{ $check->{$code} } ) {              $result = 'OK' if $result eq 'UNKNOWN';
                 my $matched = 0;  
                 foreach ( @{ $check->{$code} } ) {  
                     my $c = $_;  
                     $c =~ s/[^\d\.]//g;  
                     if ( !length $c ) {  
                         warn "INVALID CHECK (" . $_  
                             . ") for '$sensor->{'id'}:$code'\n";  
                         next;  
                     }  
   
                     if ( $c eq $data ) {  
                         $matched = 1;  
                         last;  
                     }  
                 }  
                 $result = $errors{$code} unless $matched;  
             }  
   
         }          }
         elsif ( $sensor->{'type'} eq 'temp' ) {          elsif ( @{ $check->{$code} } ) {
             my ( $degC, $degF ) = split /\//, $sensor->{'data'};              my $matched = 0;
             $degC =~ s/[^\d\.]//g;          NUMERIC_CHECK: foreach ( @{ $check->{$code} } ) {
             $degF ||= $degC * 9 / 5 + 32;                  my $c = $_;
             $degF =~ s/[^\d\.]//g;                  $c =~ s/[^\d\.]//gxms;
             if (   defined $check->{ $code . ".low" }                  if ( !length $c ) {
                 || defined $check->{ $code . ".high" } )                      warn "INVALID CHECK ($_) for '$code'\n";
             {                      next;
                 if ( defined $check->{ $code . ".low" } ) {  
                     my $c    = $check->{ $code . ".low" };  
                     my $data = $degC;  
   
                     $data = $degF if ( $c =~ /F/i );  
                     if ( !length $data ) {  
                         warn "INVALID DATA ("  
                             . $sensor->{'data'}  
                             . ") for '$sensor->{'id'}'\n";  
                         next;  
                     }  
   
                     $c =~ s/[^\d\.]//g;  
                     if ( !length $c ) {  
                         warn "INVALID CHECK ("  
                             . $check->{ $code . ".low" }  
                             . ") for '$sensor->{'id'}':$code.low\n";  
                         next;  
                     }  
   
                     $result = $errors{$code}  
                         if ( $c >= $data );  
                 }                  }
                 if ( defined $check->{ $code . ".high" } ) {  
                     my $c = $check->{ $code . ".high" };  
   
                     my $data = $degC;                  if ( $c eq $data ) {
                     $data = $degF if ( $c =~ /F/i );                      $matched = 1;
                     if ( !length $data ) {                      last NUMERIC_CHECK;
                         warn "INVALID DATA ("  
                             . $sensor->{'data'}  
                             . ") for '$sensor->{'id'}'\n";  
                         next;  
                     }  
   
                     $c =~ s/[^\d\.]//g;  
                     if ( !length $c ) {  
                         warn "INVALID CHECK ("  
                             . $check->{ $code . ".high" }  
                             . ") for '$sensor->{'id'}:$code.high'\n";  
                         next;  
                     }  
   
                     $result = $errors{$code}  
                         if ( $c <= $data );  
                 }                  }
             }              }
             elsif ( @{ $check->{$code} } ) {              if ($matched) {
                   $result = 'OK' if $result eq 'UNKNOWN';
               }
               else {
                   $result = $errors{$code};
               }
           }
       }
   
                 my $matched = 0;      return $result;
                 foreach ( @{ $check->{$code} } ) {  }
                     my $c    = $_;  
                     my $data = $degC;  
   
                     $data = $degF if ( $c =~ /F/i );  sub check_sensor_list {
                     if ( !length $data ) {      my ( $data, $check ) = @_;
                         warn "INVALID DATA ("  
                             . $sensor->{'data'}  
                             . ") for '$sensor->{'id'}'\n";  
                         next;  
                     }  
   
                     $c =~ s/[^\d\.]//g;      my $result = 'UNKNOWN';
                     if ( !length $c ) {      my %errors = (
                         warn "INVALID CHECK (" . $_          'warn' => 'WARNING',
                             . ") for '$sensor->{'id'}':$code\n";          'crit' => 'CRITICAL',
                         next;      );
                     }  
   
                     if ( $c eq $data ) {      foreach my $code ( 'warn', 'crit' ) {
                         $matched = 1;          if ( @{ $check->{$code} } ) {
                         last;              my $matched = 0;
                     }          LIST_CHECK: foreach ( @{ $check->{$code} } ) {
                   if ( $_ eq $data ) {
                       $matched = 1;
                       last LIST_CHECK;
                 }                  }
                 $result = $errors{$code} unless $matched;  
             }              }
         }              if ($matched) {
         elsif ($sensor->{'type'} eq 'drive'                  $result = 'OK' if $result eq 'UNKNOWN';
             || $sensor->{'type'} eq 'indicator' )  
         {  
             $sensor->{'data'} =~ s/^drive\s+//;  
             if ( @{ $check->{$code} } ) {  
                 my $matched = 0;  
                 foreach ( @{ $check->{$code} } ) {  
                     if ( $_ eq $sensor->{'data'} ) {  
                         $matched = 1;  
                         last;  
                     }  
                 }  
                 $result = $errors{$code} unless $matched;  
             }              }
               else {
                   $result = $errors{$code};
               }
         }          }
         else {  
             warn 'Unknown Sensor Type: ',  
                 $sensor->{'id'},  
                 '=',  
                 $sensor->{'type'},  
                 "\n";  
             $result = 'UNKNOWN';  
         }  
   
     }      }
   
     return $result;      return $result;
Line 542 
Line 520 
   
 FILE is in the same format as sensorsd.conf(5) plus some additional  FILE is in the same format as sensorsd.conf(5) plus some additional
 entries.  These additional entries in the file are ignored by  entries.  These additional entries in the file are ignored by
 sensorsd(8) this means you can use the same config file for $PROGNAME  sensorsd(8).  This means you can use the same config file for $PROGNAME
 as well as sensorsd(8).  as well as sensorsd(8).
   
 $PROGNAME understands the following entries:  $PROGNAME understands the following entries:
Line 554 
Line 532 
 can be used when appropriate, or you can use the following:  can be used when appropriate, or you can use the following:
   
     fanrpm, volts_dc, amps, watthour, amphour, integer (raw), percent,      fanrpm, volts_dc, amps, watthour, amphour, integer (raw), percent,
     lux or timedelta - Anything that includes digits.  Both the value of      lux, temp or timedelta - Anything that includes digits.  Both the
     the check and the value of the sensor response that are not either a      value of the check and the value of the sensor response that are not
     digit or period are stripped and then the two resultant values are      either a digit or period are stripped and then the two resultant
     compared.      values are compared.
   
     temp - Can be as above, but if the entry has an F in it,  
     it compares farenheit, otherwise it uses celcius.  
   
     indicator or drive - does a case sensitive match of each      indicator or drive - does a case sensitive match of each
     entry in the comma separated list and if it does not match      entry in the comma separated list and if it does not match
     any of the entries, it sets the status.      any of the entries, it sets the status.
Line 585 
Line 560 
   
 EOL  EOL
   
     print_revision( $PROGNAME, '$Revision$' );      print_revision( $PROGNAME, $VERSION );
   
     print $License;      print $LICENSE;
   
       return;
 }  }
   
 sub print_revision {  sub print_revision {
     my ( $prog, $rev ) = @_;      my ( $prog, $rev ) = @_;
     $rev =~ s/^\D+([\d\.]+)\D+$/v$1/xms;  
   
     print "$prog $rev\n";      print "$prog $rev\n";
   
       return;
 }  }
   

Legend:
Removed from v.1.31  
changed lines
  Added in v.1.43

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>