#!/usr/local/bin/perl
#--------------------------------- Logger.pl ----------------------------------
#
#  Perl script which supports:
#    Logfile rotation up to a maximum number of days to be kept....
#    A "guestbook" which tracks sites which hit on you, and how many times
#      they've hit things.
#    A primitive usage database which shows _what's_ getting hit
#    A mailed report of "newbies" sent to the system administrator (ie.
#      new sites which have hit you since the last report).
#
#  Making it work:
#    Change the parms below to something you find aesthetically pleasing.
#    Put it up as a cron job to be run once per day.
#
#  General disclaimer of competence:
#    I'm new at this (and I bet it shows), so send suggestions for 
#    improvements to:   tom@law.mail.cornell.edu
#
#   "A Perl script is correct if it's halfway readable and gets
#    the job done before your boss fires you"
#                             -- Larry Wall
#  
#----------------------------------------------------------------------------

#--------------------------- Site-configured stuff --------------------------
#  These could probably all be done from the command line, but so what.
# 
#  Set this to the full path and name of your gopher log file as you've
#  set it in the -l parameter for gopherd:

$logbase="/home/mudhoney/GopherLog70";

#  This script will generate files gopherlog.1 .. gopherlog.nn depending
#  on how many days you decide to keep, as in:

$keepfor=7;

#  Setting $keepfor to "" permits all the logging/reporting to take place
#  but zaps the logfile.
# 
#  Next, pick a path and name for your guestbook (the file which records
#  sites which have hit on you). Leave it empty ("") if you don't want a
#  guestbook.

$guestbook="/home/mudhoney/gopherlogs/gopher_guests";

#  Next, pick a path and name for the usage file (the one which tracks
#  which of your local choices gets hit on, and how much).

$usage="/home/mudhoney/gopherlogs/usage_log";

#  Finally, pick a person to receive mailed reports on new sites which hit
#  you (or any other reports you might decide to have this thing generate).
#  You can put more than one person here, separate them with semicolons
#  if you want more than one.

$mail_to="lindner";

#  OK, down to business.
#  Do file rotation; this has the useful effect that we won't be tallying
#  from something gopher is trying to write to.

$i = $keepfor;
LOGFILE:
while ($i>0)
	{
	$i--;
	next LOGFILE unless -e $logbase.".".$i;
	system("mv ".$logbase.".".$i." ".$logbase.".".($i+1));
	}
system("cp ".$logbase." ".$logbase.".1");
unlink $logbase;

#  Do the guestbook and usage.
if ($guestbook || $usage)
	{
	open(INFILE,"< $logbase.1");
	if ($guestbook && -T $guestbook)
		{
		open(GUESTBOOK, "< $guestbook") || die "Can't get the guestbook file.";
		#load up the array
		while (<GUESTBOOK>)
			{
			chop($line=$_);
			($site, $hits)=split(':',$line);
			if (!defined($hits) || ($hits eq ""))
				{
				$hits = 1;
				}
			$guests{$site}=$hits;
			}
		close GUESTBOOK;
		}
	if ($usage && -T $usage)
		{
		open(USAGE, "< $usage") || die "Can't get the usage file.";
		#load up the array
		while (<USAGE>)
			{
			chop($line=$_);
			#The usage line may have more than one colon, 
			#as with mail files from the disctool script,
			# in which case we want the last field.

			@flds=split(':',$line);

			#the last field is always going to be the number of
			#of hits, everything else should get joined into
			#the key.
			$action=join(':',@flds[0 .. $#flds-1]);
			$activities{$action}=$flds[$#flds];
			}
		close USAGE;
		}
	LINE:
	while(<INFILE>)
		{
		chop($line=$_);
		if(!grep(/Root Connection| \//,$line))
			{
			next LINE; #skip anything but hits on server
			}
		($prefix, $what)=split(/\s+:\s+/,$line);
		($dow, $mon, $day, $tm, $yr, $seq, $guest)=split(' ', $prefix);

		#don't think my clever and succinct code of the original
		#version works very well.  Hafta go with something less
		#quote elegant unquote.  How elegant is it if it doesn't
		#work?

		if ($usage)  #see if anybody's done this before
			{
			if (defined $activities{$what})
				{
				$activities{$what}++;
				}
			else	
				{
				$activities{$what}=1;
				$newactivs{$what}=1;
				}
			}
		if ($guestbook)
			{
			if (defined $guests{$guest})
				{
				$guests{$guest}++;
				}
			else
				{
				$guests{$guest}=1;
				$newguests{$guest}=1;
				}
			
			}
		}
	close INFILE;
	}

#write out.
if ($usage)
	{
	open(USAGE, "> $usage") || die "Can't open usage file for output";
	foreach $key (sort(keys %activities))
		{
		print USAGE $key,":",$activities{$key},"\n";
		}
	close USAGE;
	}
if ($guestbook)
	{
	open(GUESTBOOK, "> $guestbook") || die "Can't open guestbook file for output";
	foreach $key (sort(keys %guests))
		{
		print GUESTBOOK $key, ":", $guests{$key},"\n";
		}
	close GUESTBOOK;
	}

#do the mail thing 
if ($mail_to)
	{
	# make a temp file
	open(MAILIT, ">zzz_logtmp") || die "Can't open mail file";
	print MAILIT "Report from Gopher log manager.\n\n";
	print MAILIT "The following new activities were logged:\n\n";
	foreach $key (sort(keys %newactivs))
		{
		print MAILIT "\t",$key,"\n";
		}

	print MAILIT "\n\n The following new guests were logged:\n\n";
	foreach $key (sort(keys %newguests))
		{
		print MAILIT "\t",$key, "\n";
		}
	close MAILIT;
	@recipients=split(';',$mail_to);
	foreach $rcpt(@recipients)
		{
		system "mail -s DailyGopherAbstract ".$rcpt." < zzz_logtmp";
		}
	unlink "zzz_logtmp";
	}

#cleanup if needed.
unlink $logbase.".1" unless $keepfor;

