# -*- perl -*-
#
# $Revision: 1.4 $
package windows_clusterfs;

require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw(&print_usage &print_version &service_test);
use lib $main::runtimedir;
use csl_utils qw($TIMEOUT %ERRORS);
use strict;
use Nagios::Config;
use Socket;
use Data::Dumper;
#use Filesys::SmbClient;

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

sub usage () {
    my $print = shift;
    print $print;
    print_usage();
}

sub print_usage () {

    print "
Usage:  Check windows service.
Options:
    -H <hostname> -P <portnumber> 
    --help
    --version
    --usage
";
    return $ERRORS{'OK'};
}

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

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

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

    my $bindir = "/s/nagios/libexec";
    my $check_nt = "$bindir/check_nt";

    my @disk = (101, 101);
    my @memory = (101, 101);
    my @uptime = (0, 10000);
    my $acronis = 0;
    my $WhatData;
    my @command;
    my $smbstatus;
    my $stdshare = "Disk\\\|C\\\$\\\|";
    my $clustershare;

    if (! -f $check_nt) {
        print "Cannot find check_nt at $check_nt\n";
        return $ERRORS{'UNKNOWN'}
    }

    # Load up all the new values and test them

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

    my $host = $options{"opt_H"};

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

    my $port = $options{"opt_P"};

    ($port) || ($port = 1248);

    my @CHECKS;
    push @CHECKS, "$check_nt -H $host -p $port -v SERVICESTATE -l ClusSvc,ClusDisk";

    my %revERRORS;

    foreach my $error (sort keys(%ERRORS)) {
        $revERRORS{$ERRORS{$error}} = $error;
    }
    
    my $output = "";
    my $status = $ERRORS{'OK'};

    my $share;
    my $junk;
    my $drive;
    my $directory;
    my $smbdir;
    my $primary;
    my $dirh;
    my $smbdir;
    my $clusterdir;
    my @smbclientdata;
    my @clusterdata;
    my @hostdata;

    # must include full AD FQDN or all this will fail
    if ($host =~ /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/) {
	# IP address...convert to FQDN
	my $iaddr = inet_aton($host);
	$host = gethostbyaddr($iaddr, AF_INET);
	# now treat it as if we had an FQDN in the first place
    }

    $host =~ s/\.\w+\.\w*\.edu//;
    $host =~ s/$/.ad.cs.wisc.edu/;
    my @pwinfo = getpwuid($<);
    my $login = @pwinfo[0];
    my $user = $login . "\@CS.WISC.EDU";
    if ($options{"verbose"}) {
    	print "Username: $user\n";
    }

    my $clustername = $host;
    $clustername =~ s/-[0-9]+//;

    # get share directory names dynamically via smbclient...too bad this 
    # can't be done via filessy::SmbClient  :(
    #
    # smbclient likes to blabber on stderr...this quiets it down

    if ($options{"verbose"}) {
    	print "\nRunning 'smbclient -U $user -k -g -L $clustername' to get cluster share drive/directory\n";
    }

    close STDERR;
    open STDERR, ">/dev/null";
    open(SHARELIST, "smbclient -U $user -k -g -L $clustername |");
#    || {
#    	$status = $ERRORS{'CRITICAL'};
#	$output = $revERRORS{$status} . ": Can't open smbclient connection!  " . $output;
#    }; 
    @clusterdata = <SHARELIST>;
    close(SHARELIST);

    open(SHARELIST, "smbclient -U $user -k -g -L $host |");
    @hostdata = <SHARELIST>;
    close(SHARELIST);

    # go looking for clustered fileserver shares...making the assumption that 
    # if shares {X}$ (drive letter) and {share}$ exist, directory {X}$/{share} 
    # will exist on the active node
    my $share, $junk, $drive, $directory, $smbdir;
    foreach (@clusterdata) {
    	if ($options{"verbose"}) {
	    print "processing share $_\n";
	}
    	if ( /^Disk/ || /[D-Z]$/ ) {
    	    # we have a disk share!
	    ($junk, $share, $junk) = split(/\|/);
	    if ( /[A-Z]\$/ ) {
	    	$drive = $share;
	    } else {
	    	if ( !($directory) ) {
	    	   $directory = $share;
		   $directory =~ s/\$$//;
	    	}
	    }
    	}
    }

    if (! $drive || ! $directory) {
    	$status = $ERRORS{'CRITICAL'};
        $output = $revERRORS{$status} . ": Drive or directory not available for host $host!" . $output;;
    } else {
    	$clusterdir = $drive . "\\" . $directory;
    	$clusterdir =~ s/\$/:/;
	#$clustershare = "Disk\\\|" . $drive . "\\\|" . $directory;	
	#$clustershare = "Disk|" . $drive . "|";
        $clustershare = "Disk\\\|" . $drive . "\\\|";
	$clustershare =~ s/\$/\\\$/;
    	if ($options{"verbose"}) {
	    print "Cluster share to check: $clustershare\n";
	}

    	# determine if we are the primary or secondary cluster host
    	if ($host =~ /\S+-1/ ) {
    	    $primary = 1;
    	} else {
    	    $primary = 0;
    	}
    	if ($options{"verbose"}) {
	    if ($primary == 1) {
	    	print "$host is primary node for cluster $clustername\n";
	    } else {
	    	print "$host is secondary node for cluster $clustername\n";
    	    }
    	}

	$smbstatus = grep {$_ =~ /$stdshare/ } @hostdata;
    	if ($options{"verbose"}) {
	    print "hostdata:\n" . Dumper(@hostdata);
	    print "Checking for C\$ share ($stdshare)\n";
	    #print "smbstatus:" . Dumper(@smbstatus) . "\n";
	    print "smbstatus (scalar): $smbstatus\n";
    	}
	if ($smbstatus != 1) {
    	    if ($options{"verbose"}) {
	    	print "Share C\$ cannot be found on host $host!\n";
	    }
	    $status = $ERRORS{'CRITICAL'};
    	    $output = $revERRORS{$status} . ": Cannot connect to host $host via smbclient! (add user $user to appropriate group or check SMB services)" . $output;
	} else {
	    $smbstatus = grep {$_ =~ /$clustershare/ } @hostdata;
    	    if ($options{"verbose"}) {
		print "clusterdata:\n" . Dumper(@clusterdata);
	        print "Checking to see if share $clustershare exists\n";
	        #print "smbstatus:" . Dumper(@smbstatus) . "\n";
	        print "smbstatus (scalar): $smbstatus\n";
		print "host: $host\tprimary: $primary\n";
    	    }
	    $clustershare =~ s/\\\$/:/;
	    $clustershare =~ s/\\\|/ /g;
	    if ($primary == 1) {
    	    	if ( $smbstatus > 0) {
	    	$output = $revERRORS{$status} . ": $clustershare present on server $host" . $output;
    	    	} else {
	    	$status = $ERRORS{'CRITICAL'};
    	    	$output = $revERRORS{$status} . ": $clustershare not present on server $host" . $output;
    	    	}
    	    } else {
    	    	if ( $smbstatus > 0) {
	    	$status = $ERRORS{'CRITICAL'};
    	    	$output = $revERRORS{$status} . ": $clustershare present on server $host" . $output;
    	    	} else {
    	    	$output = $revERRORS{$status} . ": $clustershare not present on server $host" . $output;
    	    	} 
    	    }
    	}
    }
    print "$output\n";
    print "Exit status: $status\n" if $options{"verbose"};

    exit $status;
}

