#!/usr/bin/perl
# RCS: $Header: /home/root/bin/RCS/chklogs,v 1.5 1995/04/30 21:42:27 root Rel $
# AUTHOR: D. Emilio Grimaldo T.
# USAGE: chklogs [option]
# DESCRIPTION:
#          Checks the sizes of system Log files and reports the results.
#       The allowed sizes and lognames are specified in `logf'. These
#       sizes can be in blocks or bytes and the variable `repmode' must
#       also indicate which is chosen. (See ls -s and ls -l)
#   Options:
#	none	Produce summary in stdout
#	-a	Produce summary in stdout. Archive all overgrown logs
#	-m	Mail summary to administrator
#	-M 	Mail summary to administrator. Archive all overgrown logs
#	-c	Only produce a listing of the (archived) logs
#
#   NOTE: mail is sent to root ONLY if one or more logs are overgrown
$logf="/home/root/.log";		# Log Index File
$repmode="byte";			# block or byte
$zipper="/bin/gzip";			# Compress program 
$zipext="gz";				# Extension given by zipper command
$mailout="/tmp/chklogs.txt";		# Temporary file for -m option
$mailer="/usr/sbin/sendmail -ep -i ";
$admin="root";				# Administrator, gets mail
$mailcmd="$mailer $admin"; 		# Command for mail option
$toucher="/usr/bin/touch";		# Recreate overfull log
#
# Archives the log by compressing it and adding a timestamp in
# the filename. No new log is created if it already exists.
#
sub make_archive {
    local($logname) = @_;
    local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst,$tmpname);
    local($d,$i,$m,$n,$uid,$gid);

    ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
    $archive_suffix = sprintf(".%2d%02d%02d",$year,$mon+1,$mday);
    $archivename = $logname . $archive_suffix;
    $tmpname = $archivename . ".$zipext";
    ($d,$i,$m,$n,$uid,$gid) = stat($logname);	# Get ownership data
    if ( ! -e $tmpname) {
	if (rename($logname,$archivename) == 1) {
    	    system("$zipper $archivename");
	    chown $uid,$gid,$tmpname;		# Set correct ownership
	}
	else {
	    warn "Could not rename $logname\n";
	}
    }
    system("$toucher $logname");		# Recreate log
    chown $uid,$gid,$logname;			# Set correct ownership
}
#
# CONSOLE_OUT displays the results of the log checking on the Console
#
sub console_out {
    printf "%-50s %7d   %7d  ",$f_name,$size,$f_size;
    if ( $size > $f_size ) { 
	print $ACTION;		# Has grown too much
	do make_archive($f_name) if defined($opt_archive);
    }
    else {
	print "OK\n";			# Size is ok
    }
}
#
# MAIL_OUT Send mail to root if there is any bigger-than-allowed logfile
#
sub mail_out {
    if ($size > $f_size) {
      	printf TMP "%-50s %7d   %7d %s",$f_name,$size,$f_size,$ACTION;
	do make_archive($f_name) if defined($opt_archive);
	$notify = 1;	# Mail ONLY IF at least one is too big
    }
}
#
# PREPARE_HEADER Sets up the header to be displayed or mailed out
# 		 and set up the option variables
sub prepare_header {
    local($opt) = @_;
    $ACTION = "Clean up\n";
    if ($opt eq "-m") { $opt_mail = 1; }
    elsif ($opt eq "-M") { 
	$opt_mail = 1; 
	$opt_archive = 1; 
	$ACTION ="Archived\n";
    }
    elsif ($opt eq "-a") { $opt_archive = 1; $ACTION = "Archived\n"; }
    elsif ($opt eq "-c") { $opt_check = 1; }

    if (defined($opt_mail)) {
	open(TMP,"> $mailout") || die "CHKLOGS: Could not create mail file";
	print  TMP "Subject: Check Logs Output\n";
	printf TMP "System Logs Index: %s    Sizes: %s\n", $logf, $repmode;
	printf TMP "%-50s Current - Allowed  Action\n","Log Name";
	$notify = 0;
    }
    elsif (!defined($opt_check)) {
	printf "System Logs Index: %s    Sizes: %s\n", $logf, $repmode;
	printf "%-50s Current - Allowed  Action\n","Log Name";
    }
}

sub basename {
    local($fpath) = @_;
    $fpath =~ s/[a-zA-Z0-9_.\/-]*\///;
    return $fpath;
}

sub dirname {
    local($fpath) = @_;
    $fpath =~ s/[a-zA-Z0-9._-]*$//;
    return $fpath;
}

#
# MAIN
#
open(logfile,$logf) || die "Cannot open Log Index\n";
do prepare_header(@ARGV[0]);
while (<logfile>) {
    ($f_name, $f_size) = split(' ');	# Logname & MaximumSize

    ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,
     $mtime,$ctime,$blksize,$blocks) = stat($f_name); # Logfile stats.

#   NOTE: HPUX the blksize is 8192 and blocks is 1/2 the size in ls -s !
#	 HP-UX  blksize: 8192, blocks is half size given by 'ls -s'
#	 Linux  blksize: 1024, blocks is twice size given by 'ls -s'

    if ( $repmode eq "block" ) {
	$size = $blocks / 2;		# See note
    }
    if (defined($opt_check)) {
   	$dname = &dirname($f_name);
	$bname = &basename($f_name);
	chdir($dname);
	print "\nRegistered Log Files in: $dname\n";
	system("/bin/ls $bname*");
    }	
    elsif (defined($opt_mail)) {
        &mail_out;
    }
    else {
        &console_out;
    }
}
close(logfile);
if (defined($opt_mail)) {
    print TMP "\nArchived as <logname>$archive_suffix.$zipext\n" if defined($opt_archive);
    close(TMP);
    if ($notify) {
	system("cat $mailout | $mailcmd");
    }
    unlink($mailout);
}
else {
    print "\nArchived as <logname>$archive_suffix.$zipext\n" if defined($opt_archive);
}
