#!/usr/bin/perl

use strict;
use warnings;

=head1 NAME

lpstat - Plugin to graph the queue size for the list of printers
available through the command "lpstat"

=head1 CONFIGURATION

No configuration

=head1 AUTHORS

Anstat Pty Ltd
Nikolai Langfeldt

=head1 LICENSE

Gnu GPL

=head1 NOTES

This script was initially developed by Anstat Pty Ltd for internal use
and has kindly been made available to the Open Source community for
redistribution and further development under the terms of the
GNU General Public License: http://www.gnu.org/licenses/gpl.html

Re-adapted to munin by Nikolai Langfeldt for Oslo Airport

=head1 MAGIC MARKERS

 #%# family=auto
 #%# capabilities=autoconf

=cut


use Getopt::Std;

my $printer;
my @printers;
my $status;
my @jobs;
my $n_jobs;
my @exclude;  # Should take this from environment.

# Force C output from lpstat
$ENV{'LC_MESSAGES'} = "C";

# This is a dumb-down.  Should take hostname(s) from environment or
# as wildcard plugin.
my $host = '127.0.0.1';

my $lpstat = exists $ENV{lpstat} ? $ENV{lpstat} : '';

# If the envvar is not set, look for lpstat
if (!$lpstat) {
   # Still not found? Check obvious places
    my @dirs = split(':',$ENV{PATH});
    push (@dirs, qw(/usr/bin /usr/sbin /usr/local/bin /usr/local/sbin) );

    until ($lpstat or @dirs == 0) {
        my $dir = shift @dirs;
        my $path = $dir.'/lpstat';
        $lpstat = $path if -x $path;
    }
} elsif (! -x $lpstat) {
    # If it is set, verify it
    warn "Predefined lpstat ($lpstat) is not a executable\n";
    undef $lpstat;
}

if (defined($ARGV[0]) && $ARGV[0] eq 'autoconf') {
    if( ! -x $lpstat ) {
        print "no (lpstat not found)\n";
        exit 0;
    }
    if( ! open(LPSTAT_R, "$lpstat $host -v 2>/dev/null |") ) {
        print "no (could not execute lpstat)\n";
        exit 0;
    }
    $_ = <LPSTAT_R>;
    if ( ! close(LPSTAT_R) ) {
        print "no (lpstat returned non-zero)\n";
        exit 0;
    }

    if (! m/device for /mi) {
        print "no (no printers configured)\n";
        exit 0;
    }
    print "yes\n";
    exit 0;
}

####################################################
# Check printers are accepting jobs
####################################################
# Get list of printers, showing which are accepting jobs...
if( ! open(LPSTAT_A, "$lpstat $host -a|") ) {
    print "graph_title Could not execute lpstat command\n";
    exit -1;
}

while(<LPSTAT_A>) {
    chomp;
    /(\S+) (.*) since/mi ;
    $printer = $1;
    $status = $2;
    if( grep /^$printer$/, @exclude ) {
	next;
    }
    if( /accepting/ ) {
	@printers = ( @printers, $printer );
    }
}
close(LPSTAT_A);

####################################################
# Check printers are enabled
####################################################
# Get list of printers, showing which are enabled/disabled...
if( ! open(LPSTAT_P, "$lpstat $host -p|") ) {
    print "graph_title Could not execute lpstat command\n";
    exit -1;
}

my %jobs = ();

while(<LPSTAT_P>) {
    if ( /^printer\s+(\S+)\s.*disabled/mi ) {
        $printer=$1;
        if( grep /^$printer$/, @exclude ) {
            next;
        }
    }
}
close(LPSTAT_P);

# Get list of jobs for each printer...
foreach $printer ( @printers ) {
    if( grep /^$printer$/, @exclude ) {
        next;
    }

    if( ! open(LPSTAT, "$lpstat $host -o $printer|") ) {
        print STDERR "Could not execute command: '$lpstat -o $printer' \n";
        exit 2;
    }
    @jobs = ( <LPSTAT> );
    $n_jobs = @jobs;
    $jobs{$printer}=$n_jobs || 0;
}

if ( defined($ARGV[0]) && $ARGV[0] eq 'config') {
    print "graph_title Print queues
graph_args --base 1000
graph_vlabel Queued jobs
graph_category printing
";
    foreach my $printer (sort(keys %jobs)) {
        print "$printer.label $printer\n";
        print "$printer.type COUNTER\n";
    }
    exit 0;
}

foreach my $printer (sort(keys %jobs)) {
    print "$printer.value ",$jobs{$printer},"\n";
}
