#!/usr/bin/perl
#-----------------------------------------------------------------------------
#
#  weximlog.pl
#
#  http://www.remote.org/jochen/software/weximlog/
#
#-----------------------------------------------------------------------------
#
#  This Perl script will do the equivalent of a 'tail -f' on your exim log
#  file and list the top 20 list of sender addresses for the last hour on
#  the screen. This is a nice way to watch what is going on in your mail
#  system, especially if you suspect a mailloop or something like that. If
#  you have a large log file it will take a while to start up and the
#  program is a resource hog, because it may have to keep track of thousends
#  of email addresses, so be careful. 
#
#-----------------------------------------------------------------------------
#
#  Copyright (C) 1999, 2000  Jochen Topf <jochen@remote.org>
#
#  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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
#
#-----------------------------------------------------------------------------

use strict;

# exim logfile location
my $EXIMLOG="/var/log/exim/mainlog";

# count all mails newer than this
my $OFFSET="010000";	# hhmmss

#-----------------------------------------------------------------------------

my $CLEAR="[H[2J";
my (%adr, @adrlist);

my $hostname=`/bin/hostname`;
chomp $hostname;

open(LOG, $EXIMLOG) or die("Can't open exim log: $!\n");
readlogline();
printtop();
while(1) {
  sleep(10);
  readlogline();
  printtop();
}
exit 0;

sub readlogline {
  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
  my $dummy;
  my $now = sprintf("%4d%02d%02d%02d%02d%02d", 1900+$year, $mon+1, $mday, $hour, $min, $sec);

  while(<LOG>) {
    next unless (/<=/);
    my ($date, $time, $dummy, $dummy, $adr, $dummy) = split(/ /, $_, 6);
    (my $t = "$date$time") =~ s/[-:]//g;
    next if ($now - $t > $OFFSET);
    push(@adrlist, "$t $adr");
    $adr{$adr}++;
  }
}

sub printtop {
  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
  my ($entry, $text);

  my $now = sprintf("%4d%02d%02d%02d%02d%02d", 1900+$year, $mon+1, $mday, $hour, $min, $sec);

  while ($#adrlist > 0) {
    my ($time, $adr) = split(/ /, $adrlist[0]);
    last if ($now - $time < $OFFSET);
    shift @adrlist;
    $adr{$adr}--;
  }

  my $n = 0;
  foreach my $key (sort { $adr{$b} <=> $adr{$a} } keys %adr) {
    $text .= sprintf("%6d %s\n", $adr{$key}, $key);
    last if ($n >= 19);
    $n++;
  }

  print "$CLEAR";
  print "$hostname\n";
  print "Number Sender                (Mails in the last hour)\n";
  print "------------------------------------------------------------------------------\n";
  print "$text";
}

#-- THE END ------------------------------------------------------------------
