#!/usr/bin/perl -w

# disk check module

# Version: $Revision: 0.11 $
# Author: Benjamin Oshrin and Matt Selsky
# Date: $Date: 2005/12/21 23:29:22 $
#
# Copyright (c) 2002 - 2003
# The Trustees of Columbia University in the City of New York
# Academic Information Systems
# 
# License restrictions apply, see doc/license.html for details.

use strict;
use FindBin;
use lib "$FindBin::Bin/../common";
use Survivor::Check;

my %argformat = (# Warning threshold
		 "warn" => "optional number between(0,101) default(101)",
		 # Problem threshold
		 "prob" => "optional number between(0,101) default(101)",
		 # Filesystems to check
		 "filesystem" => "optional directory list",
		 # Configuration file
		 "diskcf" => "optional file");

sub DiskValidate {
    return(MODEXEC_OK, 0, 'Disk OK');
}

sub DiskCheck {
    my ($self, $host) = @_;

    my @fs = ();

    if($self->Arg('filesystem')) {
	@fs = $self->Arg('filesystem');
    } else {
	@fs = $self->ShouldBeMountedFilesystems('local');
    }

    unless(scalar @fs) {
	return(MODEXEC_NOTICE, 0, 'No filesystems to check');
    }

    my(%fswarn, %fsprob);

    # If we were given a control file, parse it

    my $cf = $self->Arg('diskcf');
    
    if(defined $cf) {	
	open(CONTROL, $cf) || return(MODEXEC_MISCONFIG, 0,
				     "Unable to read configuration file $cf");

	while(<CONTROL>) {
	    chomp;          # Toss newline
	    s/#.*$//;       # Toss comments
	    s/^\s+//;       # Toss initial spaces
	    s/\s+$//;       # Toss final spaces
	    my($xfs,$xwarn,$xprob) = split(/,/, $_, 3);
	    
	    if(defined $xfs && $xfs ne '') {
		$fswarn{$xfs} = $xwarn;
		$fsprob{$xfs} = $xprob;
	    }
	}

	close(CONTROL);
    }
    
    my $DF;
    if(!$self->IsBSDish()) {
	$DF = '/bin/df -k';
    } else {
	$DF = '/bin/df';
    }
    $DF .= ' ' . join(' ', @fs);

    # Prepare some result text strings
    my $count = 0; # If not given fs, scalar is number of "full" filesystems
    my $max = 0;   # If given, scalar is fullness of that fs

    open(ANSWER, "$DF 2>/dev/null |") || return(MODEXEC_PROBLEM, 0,
					 "Failed to exec $DF");

    # Skip header
    <ANSWER>;
    
    while(<ANSWER>) {
	chomp;

	my($raw,$kb,$used,$avail,$capacity,$mount) = split(/\s+/, $_, 6);

	# Check for device and rest on separate lines
	if(defined $raw && !defined $kb) {
	    chomp($_ = <ANSWER>);
	    s/^\s+//;
	    ($kb,$used,$avail,$capacity,$mount) = split(/\s+/, $_, 5);
	}

	chop($capacity);

	my $w = -1;
	my $p = -1;

	foreach my $key (keys %fswarn) {
	    if($mount =~ /$key/) {
		if($w == -1) {
		    $w = $fswarn{$key};
		    $p = $fsprob{$key};
		}
	    }
	}

	if($w == -1) {
	    $w = $self->Arg('warn');
	    $p = $self->Arg('prob');
	}

	if($capacity >= $p) {
	    $self->AccResultAdd($host, MODEXEC_PROBLEM,
				"$mount at $capacity%");
	    $count++;
	} elsif($capacity >= $w) {
	    $self->AccResultAdd($host, MODEXEC_WARNING,
				"$mount at $capacity%");
	    $count++;
	} else {
	    $self->AccResultAdd($host, MODEXEC_OK,
				"$mount at $capacity%");
	}

	if($capacity > $max) {
	    $max = $capacity;
	}
    }

    close(ANSWER);

    if(defined $self->Arg("filesystem")) {
	$count = $max;
    }

    return($self->AccResultGet($host, $count));
}

my $sc = new Survivor::Check();

$sc->GetOpt(\%argformat, \&DiskValidate);

my $r = $sc->Exec(\&DiskCheck);

exit($r);
