#!/opt/bin/perl # # rotatelogs - Renames log file to logfilename.n when size threshold # in $tabfile is reached. Also will optionally archive # log file to another location and purge off disk. # # Written by Kevin P. Inscoe [kevin@inscoe.org] (1/25/2000) # # # Library routines # require 'getopts.pl'; # # Global variables # $vers = "1.1.1"; $tab = "/etc/rotatelogstab"; chop($hostname = `/bin/hostname 2>/dev/null` || `/bin/uname -n 2>/dev/null`); $noopts=0; # -h $flaghelp=0; # -v $flagvers=0; # -V $flagverbose=0; # -t $flagtest=0; # # Evaluate command switches # if ($#ARGV == -1) { $noopts = 1; } @cmdflags = @ARGV; &Getopts('hvtV'); if ( defined( $opt_h ) && ( $opt_h )) { $flaghelp = 1; } if ( defined( $opt_v ) && ( $opt_v )) { $flagvers = 1; } if ( defined( $opt_V ) && ( $opt_V )) { $flagverbose = 1; } if ( defined( $opt_t ) && ( $opt_t )) { $flagtest = 1; } # # Decide what to do # #if (($noopts) || ($flaghelp)) { if ($flaghelp) { print "usage: $0 [-h][-v][-tV] [-i]\n"; print " -h Print this message\n"; print " -v Print version and quit\n"; print " -t Test logfiles to be rotated but do not actually perform rotation\n"; print " -V Verbose mode\n"; print "\n"; print "usage note: Use -tV to verify correct settings in the $tab file\n"; exit 0; } if ($flagvers) { print "$0: version $vers\n"; exit 0; } # # announce ourselves # $datetime = localtime(time); print "$0: version $vers starting at $datetime on $hostname\n"; if (!$noopts) { print "$0: with command flags: @cmdflags\n"; } # # validate existence and security of tab file # # does file exist? if ( ! -e $tab ) { die "$0: tab file $tab: file not found\n"; } # can I read it? if ( ! -r $tab ) { die "$0: tab file $tab: can't read file\n"; } # first check security. does this file writable by root only? # if not wail and bail... if ( ! -f $tab ) { print "$0: tab file $tab: bad security: file is not a plain file\n"; } $grpsec = `/bin/ls -l $tab | /bin/cut -c6`; chomp($grpsec); if ($grpsec eq 'w') { die "$0: tab file $tab: bad security: file is group writable\n"; } $wldsec = `/bin/ls -l $tab | /bin/cut -c9`; chomp($wldsec); if ( $wldsec eq 'w' ) { die "$0: tab file $tab: bad security: file is world writable\n"; } # # mainbody # open(TAB, $tab) || die "$0: cannot open tab file $tab $!\n"; while() { $archiveloc=""; @fields=split(/:/, $_); $fields=@fields; @first=split(//,$fields[0]); if($first[0] ne '#') { $create = "n"; $logfile=$fields[0]; $sizetoken=$fields[1]; $retnum=$fields[2]; $hup="n"; $archiveloc=""; $perm=""; $owner=""; $group=""; if ($fields > 3) { $hup=$fields[3]; chomp($hup); $hup=lc$hup; } if ($fields > 4) { $archiveloc=$fields[4]; chomp($archiveloc); } if ($fields > 5) { $perm=$fields[5]; chomp($perm); if ($perm ne '') { $create = "y"; } } if ($fields > 6) { $owner=$fields[6]; chomp($owner); if ($owner ne '') { $create = "y"; } } if ($fields > 7) { $group=$fields[7]; chomp($group); if ($group ne '') { $create = "y"; } } chomp($logfile); chomp($sizetoken); chomp($retnum); if ( $flagverbose == 1 ) { print "---------------------------------------------------------------------\n"; print "logfile=$logfile\n"; print "sizetoken=$sizetoken\n"; print "retnum=$retnum\n"; print "hup=$hup\n"; if ($fields > 3) { print "archiveloc=$archiveloc\n\n"; } } # Make sure file actually exists... if ( -e $logfile) { # Begin checking log files for size compliance... $lsout = `/bin/ls -l $logfile`; $lscomp=$lsout; $lscomp =~ tr/ / /s; @fields=split(/ /, $lscomp); $fs=$fields[4]; chomp($fs); # if ( $flagverbose == 1 ) { print "The filesize of $logfile is $fs bytes.\n"; } # convert size from bytes to kb $size=int $fs/1024; if ( $flagverbose == 1 ) { print "The filesize of $logfile is $size kbytes.\n"; } if ($size >= $sizetoken) { &movefile(); } } else { print "$0: info: cannot access file $logfile at $datetime - continuing...\n"; } } } close(TAB); print "$0: ended at $datetime\n"; # # End of main program # ########## subroutines ################# # # move file routine # sub movefile { # first have we reached max retention? If so archive if called for... if ($archiveloc ne "" ) { $logmax = $logfile . $retnum; if ( $flagverbose == 1 ) { print "\$logmax=$logmax\n"; } if ( -r $logmax ) { &ArchiveLog(); } } # Now begin crop rotation...oh oh circles! $logidx=$retnum; while ($logidx < 100) { $logprior=$logidx-1; $logcur = $logfile . "." . $logprior; $lognew = $logfile . "." . $logidx; if ( $flagverbose == 1 ) { print "\$logprior=$logprior\n"; print "\$logcur=$logcur\n"; print "\$lognew=$lognew\n"; print "\$logidx=$logidx\n"; } if ( -e $logcur ) { if ( $flagtest != 1 ) { print "$0: Rotating $logcur to $lognew at $datetime\n"; `/bin/mv $logcur $lognew`; } else { print "$0: Would have rotated $logcur to $lognew at $datetime\n"; } } if ($logidx > 1) { $logidx--; } else { $logidx = 100; } } $lognew = $logfile . ".0"; if ( $flagtest != 1 ) { print "$0: Rotating $logfile to $lognew at $datetime\n"; `/bin/mv $logfile $lognew`; if ( $create eq "y" ) { `/bin/touch $logfile`; if ( $perm ne '' ) { `/bin/chmod $perm $logfile`; } if ( $owner ne '' ) { `/bin/chown $owner $logfile`; } if ( $group ne '' ) { `/bin/chgrp $group $logfile`; } } } else { print "$0: Would have rotated $logfile to $lognew at $datetime\n"; if ( $create eq "y" ) { print "$0: Would have created empty log $logfile\n"; if ( $perm ne '' ) { print "$0: Would have set permissions on $logfile to $perm\n"; } if ( $owner ne '' ) { print "$0: Would have changed owner on $logfile to $owner\n"; } if ( $group ne '' ) { print "$0: Would have changed group on $logfile to $group\n"; } } } } # # HUP the writing process... # sub hupfile { print "HUP'ing file is not yet supported!\n"; } # # Archive the rotated file beyond $retnum to $archiveloc # sub ArchiveLog { print "File archiving is not supported yet\n"; } ############ end subroutines ##############