# -*- perl -*-
#
# $Revision: 1.5 $
#/s/nagios/bin/nagioscmd service post <host> <service> \
# <result_code> <service_message>

package ntpd;

require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw(&print_usage &print_version &service_test);

use FileHandle;
use Data::Dumper;
use XML::Simple;
use IPC::Open3;

use lib $main::runtimedir;
use csl_utils qw($TIMEOUT %ERRORS);
use strict;
use CSL::ThreeWare;
use ThreeWare::Query;

my $CONFIG = '/etc/3ware.conf';

my $CACHE_DIR = "/tmp/nagios_ntp"; # what directory to create error state information in
my $CACHE_FILE_SUFFIX = "_last_ok";
my $DIR_PERMS = 0777;           # Dir permisions for the chache directory
my $CACHE_FILE_PERMS = 0666;           # Dir permisions for the chache directory
my $ERROR_THRESHOLD = "120"; # default 2 hours threshold until a warning is an error
my $CACHE_FILE;  # defined later as $CACHE_DIR/$host . $CACHE_FILE_SUFFIX

my ($critical_error, $warning_error);

sub print_usage ();
sub print_version ();
sub service_test (%);

sub print_usage () {

    print <<__Eof__
Usage:  Check ntp server information
Options:
    -H <hostname> -P <portnumber>
    --stratum
    [--verbose]
    [--help]
    [--version]
    [--usage]
    [-t|--time <error threshold in seconds, default 120>]
__Eof__
  ;
    return $ERRORS{'OK'};
}

sub print_version () {
  my $version = '$Revision: 1.5 $ ';
    $version =~ s/^\$Revision: //;
    $version =~ s/ \$\s*$//;

    print "3ware.pm - $version\n";
    return $ERRORS{'OK'};
}

sub service_test (%) {
  my %options = @_;

  # make sure the state directory exists
  mkdir "$CACHE_DIR" if ! -d $CACHE_DIR;
  chmod $DIR_PERMS, $CACHE_DIR;

  if ($options{"opt_t"}) {
    $ERROR_THRESHOLD = $options{"opt_t"};
  }

  $critical_error = $warning_error = 0;

  if ($options{"verbose"}) {
    foreach my $opt (sort keys(%options)) {
      if ($options{$opt}) {
	print "$opt - $options{$opt}\n";
      }
    }
  }

  my $host = $options{"opt_H"};
  
  # with $host, define CACHE_FILE for later state use.
  $CACHE_FILE = $CACHE_DIR . "/" . $host . $CACHE_FILE_SUFFIX;

  if ((!$host) || ($host eq "")) {
    print "\nHost name not specified.\n";
    &print_usage();
    return $ERRORS{CRITICAL};
  }

  my $desired_stratum = $options{"opt_stratum"};
  if (!defined ($desired_stratum) || $desired_stratum < 1) {
    print "# Stratum not specified.\n";
    &print_usage();
    return $ERRORS{CRITICAL};
  }

  my ($cin, $cout);
  my $pid = open3 (
		   $cin, $cout, undef,
		   '/usr/sbin/ntpdc',
		   '-c',
		   'sysinfo',
		   $host,
		   );
  if (!defined $pid) {
    print "# Failed to start ntpdc for $host.\n";
    return $ERRORS{CRITICAL};
  }

  my $found_stratum;
  undef $cin;
  while (<$cout>) {
    if (/^stratum:\s+(\d+)/) {
      $found_stratum = $1;
      last;
    }
  }
  undef $cout;
  if (!defined $found_stratum) {
    print "# Failed to read stratum for $host.\n";
    return $ERRORS{CRITICAL};
  }

  my $now = time;

  if ($found_stratum != $desired_stratum) {
    my $last_ok_time = -M "$CACHE_FILE";
    $last_ok_time = ( int ($last_ok_time * 24 * 60 * 10 ) / 10);

    if ($last_ok_time >= $ERROR_THRESHOLD) {
      print "# $host ntp stratum incorrect ($found_stratum, should be $desired_stratum), over error threshold of $ERROR_THRESHOLD minutes.\n";
      return $ERRORS{CRITICAL};
    } 
    
    print "# $host ntp stratum incorrect ($found_stratum, should be $desired_stratum), under error threshold of $ERROR_THRESHOLD minutes.\n";
    return $ERRORS{WARNING};
  }

  system("touch $CACHE_FILE");
  chmod $CACHE_FILE_PERMS, $CACHE_FILE;

  print "# ntp status OK \n";
  return $ERRORS{OK};
}

1;
