#    Big Sister sendmail queue size monitor
#
#    Copyright (C) 2001 ToolCASE LLC
#    Contact: Jacob Gore <jacob.gore@toolcase.com>, +1-303-771-5436.
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#    NB: This program has only been really tested on Solaris, though
#    it seems to work on Linux too.  The OS dependency is the format
#    produced by the "mailq" command.

#=============================================================================

package Monitor::sendmail;

require 5.002;

#use strict;

@Monitor::sendmail::ISA = qw(Monitor::Monitor);

sub new {
    my ($this, $mailq_command) = @_;

    print "SENDMAIL: Creating new monitor object...\n" if $BigSister::common::dl > 4;

    my  $class = ref($this) || $this;
    my  $self = {};

    bless($self, $class);

    # create an array to store the qmail queue limits info
    $self->{htable} = [];

    $self->{mailq_command} = defined $mailq_command ? $mailq_command : 'mailq';
    
    print "SENDMAIL: ...done.\n" if $BigSister::common::dl > 4;
    
    return $self;
}

sub add_check {
    my ($self, $max1, $max2, $item) = @_;

    my $htable = $self->{htable};

    # figure out how to report this data ( server name + monitor name )
    $item = $uxmon::hostname . '.mail' unless $item;

    print "SENDMAIL: add_check - item='$item'\n" if $BigSister::common::dl>3;

    # add this info to the configuration array
    push (@$htable, join("\x00", $item, $max1, $max2));
}

sub check {
    my ($self) = @_;

    unless (open(QUEUE, "$self->{mailq_command}|")) {
        $self->report($item, $BigSister::common::status_codes{yellow},
                      "Could not run '$self->{mailq_command}': $!");
        print "Could not run '$self->{mailq_command}': $!" if $BigSister::common::dl > 0;
        return;
    }

    my $line;
    
    my ($messages, $addresses, $messagesNow, $addressesNow) = (0, 0, 0, 0);
    
    my $now;

    while ($line = <QUEUE> && $line !~ /^[A-Za-z0-9]/) {
        next;   # Skip the header
    }
    
    while ($line = <QUEUE>) {
        
        if ($line =~ /^\s/) {
            
            next if ($line =~ /^\s+\(/); # An error message
            
            # An address
            if ($now) {
                $addressesNow++;
            }
            else {
                $addresses++;
            }
            
        } else {
            
            # ID* means it is being worked on now; ID means it is waiting
            if ($line =~ /^\S+\*/) {
                $now = 1;
                $messagesNow++;
            } else {
                $now = 0;
                $messages++;
            }
            
        }
    }

    unless (close(QUEUE)) {
        $self->report(
            $item,
            $BigSister::common::status_codes{yellow},
            "Could not close '$self->{mailq_command}': $!"
        );
        print "Could not close '$mailq_command': $!" if $BigSister::common::dl > 0;
        # return;
    }
    
    $self->set_variable('', 'sendmail.addresses',    $addresses);
    $self->set_variable('', 'sendmail.addressesNow', $addressesNow);
    $self->set_variable('', 'sendmail.messages',     $messages);
    $self->set_variable('', 'sendmail.messagesNow',  $messagesNow);

    # Loop throught every item to be checked (probably only one per box)
    # and set the state colors.
    my $htable = $self->{htable};
    for ($i=0; $i<=$#$htable; $i++) {
        ($item, $max1, $max2) = split("\x00", $$htable[$i]);

        print "working on '$i': item='$item' max1='$max1' max2='$max2'\n"
            if $BigSister::common::dl>3;

            # Are three enough messages to signal red?
            if (defined($max2) && $messages>$max2) {
                $self->report(
                    $item,
                    $BigSister::common::status_codes{red},
                    "$messages messages in the queue (more than $max2)"
                );
            } elsif (defined($max1) && $messages>$max1) {
                $self->report(
                    $item,
                    $BigSister::common::status_codes{yellow},
                    "$messages messages in the queue (more than $max2)"
                );
            } else {
                $self->report(
                    $item,
                    $BigSister::common::status_codes{green},
                    "$messages messages to $addresses address are in the queue, $messagesNow messages to $addressesNow are being delivered right now."
                );
            }
            
            print "Reached the end of sendmail check\n" if $BigSister::common::dl>3;
        
    }
}

1;
