#!/usr/bin/perl

# binkd log analizer     ver 0.1   11 Jan 1999
# Copyright (c) Pavel Gulchouck <gul@lucky.net>  2:463/68
# freeware

while (<>)
{
	chomp();
	if (s/^. [0-9][0-9] [A-Za-z]+ [0-9:]+ \[([0-9]+)\]\s+//)
	{
		$pid = $1;
	}
	else
	{
		next;
	}
	if (/^call to ([0-9:\/\.]+)\@/)
	{
		$pid{$pid} = "out $1";
		next;
	}
	if (/^addr: ([0-9:\/\.]+)\@\S+$/)
	{
		$pid{$pid} = "in $1" unless defined($pid{$pid});
		next;
	}
	next unless defined($pid{$pid});
	($addr) = $pid{$pid} =~ / ([0-9:\/\.]+)/;
	$addr{$addr}=1;
	if (/^getaddrinfo failed:/)
	{
		$failedout{$addr}++;
		delete($pid{$pid});
		next;
	}
	if (/^unable to connect:/)
	{
		$failedout{$addr}++;
		delete($pid{$pid});
		next;
	}
	if (/^connection to (.*) failed:/)
	{
		$failedout{$addr}++;
		delete($pid{$pid});
		next;
	}
	if (/^rcvd: \S+ \(([0-9]+), ([0-9\.]+) CPS,/)
	{
		$rcvfiles{$addr}++;
		$rcvbytes{$addr}+=$1;
		$time{$addr}+=$1/$2 unless ($2 == 0);
		next;
	}
	if (/^sent: \S+ \(([0-9]+), ([0-9\.]+) CPS,/)
	{
		$sentfiles{$addr}++;
		$sentbytes{$addr}+=$1;
		$time{$addr}+=$1/$2 unless ($2 == 0);
		next;
	}
	if (/^done \((from|to) \S+, (OK|failed),/)
	{
		if ($1 eq "from")
		{
			if ($2 eq "OK")
			{
				$okin{$addr}++;
			}
			else
			{
				$failedin{$addr}++;
			}
		}
		else
		{
			if ($2 eq "OK")
			{
				$okout{$addr}++;
			}
			else
			{
				$failedout{$addr}++;
			}
		}
		delete ($pid{$pid});
		next;
	}
}

print <<EOF;
  Addr           In    In   Out    Out    Bytes     Bytes Files Files    Avg
                 OK   Fail   OK   Fail     sent      recv  sent  recv    CPS
==============================================================================
EOF

$format = "%-13s %5d %5d %5d %5d %9d %9d %5d %5d %8.2f\n";

foreach $addr (sort cmpaddr keys %addr)
{
	printf $format,
	  $addr, $okin{$addr}, $failedin{$addr},
	  $okout{$addr}, $failedout{$addr},
	  $sentbytes{$addr}, $rcvbytes{$addr},
	  $sentfiles{$addr}, $rcvfiles{$addr},
	  $time{$addr} ? ($sentbytes{$addr}+$rcvbytes{$addr})/$time{$addr} : 0;
	$totokin += $okin{$addr};
	$totfailedin += $failedin{$addr};
	$totokout += $okout{$addr};
	$totfailedout += $failedout{$addr};
	$totsentbytes += $sentbytes{$addr};
	$totrcvbytes += $rcvbytes{$addr};
	$totsentfiles += $sentfiles{$addr};
	$totrcvfiles += $rcvfiles{$addr};
	$tottime += $time{$addr};
}
print <<EOF;
==============================================================================
EOF
printf $format,
  "  Total", $totokin, $totfailedin, $totokout, $totfailedout,
  $totsentbytes, $totrcvbytes, $totsentfiles, $totrcvfiles,
  $tottime ? ($totsentbytes+$totrcvbytes)/$tottime : 0;

sub cmpaddr
{
	my ($zonea, $neta, $nodea, $pointa) = split (/[:\/\.]/, $a);
	my ($zoneb, $netb, $nodeb, $pointb) = split (/[:\/\.]/, $b);
	return ($zonea <=> $zoneb) || ($neta  <=> $netb) ||
               ($nodea <=> $nodeb) || ($pointa<=> $pointb);
}
