#! /opt/perl/bin/perl -w
# -*- perl -*-

=head1 NAME

  sendmail_mailq

=head1 APPLICABLE SYSTEMS

  Systems running sendmail as MTA

=head1 CONFIGURATION

  [sendmail_mailq]
    user              root

    env.warning       200
    env.critical      300

    env.mtatotal      yes
    env.mtadetail     yes

    env.msptotal      yes
    env.mspdetail     yes

  This plugin shall run as user "root" because access to sendmail queues is 
  restricted to root.

=head1 BUGS/GOTCHAS

    None known - if you find one, drop a message to the author

=head1 AUTHOR

    Jose-Marcio Martins da Cruz - mailto:Jose-Marcio.Martins@mines-paristech.fr
    Ecole Nationale Superieure des Mines de Paris

=head1 VERSION 

   1.0 - Jan, 04, 2014

=head1 LICENSE

   GPLv2

=head1 MAGIC MARKERS

 #%# family=contrib
 #%# capabilities=autoconf

=cut

use strict;
use warnings;

my $MAILQ = "mailq";
my $SMCF  = "/etc/mail/sendmail.cf";

my %EnvConf = ('warning' => $ENV{'warning'} || '200',
               'critical' => $ENV{'critical'} || '300');
foreach my $k (qw(mtatotal mtadetail msptotal mspdetail)) {
  if (exists $ENV{$k}) {
    $EnvConf{$k} = $ENV{$k} =~ /^(yes|true|oui|vrai|1)$/i;
  } else {
    $EnvConf{$k} = 1;
  }
}

my $ThreshWarn = $ENV{'warning'}  || '200';
my $ThreshCrit = $ENV{'critical'} || '300';

if ($#ARGV >= 0 && $ARGV[0] eq "autoconf") {
  unless (-f $SMCF) {
    print "no\n";
    exit 0;
  }
  unless (system("$MAILQ > /dev/null 2>&1") == 0) {
    print "no\n";
    exit 0;
  }
  print "yes\n";
  exit 0;
}

if ($#ARGV >= 0 && $ARGV[0] eq "config") {
  my %MTAQueue = ();
  my %MSPQueue = ();

  GetQueue(\%MTAQueue, "",    $EnvConf{mtadetail}, $EnvConf{mtatotal});
  GetQueue(\%MSPQueue, "-Ac", $EnvConf{mspdetail}, $EnvConf{msptotal});

  print <<EOT;
graph_title    sendmail queue size
graph_category sendmail
graph_vlabel   messages
graph_scale    no
EOT
  my @ord = qw();
  push @ord, sort grep {$_ = "mta_" . $_;} keys %MTAQueue;
  push @ord, sort grep {$_ = "msp_" . $_;} keys %MSPQueue;
  printf "graph_order %s\n", join " ", @ord;
  foreach my $k (sort keys %MTAQueue) {
    printf "mta_%s.label MTA %s\n", $k, $MTAQueue{$k}{name};
    printf "mta_%s.warning %d\n",   $k, $ThreshWarn;
    printf "mta_%s.critical %d\n",  $k, $ThreshCrit;
  }
  foreach my $k (sort keys %MSPQueue) {
    printf "msp_%s.label MSP %s\n", $k, $MSPQueue{$k}{name};
    printf "msp_%s.warning %d\n",   $k, $ThreshWarn;
    printf "msp_%s.critical %d\n",  $k, $ThreshCrit;
  }
  exit 0;
}

if ($#ARGV < 0) {
  my %MTAQueue = ();
  my %MSPQueue = ();

  GetQueue(\%MTAQueue, "", $EnvConf{mtadetail}, $EnvConf{mtatotal});
  foreach my $k (sort keys %MTAQueue) {
    printf "mta_%s.value %d\n", $k, $MTAQueue{$k}{value};
  }
  GetQueue(\%MSPQueue, "-Ac", $EnvConf{mspdetail}, $EnvConf{msptotal});
  foreach my $k (sort keys %MSPQueue) {
    printf "msp_%s.value %d\n", $k, $MSPQueue{$k}{value};
  }
  exit 0;
}

sub GetQueue {
  my ($h, $opt, $detail, $total, undef) = @_;
  my @QUEUE   = `$MAILQ $opt 2>/dev/null`;
  my $totsz   = 0;
  my $ndetail = 0;
  foreach my $qline (@QUEUE) {
    if ($qline =~ /^\s*(\S+)\s+\((\d+)\s+request\)/) {
      $ndetail++;
      if ($detail || !$total) {
        my ($field, $name) = QueueName($1);
        $h->{$field}{name}  = $name;
        $h->{$field}{value} = $2;
        $totsz += $2;
      }
      next;
    }
    if ($qline =~ /^\s*(\S+)\s+is\s+empty/) {
      $ndetail++;
      if ($detail || !$total) {
        my ($field, $name) = QueueName($1);
        $h->{$field}{name}  = $name;
        $h->{$field}{value} = 0;
      }
      next;
    }
  }
  if ($total && $ndetail > 1) {
    $h->{zztotal}{name}  = "=== Total ===";
    $h->{zztotal}{value} = $totsz;
  }
}

sub QueueName {
  my ($q, undef) = @_;
  my ($field, $name) = (undef, undef);
  $name = `basename $q`;
  chomp $name;
  $field = $name;
  $field =~ s/[^A-Za-z0-9_]/_/g;
  return ($field, $name);
}

