#!/usr/bin/perl

#
#	This script is intented to be used from snmpd. 
#
#	It parse the cpop stats file to build a temporary cache file. That
#	cache file stay valid for 290 seconds in order to give the same
#	results when polled several times successively.
#
#	(c) 2006 Yann Grossel
#

use strict;
use warnings;
use POSIX;

my $cache = '/var/tmp/stats.cache';
my $stats = '/var/tmp/cpop.stats';

die("Usage: $0 [ -c4 | -a4 | -c6 | -a6 | -stls | -immediate ]\n")
	if (scalar(@ARGV) != 1 || $ARGV[0] !~ m/^-([ac][46]{0,1}|stls|immediate)$/);

my $connections_v4		= 0;
my $authentications_v4	= 0;
my $connections_v6		= 0;
my $authentications_v6	= 0;
my $n_stls					= 0;
my $n_immediate			= 0;

sub rebuild_cache()
{
	# Open the cpop stats file and compute the average values for all
	# lines found. Results are stored in the cache file.
	# The cpop stats file is then deleted.

	unlink "${stats}.work";

	if (rename $stats, "${stats}.work")
	{
		if (open F, "${stats}.work")
		{
			my (@connections_v4, @authentications_v4, @connections_v6, @authentications_v6, @n_stls, @n_immediate);
			my $n_minutes = 0;
			my $cur = '';

			while (<F>)
			{
				# 20060321 163806 pop.fr.clara.net 2665 2614 0 0 0 0

				next unless (m/^(\d+\s+\d+)\s+\S+\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/);

				if ($cur ne $1)
				{
					$cur = $1;
					$n_minutes += 1;
				}

				push @connections_v4,		$2;
				push @authentications_v4,	$3;
				push @connections_v6,		$4;
				push @authentications_v6,	$5;
				push @n_stls,					$6;
				push @n_immediate,			$7;
			}

			close F;

			if ($n_minutes > 0)
			{
				foreach $_ (@connections_v4)		{ $connections_v4			+= $_; }
				foreach $_ (@authentications_v4)	{ $authentications_v4	+= $_; }
				foreach $_ (@connections_v6)		{ $connections_v6			+= $_; }
				foreach $_ (@authentications_v6)	{ $authentications_v6	+= $_; }
				foreach $_ (@n_stls)					{ $n_stls					+= $_; }
				foreach $_ (@n_immediate)			{ $n_immediate				+= $_; }

				$connections_v4		= ceil($connections_v4		/ $n_minutes);
				$authentications_v4	= ceil($authentications_v4	/ $n_minutes);
				$connections_v6		= ceil($connections_v6		/ $n_minutes);
				$authentications_v6	= ceil($authentications_v6	/ $n_minutes);
				$n_stls					= ceil($n_stls					/ $n_minutes);
				$n_immediate			= ceil($n_immediate			/ $n_minutes);
			}
		}

		unlink "${stats}.work";
	}

	open F, ">$cache"
		or die "Can't open $cache: $!\n";

	print F time() . "\n";

	print F "$connections_v4\n";
	print F "$authentications_v4\n";
	print F "$connections_v6\n";
	print F "$authentications_v6\n";
	print F "$n_stls\n";
	print F "$n_immediate\n";

	close F;
}

my $now = time();

if (-f $cache)
{
	open F, "$cache";

	chomp(my $ts = <F>);

	if (($now - $ts) < 290)
	{
		chomp($connections_v4		= <F>);
		chomp($authentications_v4	= <F>);
		chomp($connections_v6		= <F>);
		chomp($authentications_v6	= <F>);
		chomp($n_stls					= <F>);
		chomp($n_immediate			= <F>);

		close F;
	}
	else
	{
		close F;

		&rebuild_cache();
	}
}
else
{
	# The cache file does not exist.
	
	&rebuild_cache();
}

# Ok, display the requested value.

print "$connections_v4\n"		if ($ARGV[0] eq '-c' || $ARGV[0] eq '-c4');
print "$authentications_v4\n"	if ($ARGV[0] eq '-a' || $ARGV[0] eq '-a4');
print "$connections_v6\n"		if ($ARGV[0] eq '-c6');
print "$authentications_v6\n"	if ($ARGV[0] eq '-a6');
print "$n_stls\n"					if ($ARGV[0] eq '-stls');
print "$n_immediate\n"			if ($ARGV[0] eq '-immediate');

# vim: set ts=3 sw=3:
