#/usr/local/bin/perl
#
#	original by Tom Christiansen <tchrist@convex.com>
#
#	Paul O'Neill
#	Coastal Imaging Lab
#	Oregon State University
#
#	18 jun 90
#	fix various bugs
#	add sorted output
#
# summarize sendmail syslog
#
# flags mean:
#
#	-o	outbound mail only
#	-i	inbound  mail only
#	-t	suppress printing of totals
#	-e 	print strange lines to stderr
#	-m	reduce to local mbox is possible

($program = $0) =~ s%.*/%%;


while ($ARGV[0] =~ /^-/) {
    $ARGV[0] =~ s/^-//; 
    foreach $flag ( split (//,$ARGV[0]) ) {
	if ( 'oitem' !~ /$flag/ ) {
	    printf stderr "unknown flag: %s\n", $flag;
	    die "usage: $program [-oitem] [syslog_file ...]\n";
	} 
	die "$0: '$flag' flag already set\n" if ($flags{$flag}++);
    } 
    shift;
}

if ( !$flags{'o'} && !$flags{'i'} && !$flags{'t'}) {
    $flags{'o'}++;
    $flags{'i'}++;
} 

do hash_passwd() if $flags{'m'};
open(M,"</usr/spool/mqueue/syslog")|| die "couldnt open mail syslog";

while (<M>) {
    if (/: [A-Z][A-Z](\d+): from=(.*), size=(\d+)/) {
#	next unless $flags{'t'} || $flags{'o'};
	($id, $user, $size) = ($1, $2, $3);
#print "$user\n";
	$user =~ s/.*<(.*)>/$1/;		# get rid of <>
#print "$user\n";
	$user =~ tr/A-Z/a-z/;			# canonical lc
#print "$user\n";

	if ($flags{'m'}) {
	    $ouser = $user;
#print "	$user\n";
	    $user = do strip($user);
#print "	 $user\n";
	    $user = $ouser if ! $known{$user};
#rint "	  $user\n";
#print "	  $known{$user}\n";
	}

	$from_user_size{$user} += $size;
	$id_size{$id} = $size;
	$from_user_count{$user}++;
	$total_from++;
    } elsif (/: [A-Z][A-Z](\d+): to=(.*), delay=/) {
#	next unless $flags{'t'} || $flags{'i'};
	$id = $1;
	for (split(/,/, $2)) {
	    s/.*<(.*)>/$1/;
#	    $to = $flags{'m'} ? do strip($_) : $_;
	    $to = $_;
	    if ($flags{'m'}) {
		$oto = $to;
#print "		$to\n";
		$to = do strip($to);
#print "		 $to\n";
		$to = $oto if ! $known{$to};
#print "		  $to\n";
#print "		  $known{$to}\n";
	    }
	    $to =~ tr/A-Z/a-z/;
#	    printf "adding %d bytes to %s from %s\n",
		$id_size{$id},$to,$user; 
	    if (!$to) {
		die "to no one: $_\n";

	    } 
	    $to_user_size{$to} += $id_size{$id};
	    $to_user_count{$to}++;
	    $total_to++;
	} 
    } else {
	study;
	next if /message-id/;
	next if /locked/;
	next if /alias database (auto|)rebuilt/;
	#next if /aliases/;
	next if /rebuilding alias database/;
	print stderr if $flags{'e'};
	$errors++;
    } 
} 

printf stderr "Error lines: %d\n", $errors if $errors && ($flags{'e'}) && !($flags{'t'});


if ($flags{'i'}) {
    printf "To: %d\n", $total_to unless $flags{'t'};;

    @loop = keys(to_user_size);
    foreach $user (sort @loop) {
	printf "%15d message%s %20d bytes %s\n",
	    $to_user_count{$user}, 
	    $to_user_count{$user} != 1 ? "s" : " ",
	    $to_user_size{$user}, 
	    $user;
    } 
}


if ($flags{'o'}) {
    printf "From: %d\n", $total_from unless $flags{'t'};;

    @loop = keys(from_user_size);
    foreach $user (sort @loop) {
	printf "%9d message%s %20d bytes %s\n",
	    $from_user_count{$user}, 
	    $from_user_count{$user} != 1 ? "s" : " ",
	    $from_user_size{$user}, 
	    $user;
    } 
}

sub tosort {
    ($to_user_count{$b} - $to_user_count{$a})* 10000000 + $to_user_size{$b} - $to_user_size{$a};
}

sub fromsort {
    ($from_user_count{$b} - $from_user_count{$a}) * 10000000 + $from_user_size{$b} -$from_user_size{$a};
}

sub strip {
    local($foo) = shift(@_);
#print "$foo\n";
    
    $foo =~ s/@.*//;
    $foo =~ s/.*!//;
    $foo =~ s/\s*\(.*\)//;
    $foo =~ tr/A-Z/a-z/;

    return $foo;
} 

sub hash_passwd {
    chop($yp = `/bin/domainname`) if -x '/bin/domainname';
    $passwd = $yp ? 'ypcat passwd |' : '/etc/passwd';
    open passwd || die "$program: can't open $passwd: $!\n";
    while (<passwd>) {
	/^(\w+):[^:]+:(\d+):.*/;
	($who,$uid) = ($1, $2);
#	$uid = 'zero' if ! $uid;  # kludge for uid 0
	$uid = 'zero' if ($uid == 0) && $who;
#	$uid = 'zero' if defined($uid);
	$known{$who} = $uid;
#print "$who $uid		$known{$who}\n";
    } 
    close passwd;
#print "SPECIEALLLL -- $known{''}\n";
} 
