#!/usr/bin/perl
# $Id: logsummary,v 1.2 1997/03/17 21:34:08 grimaldo Rel $
#
# Print various statistics about the Log file
#
# Todo: summarize admin commands
#
# Paul Close, April 1994
# Emilio Grimaldo, June 1996 
#		- Use $LogFile rather than stdin to get data
#		- Print to device $Out
#		- Select output (STDOUT or file) with command line option
#		- Usage: logsummary [LogPath [-m]]
#		- Added parameter parsing loop

$LogFile = "/home/majordom/Log";
$TmpFile = "$ENV{'HOME'}/.majordomo.sum";
$AdminUser = "root";
$MailCmd = "/usr/sbin/sendmail -ep -i $AdminUser";
$Option = "";	# -m

if ($#ARGV > -1) {
    foreach $i (0 .. $#ARGV) {
	if ($ARGV[$i] eq "-m") { $Option = "mail"; }
	else {
	    $LogFile = $ARGV[$i];
	}
    }
}

open(LOGFILE,$LogFile) || die "Couldn't open $LogFile\n";
if ($Option eq "mail") {
    open(TMP,"> $TmpFile") || die "Couldn't open $TmpFile\n";
    print TMP "Subject: Majordomo Log Summary\n\n";
    print TMP "\t\t* * * Majordomo Activity Summary * * *\n\n";
    $Out = "TMP";
    $opt_mail = 1;
}
else {
    $Out = "STDOUT";
}

while (<LOGFILE>) {
    if (($mon,$day,$time,$who,$cmd) =
	/([A-Za-z]+) (\d+) ([\d:]+)\s+.*majordomo\[\d+\]\s+{(.*)} (.*)/)
    {
	@f = split(' ',$cmd);
	$cmd = $f[0];
	$count{$cmd}++;

	# help
	# lists
	# which [address]
	# approve PASSWD ...
	if ($cmd eq "approve" ||
	    $cmd eq "help" ||
	    $cmd eq "lists" ||
	    $cmd eq "which")
	{
	    eval "\$$cmd++";
	}

	# index list
	# info list
	# who list
	elsif ($cmd eq "index" ||
	       $cmd eq "info" ||
	       $cmd eq "who")
	{
	    if ($#f == 1) {
		$lists{$f[1]}++;
		$f[1] =~ s/-//g;
		eval "\$$f[1]{\$cmd}++";
	    } else {
		$bad{$cmd}++;
	    }
	}

	# get list file
	# newinfo list passwd
	elsif ($cmd eq "get" ||
	       $cmd eq "newinfo")
	{
	    if ($#f == 2) {
		$lists{$f[1]}++;
		$f[1] =~ s/-//g;
		eval "\$$f[1]{\$cmd}++";
		if ($cmd eq "get") {
		    $req = &ParseAddrs($who);
		    $long{$req} = $who;
		    $getcount{$req}++;
		}
	    } else {
		$bad{$cmd}++;
	    }
	}

	# subscribe list [address]
	# unsubscribe list [address]
	elsif ($cmd eq "subscribe" ||
	       $cmd eq "unsubscribe")
	{
	    if ($#f >= 1) {
		$lists{$f[1]}++;
		$f[1] =~ s/-//g;
		eval "\$$f[1]{\$cmd}++";
	    } else {
		$bad{$cmd}++;
	    }
	}

	# request cmd list subscribe (for approval)
	elsif ($cmd eq "request") {
	    if ($#f >= 2) {
		$lists{$f[2]}++;
		$f[2] =~ s/-//g;
		eval "\$$f[2]{\$cmd}++";
	    } else {
		$bad{$cmd}++;
	    }
	}

	else {
	    $unrecognized{$cmd}++;
	}
    } else {
	warn "line $. didn't match!\n" if !/^$/;
    }
}
close(LOGFILE);

print "Command summary:\n";
foreach $cmd (sort keys %count) {
    printf "    %-20s %4d\n", $cmd, $count{$cmd};
}

print $Out "Global commands:\n";
printf $Out ("    %-15s %4d\n", "help", $help) if defined($help);
printf $Out ("    %-15s %4d\n", "lists", $lists) if defined($lists);
printf $Out ("    %-15s %4d\n", "which", $which) if defined($which);
print $Out "\n";

#print "Unrecognized commands:\n";
#foreach $cmd (sort keys %unrecognized) {
#    printf "    %-15s %4d\n", $cmd, $unrecognized{$cmd};
#}
#print "\n";

if (defined(%bad)) {
    print $Out "Incomplete commands:\n";
    foreach $cmd (sort keys %bad) {
	printf $Out "    %-15s %4d\n", $cmd, $bad{$cmd};
    }
    print $Out "\n";
}

# skip request and newinfo
print $Out "List               subscr  unsub  index    get   info    who\n";
print $Out "--------------     ------  -----  -----    ---   ----    ---\n";
foreach $list (sort keys %lists) {
    printf $Out "%-18s", substr($list,0,20);
    $list =~ s/-//g;
    eval "\%l = \%$list";
    printf $Out " %6s %6s %6s %6s %6s %6s\n", $l{"subscribe"}, $l{"unsubscribe"},
       $l{"index"}, $l{"get"}, $l{"info"}, $l{"who"};
}
print $Out "\n";

@reqs = sort {$getcount{$b}<=>$getcount{$a};} keys %getcount;
if ($#reqs >= 0) {
    print $Out "Top requestors (get command):\n";
    for ($i=0; $i < 5; $i++) {
	printf $Out "    %5d  %s\n", $getcount{$reqs[$i]}, $long{$reqs[$i]};
	last if ($i == $#reqs);
    }
}

# from majordomo.pl, modified to work on a single address
# $addrs = &ParseAddrs($addr_list)
sub ParseAddrs {
    local($_) = shift;
    1 while s/\([^\(\)]*\)//g; 		# strip comments
    1 while s/"[^"]*"//g;		# strip comments
    1 while s/.*<(.*)>.*/\1/;
    s/^\s+//;
    s/\s+$//;
    $_;
}

if (defined($opt_mail)) {
    close($Out);
    system("cat $TmpFile | $MailCmd");
    unlink($TmpFile);
}
