#! /usr/local/bin/perl # $Id: sm.logger,v 1.3 92/08/25 16:00:34 drich Exp Locker: drich $ # $Id: sm.logger,v 1.4 8th Feb 2002 sins Exp Locker: sins $ # # Original Copyright (C) 1992 Daniel Rich # Copyright (C) 2002 Sinclair InterNetworking Services # # Author: Daniel Rich (drich@lerc.nasa.gov) # Author: Sinclair InterNetworking Services (andrew@sins.com.au) # # 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 1, 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. # # A copy of the GNU General Public License can be obtained from this # program's author (send electronic mail to ange@hplb.hpl.hp.com) or from # the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA # 02139, USA. # # sm.logger - parse the sendmail log and produce a summary # # $Log: sm.logger,v $ # Revision 1.4 02/02/07 sins # Add new log formats to handle sendmail 9.11.6 on Suns and Cobalt RAQ4 # Change column formatting for easier Excel Imports # # Revision 1.3 92/08/25 16:00:34 drich # Fixed divide by zero error if no mail either delivered or sent. # # Revision 1.2 92/08/05 14:03:14 drich # Replaced '=' with '-' in output report # # Revision 1.1 92/07/22 16:36:54 drich # Logfile processor for sendmail # # # Written by Dan Rich - drich@lerc.nasa.gov # Wed July 22, 1992 # $debug=shift ; # Change the following for the appropriate system type. $systype = "Solaris"; # Valid are Ultrix, Sun, SGI, RS6000, Solaris # Change the following to the local sendmail domain $local_domain = "webdata.com.au"; if (! ($MAILLOG = shift)) { LOOP: { if ( $systype eq "SGI") { $MAILLOG = "/usr/adm/SYSLOG"; last LOOP; } if ( $systype eq "Ultrix") { $MAILLOG = "/usr/spool/mqueue/syslog"; last LOOP; } if ( $systype eq "Sun") { $MAILLOG = "/var/adm/messages"; last LOOP; } if ( $systype eq "Solaris"){ $MAILLOG = "/var/log/syslog" ; print "Solaris - /var/log/syslog" ; last LOOP; } if ( $systype eq "RS6000") { $MAILLOG = "/var/adm/messages"; last LOOP; } print "This script does not support the system type: $systype"; exit(1); } } sub parse_mail_addr { local($addr) = @_; # Attempt to parse an address down to an *originating* user and host. # Assume the address takes one of the following forms: # user@host.domain # host!host!host!user # host!host!host!user@host.domain # @host.domain:user@host.domain $user = ""; $host = ""; $domain = ""; # Get rid of <> in address $addr =~ s/\//g; # Get rid of (Real Name) $addr =~ s/\(.*\)//; # Strip spaces $addr =~ s/ //g; # Split user and host if ( $addr =~ /[@!]/ ) { # If we have and @ or ! address if ( (($user,$host) = ($addr =~ /@.*:(.*)@(.*)/ )) || (($user,$host) = ($addr =~ /(.*)@(.*)/ )) ) { if ( $user =~ /!/ ) { ( $host, $user ) = ( $user =~ /([^!]*)!([^!]*)$/ ); } } else { # Ok, it is uucp format if ( $addr =~ /!/ ) { ( $host, $user ) = ( $addr =~ /([^!]*)!([^!]*)$/ ); } } } else { # This had better be local... $user = $addr; $host = ""; $domain = ""; } # Split host and domain if ( $host =~ /\./ ) { ($host,$domain) = ( $host =~ /([^.]*)\.(.*)/ ); } return ($user, $host, $domain); } sub format_addr { local($username, $host, $domain) = @_; $addr = ""; $username =~ tr/A-Z/a-z/; $host =~ tr/A-Z/a-z/; $domain =~ tr/A-Z/a-z/; if ((length($domain) != 0) && ($domain ne $local_domain)) { $addr = $username. "@" . $host . "." . $domain; } elsif (length($host) != 0 ) { $addr = $username. "@" . $host; } else { $addr = $username; } return $addr; } sub format_host { local($host, $domain) = @_; $addr = ""; $host =~ tr/A-Z/a-z/; $domain =~ tr/A-Z/a-z/; if (($domain eq $local_domain) || (($host . "." . $domain) eq $local_domain) || (length($domain) == 0)) { $addr = "local"; } else { $addr = $host . "." . $domain; } return $addr; } open (MAILLOG) || die "failed to open log file: $!\n"; $start_date = ""; $start_time = ""; while ( ) { $line = ""; ( $systype eq "SGI" ) && ( /sendmail\[[0-9]*\]:/ && ($line = $_) ); ( $systype eq "Sun" ) && ( /sendmail\[[0-9]*\]:/ && ($line = $_) ); ( $systype eq "Solaris" ) && ( /sendmail\[[0-9]*\]:/ && ($line = $_) ); ( $systype eq "Ultrix") && ( /sendmail:/ && ($line = $_) ); if ( length($line) == 0 ) { next; } if ( length($start_date) == 0 ) { ($start_date, $start_time) = ($line =~ /^([A-Z][a-z]* *[0-9]*) ([0-9][0-9]:[0-9][0-9]:[0-9][0-9])/); } ($end_date, $end_time) = ($line =~ /^([A-Z][a-z]* *[0-9]*) ([0-9][0-9]:[0-9][0-9]:[0-9][0-9])/); $counter++; if ($debug>9) { print "$counter:\t$line" ; } if ($debug) { last if ($counter>50 ); } # if (($ID, $addr) = ($line =~/: ([A-Za-z0-9]*): to=(.*), delay/)) { # Changed by Andrew 07.02.02 for new format within [ ] section # Get the ID(unique) and the to address if (($ID2, $ID, $addr) = ($line =~/: \[ID ([0-9]*) mail.info\] ([A-Za-z0-9]*): to=(.*), delay/)) { if ($debug>9) { print "####to if\n" ; } if ( $line =~ /stat=Sent/ ) { if ($debug>9) { print "####Sent if\n" ; } foreach $taddr (split(/,/, $addr)) { ($username, $host, $domain) = &parse_mail_addr($taddr); $user = &format_addr($username, $host, $domain); $host = &format_host($host, $domain); $userlist{$user} = 1; $delivered{$user} .= $ID . ' '; $hostlist{$host} = 1; $delivered{$host} .= $ID . ' '; # Check if it was deferred $IDlist = $deferred{$user}; foreach $tID (split(/ /, $IDlist)) { if ( $tID == $ID ) { $deferred{$user} =~ s/$ID //g; } } $IDlist = $deferred{$host}; foreach $tID (split(/ /, $IDlist)) { if ( $tID == $ID ) { $deferred{$host} =~ s/$ID //g; } } } } elsif ( $line =~ /stat=Deferred/ ) { foreach $taddr (split(/,/, $addr)) { ($username, $host, $domain) = &parse_mail_addr($taddr); $user = &format_addr($username, $host, $domain); $host = &format_host($host, $domain); $userlist{$user} = 1; $hostlist{$host} = 1; # Check if it was deferred earlier $IDlist = $deferred{$user}; $IDdeferred = 0; foreach $tID (split(/ /, $IDlist)) { if ( $tID == $ID ) { $IDdeferred = 1; } } if ( $IDdeferred == 0 ) {$deferred{$user} .= $ID . ' ';} $IDlist = $deferred{$host}; $IDdeferred = 0; foreach $tID (split(/ /, $IDlist)) { if ( $tID == $ID ) { $IDdeferred = 1; } } if ( $IDdeferred == 0 ) {$deferred{$host} .= $ID . ' ';} } } else { if ($debug>9) { print "####first else\n" ;} foreach $taddr (split(/,/, $addr)) { ($username, $host, $domain) = &parse_mail_addr($taddr); $user = &format_addr($username, $host, $domain); $host = &format_host($host, $domain); $IDlist = $deferred{$user}; foreach $tID (split(/ /, $IDlist)) { if ( $tID == $ID ) { $deferred{$user} =~ s/$ID //g; last; } } $IDlist = $deferred{$host}; foreach $tID (split(/ /, $IDlist)) { if ( $tID == $ID ) { $deferred{$host} =~ s/$ID //g; last; } } } } } #if (($ID, $addr, $size) = ($line =~/: ([A-Za-z0-9]*): from=(.*), size=([0-9]*)/)) { if (($ID2, $ID, $addr, $size) = ($line =~/: \[ID ([0-9]*) mail.info\] ([A-Za-z0-9]*): from=(.*), size=([0-9]*)/)) { if ($debug>9) { print "from if#####\n" ; } ($username, $host, $domain) = &parse_mail_addr($addr); $user = &format_addr($username, $host, $domain); $host = &format_host($host, $domain); $userlist{$user} = 1; $sent{$user} .= $ID . ' '; $hostlist{$host} = 1; $sent{$host} .= $ID . ' '; $size{$ID} = $size; } } printf ("\n\n\t\t\tSendmail activity report\n"); printf ("Starting: %s %s\n",$start_date,$start_time); printf ("Ending: %s %s\n",$end_date,$end_time); # # User statistics $totsent = 0; $totdelivered = 0; $totpctsent =0; $totpctdelivered = 0; $countsent = 0; $countdelivered = 0; $countdeferred = 0; foreach $user (sort keys(%userlist)) { $totsent{$user} = 0; $totdelivered{$user} = 0; $countsent{$user} = 0; $countdelivered{$user} = 0; $countdeferred{$user} = 0; # Count total messages sent by each user $IDlist = $sent{$user}; foreach $ID (split(/ /, $IDlist)) { $totsent{$user} += $size{$ID}; $countsent{$user}++; } $totsent += $totsent{$user}; $countsent += $countsent{$user}; # Count total messages received by each user $IDlist = $delivered{$user}; foreach $ID (split(/ /, $IDlist)) { $totdelivered{$user} += $size{$ID}; $countdelivered{$user}++; } $totdelivered += $totdelivered{$user}; $countdelivered += $countdelivered{$user}; # Count deferred messages for each user $IDlist = $deferred{$user}; foreach $ID (split(/ /, $IDlist)) { $countdeferred{$user}++; } $countdeferred += $countdeferred{$user}; } printf ("\n\n"); $REPORTFMT = "%-20s %5s %8s\n"; $REPORTNUM = "%-20s %5d %8d\n"; printf ($REPORTFMT,"Message Status","Total","Size"); printf ("-----------------------------------\n"); printf ($REPORTNUM,"Received",$countsent,$totsent); printf ($REPORTNUM,"Delivered",$countdelivered,$totdelivered); printf ($REPORTNUM,"Deferred",$countdeferred); printf ("\n\nUser Statistics:\n\n"); $REPORTFMT = "%-30s %6s %8s %7s %6s %8s %7s\n"; $REPORTNUM = "%-30s %6d %8d %6.2f%% %6d %8d %6.2f%%\n"; printf ($REPORTFMT,"Username","#from","size","%","#to","size","%"); printf ($REPORTFMT,"---------","------","--------","------","------","--------","------"); foreach $user (sort keys(%userlist)) { $percent1 = 0; $percent2 = 0; $percent1 = ($totsent{$user}/$totsent)*100 if ($totsent != 0); $percent2 = ($totdelivered{$user}/$totdelivered)*100 if ($totdelivered != 0); printf ($REPORTNUM,substr($user,0,30), $countsent{$user},$totsent{$user},$percent1, $countdelivered{$user},$totdelivered{$user},$percent2); $totpctsent += $percent1; $totpctdelivered += $percent2; } printf ("------------------------------------------------------------------------------\n"); printf ($REPORTNUM,"Totals",$countsent,$totsent,$totpctsent,$countdelivered,$totdelivered,$totpctdelivered); # # Host statistics foreach $host (sort keys(%hostlist)) { $totsent{$host} = 0; $totdelivered{$host} = 0; $countsent{$host} = 0; $countdelivered{$host} = 0; $countdeferred{$host} = 0; # Count total messages sent by each host $IDlist = $sent{$host}; foreach $ID (split(/ /, $IDlist)) { $totsent{$host} += $size{$ID}; $countsent{$host}++; } # Count total messages received by each host $IDlist = $delivered{$host}; foreach $ID (split(/ /, $IDlist)) { $totdelivered{$host} += $size{$ID}; $countdelivered{$host}++; } } printf ("\n\nHost Statistics:\n\n"); $REPORTFMT = "%-30s %6s %8s %7s %6s %8s %7s\n"; $REPORTNUM = "%-30s %6d %8d %6.2f%% %6d %8d %6.2f%%\n"; printf ($REPORTFMT,"Hostname","#from","size","%","#to","size","%"); printf ($REPORTFMT,"---------","------","--------","------","------","--------","------"); foreach $host (sort keys(%hostlist)) { $percent1 = 0; $percent2 = 0; $percent1 = ($totsent{$host}/$totsent)*100 if ($totsent != 0); $percent2 = ($totdelivered{$host}/$totdelivered)*100 if ($totdelivered != 0); printf ($REPORTNUM,substr($host,0,30), $countsent{$host},$totsent{$host},$percent1, $countdelivered{$host},$totdelivered{$host},$percent2); } printf ("------------------------------------------------------------------------------\n"); printf ($REPORTNUM,"Totals",$countsent,$totsent,$totpctsent,$countdelivered,$totdelivered,$totpctdelivered);