// Rewrite Apache logs that have incorrect dates
use strict;
use warnings;
our ($VERSION) = '$Revision$' =~ m{ \$Revision: \s+ (\S+) }xms;
use HTTP::Date;
my @DAYS = qw(Sun Mon Tue Wed Thu Fri Sat);
my @MONTHS = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
my $wrong_datetime = shift @ARGV;
my $right_datetime = shift @ARGV;
my ($timezone) = $right_datetime =~ m/ ([+-]\d\d\d\d)\z/xms;
my $seconds_diff = str2time($right_datetime) - str2time($wrong_datetime);
foreach my $file (@ARGV) {
print "Rewriting $file\n";
open my $IN, '<', $file
or die "Can't open $file: $!\n";
open my $OUT, '>', "$file.rewritten"
or die "Can't write to $file.rewritten: $!\n";
while (<$IN>) {
if (m{
\A
(.+\s+)
\[
(
\d\d/\w\w\w/\d\d\d\d
:\d\d:\d\d:\d\d
\s
[\+\-]\d\d\d\d
)
\]
(\s+.+)
\z
}xms) {
print {$OUT}
$1, q{[},
rewrite_access_datetime($2, $seconds_diff, $timezone),
q{]}, $3;
}
elsif (m{
\A
\[
(
\w\w\w \s \w\w\w \s \d\d \s
\d\d:\d\d:\d\d \s
\d\d\d\d
)
\]
(\s+.+)
\z
}xms) {
print {$OUT}
q{[},
rewrite_error_datetime($1, $seconds_diff),
q{]}, $2;
}
else {
print {$OUT} $_;
}
}
}
sub rewrite_access_datetime {
my ($datetime, $seconds_diff, $timezone) = @_;
my ($sign, $hours, $minutes) = $timezone =~ m/\A([+-])(\d\d)(\d\d)\z/xms;
my $seconds_offset = ($hours * 60 + $minutes) * 60;
$datetime = str2time($datetime) + $seconds_diff;
if ($sign eq q{+}) {
$datetime = $datetime + $seconds_offset;
}
elsif ($sign eq q{-}) {
$datetime = $datetime - $seconds_offset;
}
my ($sec, $min, $hour, $mday, $mon, $year) = gmtime $datetime;
return sprintf '%02d/%s/%04d:%02d:%02d:%02d %s',
$mday, $MONTHS[$mon], $year + 1900, $hour, $min, $sec, $timezone;
}
sub rewrite_error_datetime {
my ($datetime, $seconds_diff) = @_;
$datetime = str2time($datetime) + $seconds_diff;
my ($sec, $min, $hour, $mday, $mon, $year, $wday) = gmtime $datetime;
return sprintf '%s %s %02d %02d:%02d:%02d %04d',
$DAYS[$wday], $MONTHS[$mon], $mday, $hour, $min, $sec, $year + 1900;
}