#!/usr/bin/perl -w

use strict;

$#ARGV == 2 or die "usage: $0 delay expire dir\n";

my ($delay, $expire, $dir) = @ARGV;

my $debug = 1;

chdir($dir) or die "unable to chdir($dir): $!\n";

# for convenience we assume the log is small enough that loading it into memory
# doesn't pose any scalability problems.
my %log;
if (open(LOG, "<grey.log")) {
	rename("grey.log", "grey.log.0") or die "error renaming grey.log: $!\n";
	while (<LOG>) {
		chomp;
		my ($time, $ip) = split;
		$time += $delay;
		if (!defined($log{$ip}) or $log{$ip} > $time) {
			$log{$ip} = $time;
		}
	}
	unlink("grey.log.0");
}

my $oldcdb = open(OLDCDB, "<grey.cdb");

open(CDBMAKE, "|cdbmake grey.cdb grey.tmp") or die "unable to exec cdbmake: $!\n";

# stick in a localhost record always... for creating the initial database
$log{"127.0.0.1"} = 0;

if ($oldcdb) {
	unless (open(CDBDUMP, "-|")) {
		open(STDIN, "<&", \*OLDCDB) or die "unable to reopen stdin: $!\n";
		exec "cdbdump" or die "unable to exec cdbdump: $!\n";
	}
	my $now = time;
	while (<CDBDUMP>) {
		chomp;
		last if /^$/;
		my ($ip, $stamp) = /^\+\d+,\d+:([^-]+)->(\d+)/ or die "unable to parse: $_\n";
		if ($now >= $stamp and defined($log{$ip})) {
			$stamp = $now;
		}
		delete $log{$ip};
		if ($stamp >= $now - $expire) {
			printf CDBMAKE "+%u,%u:%s->%s\n", length($ip), length($stamp), $ip, $stamp;
		}
	}
	close(CDBDUMP);
}

foreach (keys %log) {
	printf CDBMAKE "+%u,%u:%s->%s\n", length($_), length($log{$_}), $_, $log{$_};
}

print CDBMAKE "\n";

close(CDBMAKE);
