#!/s/std/bin/perl -w
# -*- perl -*-
#
# $Revision: 1.2 $
package lowmemory;

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 integer;

use Socket;
use POSIX;

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

sub error () {
    my $print = shift;
    print "CRITICAL: $print";
    return $ERRORS{'CRITICAL'};
}

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

sub print_usage () {
    print "
Usage:  Check lowmemory usage.
Options:
    -H <hostname> [-v -l <warn percent,crit percent> ]
    --help
    --version
    --usage
";
    return $ERRORS{'OK'};
}

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

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


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

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

    my $host = $options{"opt_H"};
    ($host) || ($host = "localhost");

    my $port;
    ($port = $options{"opt_P"}) || ($port = 49184);

    my @low = (1, 0);

    ((@low) = 
        split(",", $options{"opt_l"})) if ($options{"opt_l"});
    &usage("Bad Low\n") if 
        ((!defined($low[0])) || (!defined($low[1])) || ($low[0] < $low[1]));

    print "Hostname: $host \nLow Memory: $low[0] - $low[1]\n" if $options{"verbose"};

    my $state = "OK";
    my @meminfo;

    if ($host ne "localhost") {
        my $remoteaddr = inet_aton("$host");
        my $paddr = sockaddr_in($port, $remoteaddr) || 
                return &error("Can't create info for connection: $!\n");
        my $proto = getprotobyname('tcp');
        socket(Server, PF_INET, SOCK_STREAM, $proto) ||
                return &error("Can't create socket: $!\n");
        setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, 1);
        connect(Server, $paddr) || return &error("Can't connect to server: $!\n");

        select(Server);
        $| = 1;

        @meminfo = <Server>;
        close(Server);
        select(STDOUT);
    } else {
        open (IN, "/proc/meminfo");
        while (<IN>) {
            push @meminfo, $_;
        }
        close IN;
    }

    my ($free, $total);
    foreach my $memory (@meminfo) {
        next unless ($memory =~ /Low(Total|Free)/);
        $memory =~ / (\d+)[ \.]/;
        if ($total) {
            $free = $1;
            last;
        } else {
            $total = $1;
        }
    }

    my $percent = $free *100 / $total;

    print "Percent = $percent\n" if ($options{"verbose"});

    if ($percent <= $low[1]) {
        $state = "CRITICAL";
    } elsif ($percent <= $low[0]) {
        $state = "WARNING";
    }

    print "$state: %$percent Low Memory Free (warn=$low[0]%, crit=$low[1]%)\n";

    exit $ERRORS{$state};

}

