#!/usr/bin/perl
#
# Converts hash databases (used prior to v1.2 of TAS) to btree sorted databases.
#
# Arguments:
# -v	outputs progress information to STDERR
# <db-file>
#

use strict;
use DB_File;
use Socket;

sub compile_host
{
	my $host = shift;

	if( $host =~ /^\d+\.\d+\.\d+\.\d+$/ ){
		return "a" . inet_aton( $host );
	}else{
		my @name = split /\./, $host;
		my $reversed = $name[ $#name ];
		my $i;

		for( $i = $#name - 1; $i >= 0; $i-- ){
			$reversed .= ".";
			$reversed .= $name[ $i ];
		}
		return "d$reversed";
	}
}


my $opt_v;
my $lines;
my %src;
my %dst_from;
my %dst_to;
my $src_file;		# old-format db file
my( $dst_from_file, $dst_to_file );	# new format db files
my( $key, $value );
my $type;		# traffic type
my( $from, $to, $tag );	# old-format key fields
my( $from_compiled, $to_compiled, $agent_host, $proto, $status );	# new-format key fields

if( $ARGV[ 0 ] eq '-v' ){
	$opt_v = 1;
	shift @ARGV;
}
die "Bad arguments!" unless( $ARGV[ 0 ] );

$src_file = $ARGV[ 0 ];
die "Wrong db file name!" unless( $src_file =~ /^(ip|squid|sendmail|mailgate)\.([^\.]+)\.db$/ );

$type = $1;
$dst_from_file = "$type.$2.from.db";
$dst_to_file = "$type.$2.to.db";

print STDERR "Number of records processed:\n" if $opt_v;

tie( %src, 'DB_File', $src_file, O_RDONLY ) || die "Can\'t tie $src_file database: $!";
tie( %dst_from, 'DB_File', $dst_from_file, O_RDWR|O_CREAT, 0644, $DB_BTREE ) || die "Can\'t tie $dst_from_file database: $!";
tie( %dst_to, 'DB_File', $dst_to_file, O_RDWR|O_CREAT, 0644, $DB_BTREE ) || die "Can\'t tie $dst_to_file database: $!";

$lines = 0;
while( ( $key, $value ) = each %src ){

	( $from, $to, $tag ) = split ' ', $key;
	$from_compiled = compile_host( $from );
	$to_compiled = compile_host( $to );
	if( $type eq 'ip' ){
		$agent_host = $tag;
		$proto = 'ip';
		$status = '*';
	}elsif( $type eq 'squid' ){
		$agent_host = '*';
		$proto = '*';
		$status = "TCP_$tag";
	}elsif( $type eq 'sendmail' ){
		$agent_host = $tag;
		$proto = 'smtp';
		$status = '*';
	}else{	# mailgate
		$agent_host = '*';
		$proto = $tag;
		$status = '*';
	}
	
	$dst_from{"$from_compiled $to_compiled $agent_host $proto $status"} = $value;
	$dst_to{"$to_compiled $from_compiled $agent_host $proto $status"} = $value;

	if ($opt_v) {
		$lines ++;
		print STDERR "$lines\r" if $lines%100 == 0;
	}
}
print STDERR "\nComplete.\n" if $opt_v;

untie %src;
untie %dst_from;
untie %dst_to;

