#!/usr/bin/perl -w
##########################################################################
# $Id: postfix,v 1.1 2003/11/03 04:49:18 kirk Exp $
##########################################################################
# $Log: postfix,v $
# Revision 1.1  2003/11/03 04:49:18  kirk
# Added postfix filter from Sven Conrad <sconrad@receptec.net>
#
# Revision 1.1  2002/03/29 15:32:14  kirk
# Added some filters found in RH's release
#
#
# Revision ???  2000/07/12 Simon Liddington <sjl@zepler.org>
# converted from sendmail to postfix Sven Conrad <scon@gmx.net>
# added unknown users
# added relay denials
# todo:
# add authentication warnings
# add forward errors
# add returns after 4 hours
# ignores alias database building
# ignores daemon start messages
# ignores clone messages
# ignores all to= lines whatever follows stat=
#
#
# Revision 1.1  2003/03/21 21:10  sven
# Initial revision
#
# filters all postfix/<process> messages
#
##########################################################################

########################################################
# This was written and is maintained by:
#    ??? Kenneth Porter <shiva@well.com> ???
#    changed by Sven Conrad <scon@gmx.net>
#
# Please send all comments, suggestions, bug reports,
#    etc, to ?? shiva@well.com.??
#    Sven Conrad <scon@gmx.net>
#
########################################################

$MsgsSent = 0;
$BytesTransferred = 0;
$FourHourReturns = 0;

while (defined($ThisLine = <STDIN>)) {
    if ( ( $ThisLine =~ m/^connect/ ) or 
	 ( $ThisLine =~ m/^disconnect/ ) or 
	 ( $ThisLine =~ m/^reload configuration/ ) or 
	 ( $ThisLine =~ m/^[a-zA-Z0-9]+: client/ ) or 
	 ( $ThisLine =~ m/^[a-zA-Z0-9]+: message-id/ ) or
	 ( $ThisLine =~ m/^[a-zA-Z0-9]+: skipped, still being delivered/ ) or
	 ( $ThisLine =~ m/^[a-zA-Z0-9]+: uid=0 from=<root>/ ) or
	 ( $ThisLine =~ m/^warning: [\.0-9]+: address not listed for hostname/ ) or
	 ( $ThisLine =~ m/^[a-zA-Z0-9]+: to\=\<.*>, relay\=.*, delay\=[0-9]+, status\=[sent|deferred]/ ) or
	 ( $ThisLine =~ m/^warning: [\.0-9]+: hostname .* verification failed: Host not found/ ) ) {
	# We don't care about these
    }
    elsif ( ($Bytes) = ($ThisLine =~ /^[a-zA-Z0-9]+: from=.*size=([0-9]+).*$/) ) {
	$MsgsSent++;
	$BytesTransferred += $Bytes;
    }
    elsif (($User) = ($ThisLine =~ /^[a-zA-Z0-9]+: to\=\<([^ ]*)>, relay\=local, delay\=[0-9]+, status\=bounced \(unknown user/)) {
	# unknown user
        $UnknownUsers{$User}++;
    }
    elsif (($Dest, $Relay, $Msg) = ($ThisLine =~ /^[a-zA-Z0-9]+: to\=\<([^ ]*)>, relay=([^ ]*).*, delay\=[0-9]+, status\=bounced \(([^)]*)/ )) {
	# unknown user
	#$Msg = " hello "
	#print "bounce message from " . $Dest . " msg : " . $Relay . "\n";
	if ($Relay =~ m/^[none|local|avcheck]/) {
	        $Temp = "To " . $Dest . " Msg=\"" . $Msg . "\"";
        	$LocalBounce{$Temp}++;				
	} else {
	        $Temp = "To " . $Dest . " Msg=\"" . $Msg . "\"";
        	$ForeignBounce{$Temp}++;
	}
    }
    elsif ( ($Relay,$Dest) = ($ThisLine =~ m/^reject: RCPT from ([^ ]*): 554 <([^ ]*)>.* Relay access denied.* to=([^ ]*)/) ) {
    	# print "reject: " . $ThisLine . "\n";
	# print "Relay :" . $Relay . " to " . $Dest . "\n";  
        $Temp = "From " . $Relay . " to " . $Dest;
        $RelayDenied{$Temp}++;
    }
#    elsif ( ($Warning)  = ($ThisLine =~ /^[a-zA-Z0-9]+: Authentication-Warning: [^ ]+: ([^ ]+ set sender to [^ ]+ using -f)/) ) {
#        $AuthWarns{$Warning}++;
#    }
#    elsif ( ($Forward,$Error) = ($ThisLine =~ /^[a-zA-Z0-9]+: forward ([^ ]*): transient error: (.*)$/) ) {
#        $Temp = $Forward . ": " . $Error;
#        $ForwardErrors{$Temp}++;
#    }
#    elsif ( ($Temp) = ($ThisLine =~ /^[a-zA-Z0-9]+: forward ([^ ]*: Permission denied)/) ) {
#        $ForwardErrors{$Temp}++;
#    }
#    elsif ( $ThisLine =~ m/^[a-zA-Z0-9]+: [a-zA-Z0-9]+: return to sender: Warning: could not send message for past 4 hours/ ) {
#        $FourHourReturns++;
#    }
    else {
	push @OtherList,$ThisLine;
    }
}

if ((@OtherList) or
    ($MsgsSent > 0) or
    ($FourHourReturns > 0) or
    (keys %UnknownUsers) or
    (keys %RelayDenied) or
    (keys %ForeignBounce) or
    (keys %LocalBounce) or
    (keys %AuthWarns) or
    (keys %ForwardErrors)) {
    print "\n\n --------------------- postfix Begin ------------------------ ";

    if($MsgsSent > 0) {
        print "\n\n" . $BytesTransferred . " bytes transferred";
        print "\n" . $MsgsSent . " messages sent";
    }

    if($FourHourReturns > 0) {
        print "\n\n" . $FourHourReturns . " messages returned after 4 hours";
    }

    if (keys %UnknownUsers) {
	print "\n\nUnknown users:\n";
	foreach $ThisOne (keys %UnknownUsers) {
	    print "    " . $ThisOne . ": " . $UnknownUsers{$ThisOne} . " Times(s)\n";
	}
    }

    if (keys %RelayDenied) {
	print "\n\nRelaying denied:\n";
	foreach $ThisOne (keys %RelayDenied) {
	    print "    " . $ThisOne . ": " . $RelayDenied{$ThisOne} . " Times(s)\n";
	}
    }

    if (keys %LocalBounce) {
	print "\n\nLocal Bounce:\n";
	foreach $ThisOne (keys %LocalBounce) {
	    print "    " . $ThisOne . ": " . $LocalBounce{$ThisOne} . " Times(s)\n";
	}
    }

    if (keys %ForeignBounce) {
	print "\n\nForeign Bounce:\n";
	foreach $ThisOne (keys %ForeignBounce) {
	    print "    " . $ThisOne . ": " . $ForeignBounce{$ThisOne} . " Times(s)\n";
	}
    }

    if (keys %AuthWarns) {
	print "\n\nAuthentication warnings:\n";
	foreach $ThisOne (keys %AuthWarns) {
	    print "    " . $ThisOne . ": " . $AuthWarns{$ThisOne} . " Times(s)\n";
	}
    }

    if (keys %ForwardErrors) {
	print "\n\nForwarding errors:\n";
	foreach $ThisOne (keys %ForwardErrors) {
	    print "    " . $ThisOne . ": " . $ForwardErrors{$ThisOne} . " Times(s)\n";
	}
    }

    if ($#OtherList >= 0) {
	print "\n\n**Unmatched Entries**\n\n";
	print @OtherList;
    }

    print "\n ---------------------- postfix End ------------------------- \n";

}

exit(0);

