#!/usr/bin/perl
# dspam_logrotate - Removed old entries from DSPAM log files.
# Steve Pellegrin <spellegrin@convoglio.com>
#
# Patched for working on dspam installation with thousends of users.
# Norman Maurer <nm@byteaction.de>
#
# Usage:
# dspam_logrotate -v -a days logfile ...
# -v: Print verbose output
# -a days: All log entries older than 'days' will be removed.
# -l logfile: A list of one or more files to process.
# -d dspamdir: The home directory of dspam.
###########################################################
#
# Print usage info
#
sub usage {
print "Usage: " . $0 . " -a age [-v] -l logfiles\n";
print "or\n";
print "Usage: " . $0 . " -a age [-v] -d /var/dspam\n";
}
###########################################################
###########################################################
#
# "Rotate" one log file
#
sub rotate {
# Give names to input args.
my($filename);
my($cutoffTimestamp);
my($printStats);
($filename, $cutoffTimestamp, $printStats) = @_;
# Generate names for the temporary files.
my($tempInputFile) = $filename . ".in";
my($tempOutputFile) = $filename . ".out";
# Rename the log file to the temporary input file name.
rename $filename, $tempInputFile;
# Open the temporary input and output files.
open INFILE, "< $tempInputFile"
or die "Cannot open input file: $tempInputFile\n$!";
open OUTFILE, "> $tempOutputFile"
or die "Cannot open output file: $tempOutputFile\n$!";
# Read the input file and copy eligible records to the output.
# Count the number of delete records in case printStats is true.
my($linesDeleted) = 0;
while (defined($thisLine = <INFILE>)) {
# Get this line's timestamp.
my($lineTimestamp) = substr($thisLine, 0, index($thisLine, "\t"));
# Write lines with newer timestamps to the output file.
if ($lineTimestamp >= $cutoffTimestamp) {
print OUTFILE $thisLine;
} else {
$linesDeleted++;
}
}
close INFILE;
# It is possible that records have been written to the log file while
# we have been processing the temporary files. If so, append them to
# our temporary output file.
if (-e $filename) {
open INFILE, "< $filename"
or die "Cannot open log file: $filename\n$!";
while (defined($thisLine = <INFILE>)) {
print OUTFILE $thisLine;
}
close INFILE;
}
# Rename our temporary output file to the original log file name.
close OUTFILE;
rename $tempOutputFile, $filename;
# Remove our temporary input file.
unlink $tempInputFile;
# Print statistics, if desired.
if ($printStats != 0) {
print "Deleted $linesDeleted lines from $filename \n";
}
}
###########################################################
###########################################################
#
# Mainline
#
###########################################################
# Extract the command line arguments
# -a days: All log entries older than 'days' will be removed.
# -v: Print verbose output
# logfile: A list of one or more files to process.
#
my($ageDays) = undef;
my($logfiles);
my($help) = 0;
my($verbose) = 0;
while ($arg = shift(@ARGV)) {
if ($arg eq "-a") {
$ageDays = shift(@ARGV);
} elsif ($arg eq "-v") {
$verbose = 1;
} elsif ($arg eq "-l") {
@logfiles = @ARGV;
} elsif ($arg eq "-d") {
my $dspamdir = shift(@ARGV);
@logfiles = split(/\n/, `find $dspamdir -name \"*.log\"`);
} elsif ($arg eq "-h") {
$help = 1;
}
}
#
# Quit now if the command line looks screwy.
#
if (!defined($ageDays) || (scalar @logfiles == 0) || $help == 1) {
usage();
exit(-1);
}
#
# Determine the earliest timestamp allowed to stay in the file.
#
my($minimumTimestamp) = (time - ($ageDays * 60 * 60 * 24));
#
# Rotate each logfile specified on the command line.
#
foreach $logfile (@logfiles) {
rotate($logfile, $minimumTimestamp, $verbose);
}
syntax highlighted by Code2HTML, v. 0.9.1