#!/usr/bin/ruby

require 'yaml'


#
#  This class either a) returns the output of running commands, or
# b) returns the output from a faked command
#
class CommandWrapper

  def CommandWrapper.run_command( str )

    if ( ENV['TEST'] && ENV['TEST_PREFIX'] )
      #
      #  Count the number of commands we've executed so far.
      #
      count = ENV['TEST_COUNT'] || '0'
      count = count.to_i
      ENV['TEST_COUNT'] = (count + 1).to_s

      #
      #  Read the output from the faked file.
      #
      #    $prefix/$count.cmd
      #
      file = "#{ENV['TEST_PREFIX']}/#{count}.cmd"
      File.open( file, "r" ).readlines().join()
    else
      `#{str}`
    end
  end
end


#
# Count the pending messages in the exim4 mailq and alert if there are
# too many. By default '500' is the threshold, but this can be changed.
#
class EximMailQ

  #
  #  Invoke exim4 to see how many messages are in the queue.
  #
  def self.count
      if ( File.executable?( "/usr/sbin/exim4" ) or ENV['TEST'] )
        c = CommandWrapper.run_command( "/usr/sbin/exim4 -bpc" )
        return c.to_i unless( c.nil? )
      end
      0
  end

end



if __FILE__ ==  $PROGRAM_NAME

  def verbose(str)
    STDERR.puts(str)
  end

  to_raise = []

  #
  #  Count pending messages.
  #
  count = EximMailQ.count
  verbose( "exim4 mailq has #{count} entries" )

  #
  #  Determine how many is too many.
  #
  max = 500
  if File.exist?('/etc/mailq.threshold')
    new_max = File.readlines('/etc/mailq.threshold').first
    unless new_max.nil?
      max = new_max.chomp.to_i
    end
  end

  #
  #  If the count is too high alert.
  #
  if ( count >= max )
    h = {}
    h[:id] = "exim4-mailq"
    h[:summary] = "Too many messages in the exim4 mailq"
    h[:detail] = "<p>There are #{count} messages in the exim4 mailq.  That might mean the host is compromised, or otherwise broken.  If the threshold of #{max} is too low please edit '/etc/mailq.threshold'.</p>"
    to_raise.push(h)
  end

  #
  #  Show the output.
  #
  puts YAML.dump(to_raise)
  exit(0)
end
