#! /usr/bin/perl -w
use strict;
# $Id: logrotate.perl,v 1.6 2002/01/28 14:43:53 khera Exp $
use constant USAGE => "usage:logrotate [-z] [-p PID] [-s SIG] -r N file...\n";
use IO::File;
use Getopt::Std;
my %opt = ();
getopts('zp:s:r:',\%opt);
scalar(@ARGV) or die USAGE; # are there files specified?
die USAGE unless $opt{'r'};
# rotate the named log file and archive $howmany old versions. eg,
# rotate("foo",3);
# will move foo -> foo.0 -> foo.1 -> foo.2 -> foo.3
# and remove old foo.3, then create empty foo.
sub rotate ($$) {
my($file,$howmany) = @_;
my($cur);
return if ($howmany < 0);
unlink ("$file.$howmany","$file.$howmany.gz"); # remove topmost one.
for ($cur = $howmany; $cur > 0; $cur--) {
my $prev = $cur - 1;
rename("$file.$prev","$file.$cur") if (-f "$file.$prev");
rename("$file.$prev.gz","$file.$cur.gz") if (-f "$file.$prev.gz");
}
rename("$file","$file.0"); # move original one
# create the new one!
my $fh = new IO::File $file, O_WRONLY|O_CREAT, 0644;
$fh->close();
}
# first rotate the files
foreach my $file (@ARGV) {
rotate ($file,$opt{'r'});
}
# now send the signal, if necessary. Default signal is HUP.
if ($opt{'p'}) {
my $sig = $opt{'s'} || 'HUP';
unless (kill $sig, $opt{'p'}) {
warn "Failed to send $sig to $opt{'p'}\n";
warn " -- disabling compression of file\n" if (delete $opt{'z'});
}
}
# and finally compress the newly rotated files, if requested
if ($opt{'z'}) {
foreach my $file (@ARGV) {
system "gzip $file.0";
}
}
exit(0);
__END__
=pod
=head1 NAME
logrotate - rotate and compress log files
usage: C<logrotate [-z] [-p PID] [-s SIG] -r N file...>
=head1 README
Rotate log files and optionally send a signal (default is HUP) to the
specified process ID, then optionally compress the newly rotated log
file(s). As many different log files may be specified on the command line
as desired.
Command line options:
=over 4
=item -z
This option causes the newly rotated log file to be gzip compressed.
=item -p PID
Sends a signal, default C<HUP>, to the C<PID> specified after the
rotation is done, but before optional compression is started.
=item -s SIG
Changes the signal sent under the C<-p> option to the one named (either
symbolic or numeric).
=item -r N
Keep C<N> old log files named as F<file.0>, F<file.1>, ..., F<file.N>.
This flag is mandatory.
=back
=head1 PREREQUISITES
Requires C<IO::File> and C<Getopt::Std>. Also required F<gzip> if you
want to compress your files. I suppose it would make sense to use a
Perl gzip module to do the compression, but they were not available when
I first wrote this program.
=head1 SCRIPT CATEGORIES
UNIX/System_administration
=head1 BUGS
Very lazy about error checking of renames and file creations.
=head1 AUTHOR
Vivek Khera <
[email protected]>
Copyright 1999-2001 Vivek Khera. This program is distributed under the
same terms as Perl itself. Please refer to the Perl license for
details.
=cut