#!/usr/bin/perl
#
#
# $Id: check_printer 65 2009-07-16 17:13:17Z ecrist $
# $HeadURL: https://www.secure-computing.net/svn/trunk/nagios/check_printer $

use strict;
use warnings;

use lib "/usr/local/libexec/nagios";
use utils qw(%ERRORS);
my $usage = "
Usage: $0 host_addr community warn% crit%

This script connects via SNMP to a print and checks printer supply
levels.  This script outputs performance data for all supplies
found for toner and drum.
";

die $usage unless ($#ARGV == 3);
my $base_oid = ".1.3.6.1.2.1.43.11.1.1";
my $name_oid = "6.1";
my $max_oid  = "8.1";
my $curr_oid = "9.1";
my $loop;

my $host = $ARGV[0];
my $comm = $ARGV[1];

my @vars = ("snmpwalk -On -v 1 -c $comm $host $base_oid.$name_oid",
	   "snmpwalk -On -v 1 -c $comm $host $base_oid.$max_oid",
	   "snmpwalk -On -v 1 -c $comm $host $base_oid.$curr_oid");
my(@values, @names, @max, @min);

foreach(@vars){
	@values = (@values, split /\n/, `$_`);
}
my %finvalues;
foreach(@values){
	# matching the following line
	# .1.3.6.1.2.1.43.11.1.1.6.1.1 = STRING: "Black Cartridge"
	$_ =~ m/^([\.\d]+).*:[\s\"]+([\d\w\s]+)\"*$/;
	$finvalues{"$1"} = $2;
}

my %status;
while (my ($key, $value) = each(%finvalues)){
	## sort this array into an associative in the following format:
	#    $status['name']   : Supply Name
	#    $status['curr']   : Supply Status
	#    $status['max']    : Supply Level When New
	my $search = quotemeta("$base_oid.$name_oid");
	if ($key =~ /^$search\.([\d\.]+)$/){
		## we'll assume a name
		$status{$value}{"sub"} = $1;
	}
}

while (my ($key, $value) = each(%finvalues)){
	my $search = quotemeta("$base_oid.$max_oid");
	if ($key =~ /^$search\.([\d\.]+)$/){
		## assign it to the other variable
		## search the existing keys, find the one we want
		foreach my $subvalue (values %status){
			if ($subvalue->{"sub"} eq $1){
			$subvalue->{"max"} = $value;
			}
		}
	}
}
	
while (my ($key, $value) = each(%finvalues)){
	my $search = quotemeta("$base_oid.$curr_oid");
	if ($key =~ /^$search\.([\d\.]+)$/){
		## assign it to the other variable
		## search the existing keys, find the one we want
		foreach my $subvalue (values %status){
			if ($subvalue->{"sub"} eq $1){
				$subvalue->{"curr"} = $value;
			}
		}
	}
}

## Assemble performance data and error string.
my $perf_str = "";
my $is_warn = 0;
my $is_crit = 0;
my $err_str = "";
while (my($key, $value) = each(%status)){
	my $maximum = $value->{"max"};
	my $current = round(($value->{"curr"} / $maximum) * 100);
	
	my $critical = $ARGV[3];
	my $warning = $ARGV[2];
	if ($current < $critical){
		$is_crit = $is_crit + 1;
		if ($err_str eq ""){
			$err_str = "$key";
		} else {
			$err_str = "$err_str, $key";
		}
	} elsif ($current < $warning){
		$is_warn = $is_warn + 1;
		if ($err_str eq ""){
			$err_str = "$key";
		} else {
			$err_str = "$err_str, $key";
		}
	}
	$perf_str = "$perf_str '$key'=$current%;$warning;$critical;0;100; ";
}

if ($is_crit){
	print "$err_str CRITICAL.  See http://$ARGV[0] | $perf_str";
	exit $ERRORS{'CRITICAL'};
} elsif ($is_warn){
	print "$err_str WARNING. See http://$ARGV[0] | $perf_str";
	exit $ERRORS{'WARNING'};
} else {
	print "Printer Supplies OK | $perf_str";
	exit $ERRORS{'OK'};
}


###
### subroutines here
###

sub round {
	my($number) = shift;
	return int($number + .5 * ($number <=> 0));
}
