#!/usr/bin/perl -wT # # deliverytimes.pl # Version 1.0.0 - 10/19/2003 # # Display SMTP delivery delay for spam and non-spam. # # # Copyright, (c) 2003, Corey S. McFadden & Associates (contact@csma.biz) # www.csma.biz # By postal mail: # McFadden Associates # PO Box 20665 # Lehigh Valley, PA 18002 # U.S.A. # # 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. # # use Time::Local; # Global Vars $IntMins = "5"; # Set this to your MRTG interval $MailLogFile = "/var/log/maillog"; # Change this if your maillog isn't here. $NonSpamCounter = 0; $SpamCounter = 0; $NonSpamTotal = 0; $SpamTotal = 0; $NonSpamAverage = 0; $SpamAverage = 0; @IDS = (); # Exec &Get_Time; &Process_Log; &Get_Mail_Times; &Print_Average; # Subroutines sub Get_Time { # Gets the start time and sets global variables. $timestart = time(); my $date = localtime(); my($day, $month, $num, $time, $year) = split(/\s+/,$date); $timeyear = $year; } sub Back_Time { # This is a debug mechanism for taking the seconds and converting them # back to human readable date format. (Not used in operation.) my $date = localtime($_[0]); my ($day, $month, $num, $time, $year) = split(/\s+/,$date); my $back = "[$month $num $time]"; return $back; } sub Rec_Time { # Takes a date string on input and returns the universal second count # which is better for comparing intervals. # input format is 'Sep 26 16:27:50' (syslog) my @DateString = split(/\ /,$_[0]); my @TimeString = split(/:/,$DateString[2]); my $month = $DateString[0]; if ($month eq "Jan") { $month = "1"; } if ($month eq "Feb") { $month = "2"; } if ($month eq "Mar") { $month = "3"; } if ($month eq "Apr") { $month = "4"; } if ($month eq "May") { $month = "5"; } if ($month eq "Jun") { $month = "6"; } if ($month eq "Jul") { $month = "7"; } if ($month eq "Aug") { $month = "8"; } if ($month eq "Sep") { $month = "9"; } if ($month eq "Oct") { $month = "10"; } if ($month eq "Nov") { $month = "11"; } if ($month eq "Dec") { $month = "12"; } $month = int($month - 1); my $iseconds = timelocal($TimeString[2],$TimeString[1],$TimeString[0] ,$DateString[1],$month,$timeyear); return $iseconds; } sub Process_Log { # Bulk of the processing occurs here. # 1. Mail Log is inputted and checked for 'score=2.0,' format entries. # 2. Only entries that fall within our program's interval are checked. # 3. A total is divided by a count producing an average. # 4. A global var is set with the average. my $totscore = "0"; my $count = "0"; my $int_secs = int($IntMins * 60); open (MAILLOG,$MailLogFile); while ($cline = ) { if ($cline =~ "stat=Sent") { my @curline = split(/\ /,$cline); my $recsecs = Rec_Time("$curline[0] $curline[1] $curline[2]"); my $distsecs = int($timestart - $recsecs); if ($int_secs > $distsecs) { # Line is within last 5 minutes my @msgid = split(/:/,$curline[5]); push @IDS,$msgid[0]; $count++; } } } close MAILLOG; } sub Print_Average { # Output the average in MRTG format. # if ($SpamCounter ne "0" && $SpamTotal ne "0") { # Div 0 protection $SpamAverage = int($SpamTotal / $SpamCounter); } if ($NonSpamCounter ne "0" && $NonSpamTotal ne "0") { $NonSpamAverage = int($NonSpamTotal / $NonSpamCounter); } print "$NonSpamAverage\n"; print "$SpamAverage\n"; } sub Get_Mail_Times { # Bulk of the processing occurs here. # 1. Mail Log is inputted and checked for 'score=2.0,' format entries. # 2. Only entries that fall within our program's interval are checked. # 3. A total is divided by a count producing an average. # 4. A global var is set with the average. my $int_secs = int($IntMins * 60); my $starttime = 0; my $stoptime = 0; my $spamstat = ""; foreach $in(@IDS) { open (MAILLOG,$MailLogFile); while ($cline = ) { if ($cline =~ "$in" && $cline =~ "from=") { my @curline = split(/\ /,$cline); $starttime = Rec_Time("$curline[0] $curline[1] $curline[2]"); } if ($cline =~ "$in" && $cline =~ "stat=Sent") { my @curline = split(/\ /,$cline); $stoptime = Rec_Time("$curline[0] $curline[1] $curline[2]"); } if ($cline =~ "$in" && $cline =~ "is spam,") { # spam, is spamassassin, no comma is usually blacklist $spamstat = "SPAM"; } } close MAILLOG; my $dist = 0; if ($starttime eq "0" || $stoptime eq "0") { $dist = 0; } else { $dist = ($stoptime - $starttime); } if ($spamstat eq "SPAM" && $dist ne "0") { $SpamCounter++; $SpamTotal = int($SpamTotal + $dist); } if ($spamstat ne "SPAM" && $dist ne "0") { $NonSpamCounter++; $NonSpamTotal = int($NonSpamTotal + $dist); } # print "$in: $dist seconds $spamstat\n"; $starttime = 0; $stoptime = 0; $spamstat = ""; } } exit 0;