#!/usr/bin/perl -w
# rotates logfiles in the manner of syslog
# Par Leijonhufvud, 2000-06-27
#
# Rewritten 2000-07-05 PKL
#
# Added gzip, strict, and debug, and some minor work 2001-11-09 PKG
# 
# If $EMAIL is defined no error is given for STDOUT for most errors;
# it is sent to $EMAIL instead.  2002-01-14 PKG

use strict; 
use Sys::Hostname;


my $NO;
my $PATH;
my $FILE;
my $EMAIL;
my $KEEP;
my $CREATE;	# defaults to not "creating" an empty
my $i;
my $j;
my $REPORT;
my $COMPRESS;
my $DEBUG;
my $GZIP 	= "/usr/bin/gzip";	
my $LS 		= "/bin/ls -goia";
my $MAILER	= "/bin/mail";
my $HOSTNAME	=  hostname();


# fix line feed in hostname
chomp($HOSTNAME);


###
### command line options
###

use Getopt::Long;

&GetOptions(
	"no=i"     => \$NO,	    # number of generations saved
	"path=s"   => \$PATH,	    # name of dir
	"file=s"   => \$FILE,	    # name of file
	"email:s"  => \$EMAIL,	    # email
	"keep"     => \$KEEP,	    # keep the original
	"create"   => \$CREATE,	    # if we shall create an empty "original" with cp /dev/null...
  "gzip"	   => \$COMPRESS,   # compress with gzip
  "debug"    => \$DEBUG,	    # debug mode
);

# make sure that everything that is needed is defined
if (! $NO || ! $PATH || ! $FILE ) {
	# send the error message as an email if $EMAIl is defined
        if ($EMAIL) {
		open MAIL, "| $MAILER $EMAIL";
		
		print MAIL "Subject: Error in rotate.pl job.\n\n";
	        print MAIL "Syntax: rotate --no <generations> --path <path> --file <file> [--email <email> --create --gzip --keep --debug]\n";
                exit;
        }
        else {
	        die "Syntax: rotate --no <generations> --path <path> --file <file> [--email <email> --create --gzip --keep --debug]\n";
        }
} 

# DEBUG mode; first some datæ
print "*** Running i debug mode\n" if $DEBUG;
print "*\t \$HOSTNAME is $HOSTNAME\n" if $DEBUG;
print "*\t \$NO is $NO\n" if $DEBUG;
print "*\t \$PATH is $PATH\n" if $DEBUG;
print "*\t \$FILE is $FILE\n" if $DEBUG;
if ($EMAIL && $DEBUG) {
	print "*\t \$EMAIL is $EMAIL\n";
}

# Checking for gzip
print "*	 Looking for gzip ($GZIP).\n" if $DEBUG;
if (-e "/bin/gzip" && -x "/bin/gzip" && $COMPRESS) {
	$GZIP 	= "/bin/gzip";
	print "*\t Using $GZIP as gzip.\n" if $DEBUG;
} elsif (-e "/usr/bin/gzip" && -x "/usr/bin/gzip" && $COMPRESS) {
	$GZIP = "/usr/bin/gzip";
	print "*\t Using $GZIP as gzip.\n" if $DEBUG;
} elsif (-e "/usr/local/bin/gzip" && -x "/usr/local/bin/gzip" && $COMPRESS) {
	$GZIP = "/usr/local/bin/gzip";
	print "*\t Using $GZIP as gzip.\n" if $DEBUG;
} elsif (-e "$GZIP" && -x "$GZIP" && $COMPRESS) {
	print "*\t Using $GZIP as gzip.\n" if $DEBUG;
} elsif (! -e "/bin/gzip" && ! -e "/usr/local/bin/gzip" && $COMPRESS) {

	# send the error message as an email if $EMAIl is defined
        if ($EMAIL) {
		open MAIL, "| $MAILER $EMAIL";
		
		print MAIL "Subject: Error in rotate.pl job.\n\n";
		print MAIL "I was told to compress $PATH/$FILE.0, but could not find gzip!\n";
                exit;
        }
        else {
		die "I was told to compress $PATH/$FILE.0, but could not find gzip!\n";
        }
}


if ($KEEP && $DEBUG) {
	print "*\t \$KEEP is $KEEP\n";
}

if ($CREATE && $DEBUG) {
	print "*\t \$CREATE is $CREATE\n";
}

if ($COMPRESS && $DEBUG) {
	print "*\t \$COMPRESS is $COMPRESS\n";
}

print "\n" if $DEBUG;


# title of report
my $REPORT_TITLE = "Rotation";

# verify that we can find the file
if (! -e "$PATH/$FILE" || ! -r  "$PATH/$FILE" || ! -w  "$PATH/$FILE" || ! -d "$PATH" || ! -w  "$PATH") {
	# send the error message as an email if $EMAIl is defined
        if ($EMAIL) {
		open MAIL, "| $MAILER $EMAIL";
		
                print MAIL "From: $0\@$HOSTNAME \n";
		print MAIL "Subject: Error in rotate.pl job.\n\n";
		print MAIL "I did not find the file or it's path (or wrong write permission) \n" if $DEBUG;
		print MAIL "File $PATH/$FILE not found, readable or writable, \n";
                print MAIL "or directory is not writable!\n\n";
		if ($PATH)      {print MAIL "*\t \$PATH is $PATH\n" ;}
		if ($FILE)      {print MAIL "*\t \$FILE is $FILE\n" ;}
                exit;
        }
        else {
	        print "I did not find the file or it's path (or wrong write permission) \n" if $DEBUG;
	        die "File $PATH/$FILE not found, readable or writable, or directory is not writable!\n";
        }
}

print "\n" if $DEBUG;
print "* Starting renaming by number (working up to number $NO - 1)\n" if $DEBUG;

# rename by the numbers


for ($i=$NO - 2; $i >= 0; $i--) {
	print "*\t Working with number $i... " if $DEBUG;
	if (-e  "$PATH/$FILE.$i" ) {
		print "file \"$PATH/$FILE.$i\" exists\n" if $DEBUG;
		$j = $i + 1;	
		rename "$PATH/$FILE.$i", "$PATH/$FILE.$j";
	} elsif (-e  "$PATH/$FILE.gz.$i") {
		print "file \"$PATH/$FILE.gz.$i\" exists. \n" if $DEBUG;
		$j = $i + 1;	
		rename "$PATH/$FILE.gz.$i", "$PATH/$FILE.gz.$j";
	} else {
		print "neither $PATH/$FILE.$i nor $PATH/$FILE.gz.$i exists.\n" if $DEBUG;
	}
}

print "* Done with the numbers\n" if $DEBUG;

# finally rename the current file to the ".0" suffix
if (-e  "$PATH/$FILE") {
	print "\n" if $DEBUG;
	print "* The file \"$PATH/$FILE\" exists.\n" if $DEBUG;
	if (! $COMPRESS) {
		print "* We don't want to compress it.\n" if $DEBUG;
		`/bin/cp -p $PATH/$FILE $PATH/$FILE.0`;
	}elsif ($COMPRESS) {
		print "* We do want to compress it.\n" if $DEBUG;
		`/bin/cp -p $PATH/$FILE $PATH/$FILE.0`;
		`$GZIP $PATH/$FILE.0`;
		rename "$PATH/$FILE.0.gz", "$PATH/$FILE.gz.0";
	} else {
	        if ($EMAIL) {
			open MAIL, "| $MAILER $EMAIL";
			
                        print MAIL "From: $0\@$HOSTNAME \n";
			print MAIL "Subject: Error in rotate.pl job.\n\n";
			print MAIL "I'm having trouble deciding if I shall compress the file or not\n";
	                exit;
                } else {
			die "I'm having trouble deciding if I shall compress the file or not\n";
                }
	}

	if ($CREATE && ! $KEEP ) {
		print "* We want to create an empty by copying /dev/null\n" if $DEBUG;
		`/bin/cp /dev/null $PATH/$FILE`;
		#unlink "$PATH/$FILE";
	} elsif ($KEEP) {
		print "* We just want to keep the original\n" if $DEBUG;
		`/bin/cp -p $PATH/$FILE $PATH/$FILE.0`
	} else {
		print "* We just want the original removed.\n" if $DEBUG;
		#`/bin/cp /dev/null $PATH/$FILE`;
		unlink "$PATH/$FILE";
	}
		
}


# generate a report, if an email address was defined on the command line
if ($EMAIL) {
	print "\n* Email an report to $EMAIL\n" if $DEBUG;
	print "*\t ls is $LS\n" if $DEBUG;
	print "*\t mailer is $MAILER\n" if $DEBUG;
	$REPORT = `$LS $PATH/$FILE*`;
	
	# send the results as an email
	open MAIL, "| $MAILER $EMAIL";
	
        print MAIL "From: $0\@$HOSTNAME \n";
	print MAIL "Subject: $REPORT_TITLE ($HOSTNAME:$PATH/$FILE)\n\n";
	print MAIL "In directory $PATH ($LS): \n\n";
	print MAIL "$REPORT\n";
	close MAIL;
	print "* Email sent\n" if $DEBUG;
}

