#!/usr/bin/env perl # # Lester the Lister - list e-mail traffic by date # # Digests sendmail logs to list e-mail sent/received by a given person. # # Eric Myers - 10 June 2000 # $Id: Lester,v 1.5 2004/04/03 15:41:54 myers Exp myers $ ####################################################################### $DEBUG=0; @logfiles = ( "/var/log/mail.log" ); chop( $basename = `basename $0` ); # So we know who we are chop( $hostname = `hostname`); require "getopts.pl"; &Getopts('u:'); if ( $opt_u ) { $User = $opt_u; &Debug(2,"User is $User"); } # remaining arguments (optional) are log files. if ( @ARGV ) { @logfiles = @ARGV; } @FromList=(); $N = 0; $WhoFrom =""; $WhoTo = ""; $ID = ""; $=--; # too long ################################################### # Open the input log file: while ( @logfiles ) { $maillog = shift @logfiles ; open(LOG, "<$maillog" ) || warn "Can't open input log file $maillog on $hostname.\n"; # Read and process lines from log file: READ: while () { $N++; # Unpack line from sendmail access_log file: ( $timestamp, $host, $prog, $pid, $jobID, $text ) = m/^(\S+\s+\S+\s\S+):\d\d\s(\S+)\s(\S+)\[(.*)\]:\s+(\S+):\s+(.*)/; next if ( "$prog" != "sendmail" ); next unless ( $jobID ); &Debug(7,"sendmail: $jobID:\n\t TEXT:$text"); # Digest from= lines &Debug(7, "Looking for from=..."); ( $from ) = $text =~ m/from=(\S+),/; if ( $from ) { &Debug(7,"...found it. $jobID: Setting from=$from"); $FromList{$jobID}=$from; $from=""; next; } # Digest to= lines &Debug(7, "Looking for to=..."); ( $to, $stat ) = $text =~ m/to=(\S+)\s*,.* stat=(\S+)/; if ( $to ) { &Debug(7,"...found it. $jobID: Setting to=$to"); $from=$FromList{$jobID}; if ( "$stat" eq "Sent" ) { if ( $StatList{$jobID} ) { $stat = $StatList{$jobID}; } if ( $User ) { $i = index($from,$User); &Debug(6,"Index of $User in $from is $i"); $i = index($to,$User); &Debug(6,"Index of $User in $to is $i"); next if ( index($from,$User)<0 && index($to,$User)<0 ); } write; } else { $StatList{$jobID} = $stat; $ToList{$jobID} = $to; } next; } # Digest "returned to sender" lines &Debug(7,"Looking for return to sender..."); ( $newID ) = $text =~ m/(\S+):\s+return to sender:/; if ( $newID ) { &Debug(7,"$newID: bounced back."); $StatList{$newID} = "$jobID returned to sender"; $FromList{$newID}= "postmaster"; $from=$FromList{$jobID}; $to=$ToList{$jobID}; $stat="returned"; if ( $User ) { $i = index($from,$User); &Debug(6,"Index of $User in $from is $i"); $i = index($to,$User); &Debug(6,"Index of $User in $to is $i"); next if ( index($from,$User)<0 && index($to,$User)<0 ); } write; next; } &Debug(6, "UNRECOGNIZED LINE: $text"); } } ################################################## sub Debug { $DEBUG || return; if ( $_[0] =~ m/^\d+$/ && $_[0] > 0 ) { $level = $_[0]; shift;} else { # default if there is no debug level $level = 5; } if ( $level <= $DEBUG ) { local(@msg) = @_; print "Debug[$level]: @msg \n"; } } ################################################## # Formats for the report format STDOUT = @<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<< $timestamp $to $from $stat . format STDOUT_TOP = Page @<< $% Date Time To From Status ====== ===== ========================= ========================== ======== . __END__;