#!/usr/bin/perl -w
#
# copyright 2000 by Gottfried Szing e9625460@stud3.tuwien.ac.at
#
# version 0.01
# 
# Author: Gottfried Szing e9625460@stud3.tuwien.ac.at
# Maintainer: Gottfried Szing e9625460@stud3.tuwien.ac.at

#
# best vieved under vi with tabstop=4

$| = 1;

# =============== MAIN BEGIN ==========================
use strict;
use Getopt::Long;
use Time::ParseDate;

# check args
if (@ARGV == 0)
{
	print <<EOF;

Usage: 
    $0 <start date/time> [<stop date/time>]

Only prints the lines in the log file which are after the
<start date/dime> if only one parameter is supplied or
prints the lines between <start> and <stop>.

As date/time strings everything what the Perl module
Time::ParseDate understand could be used. So for a complete
list i refere to Time::ParseDate(3).

Examples:

- everything since yesterday 00:00
  \$ cat access.log | logfilter "yesterday 00:00" > new.log

- last two weeks 
  \$ cat access.log | logfilter "-2 weeks" > new.log

- only log from yesterday
  \$ cat access.log | logfilter "yesterday 00:00" "yesterday 23:59:59" > new.log

EOF
exit();
}

my %monthtab = (    "Jan" => "1",
					"Feb" => "2",
					"Mar" => "3",
					"Apr" => "4",
					"May" => "5",
					"Jun" => "6",
					"Jul" => "7",
					"Aug" => "8",
					"Sep" => "9",
					"Oct" => "10",
					"Nov" => "11",
					"Dec" => "12" );

my $from	= 0;
my $to		= 0;
my $start	= "";
my $stop	= "";

if (@ARGV == 1)
{
	# relative date
	$start 	= $ARGV[0];
	$stop	= "tomorrow 00:00";
}
else 
{
	$start = $ARGV[0];
	$stop  = $ARGV[1];
}

$from = &parsedate($start);
$to   = &parsedate($stop);

print STDERR <<EOF;

From:     $start    ($from)
To:       $stop     ($to)

EOF

my ($line, $day, $month, $year, $timestamp, $newdate, $secs);

INPUT: while (defined($line = <STDIN>))
{
	chomp($line);

	if ( ($line =~ m!\[(\d+)/(\w+)/(\d+):([\d:]+) ([+-]\d+)\]!) )
	{
		($day, $month, $year, $timestamp) = ($1, $2, $3, $4);
		$month 		= $monthtab{$month};				
		$newdate    = "$year-$month-$day $timestamp";

		$secs = &parsedate($newdate);

		next INPUT if ($secs < $from);
		next INPUT if ($secs > $to);

		print "$line\n";
	}
	else
	{
		print STDERR "Wrong date format: $line\n";
	}
}
