#!/usr/bin/perl
# Verbrochen von: Sven Weise <sven.weise@unit0.net>
#
# Checks for feedholes
#
# Gets $maxget Message-IDs (and Path-Header data) from @servers and checks if
# $self misses some of the Message-IDs
#
# The $group for comparisation can be supplied as parameter:
# /check_feedholes.pl de.test
# If no parameter is set alt.binaries.sounds.mp3 will be used as default
#

use strict;
use News::NNTPClient;
use Data::Dumper;

# CHANGE ME! 
my $self='news.unit0.net';
# Group we want to use for comparisation
my $group=$ARGV[0]||'alt.binaries.sounds.mp3';
# Max MIDs we want to fetch
my $maxget='1000';
# Servers we want to fetch
my @servers=(
	# First we declare ourself to be fetched;
	{
		'host' => $self,
		'user' => '',
		'pass' => '',
	},
	# Now we declare some servers we want to use as references
	{
		'host' => 'news.sample.com',
		'user' => 'username',
		'pass' => 'password',
	},
	{
		'host' => 'news.bigserver.net',
		'user' => 'username',
		'pass' => 'secret',
	},
);
# Normaly nothing to change below this line
my %result;
my %missing;





# Get data from servers
for my $ref (@servers) {
	my $lain=conn(
		'host' => $ref->{'host'},
		'user' => $ref->{'user'},
		'pass' => $ref->{'pass'},
	);

	%{$result{$ref->{'host'}}}=query(
		'conn' => $lain,
		'get'  => $maxget,
	);

	$lain->quit;
}

# Get throu the server results and determine missing MIDs
foreach my $server (keys %result) {
	next if ($server eq $self);

	foreach my $mids (keys %{$result{$server}}) {
		$missing{$server}{$mids}=$result{$server}->{$mids} if (! exists $result{$self}->{$mids});
	}
}

# If we got some missing MIDs print it.
if (scalar(keys %missing) >= 1) {
	print "********** Check for feedholes **********\n";
	print '#########################################'."\n";
	print "Gruppe: $group\n";
	print "Myself: $self\n";
	foreach my $server (keys %missing) {
		my $count;
		print '#########################################'."\n";
		print "Reference server : $server\n";
		print 'Count "missing"  : '.scalar(keys %{$missing{$server}})."\n";
		print "\n";
		foreach my $mids (keys %{$missing{$server}}) {
			print "$mids => $missing{$server}->{$mids}\n";
		}
	}
}





sub conn {
	my %config=@_;

	my $wired=new News::NNTPClient($config{'host'},119,0);
	if ($wired->ok != 1) {
		printf "%d %s", $wired->code, $wired->message;
		exit(1);
	}
	$wired->mode_reader;
	if ($wired->ok != 1) {
		print "$config{'host'}: Readeraccess not permitted.\n";
		$wired->quit;
		exit(1);
	}
	if ((defined($config{'user'}) && $config{'user'}) && (defined($config{'pass'}) && $config{'pass'})) {
		$wired->authinfo($config{'user'},$config{'pass'}) || do { $wired->quit; die "$config{'host'}: Authentication failed!\n"; }
	}
	return $wired;
}

sub query {
	my %config=@_;
	my (%return,%tmp);

	my @counts=$config{'conn'}->group($group);
	my $idx=$counts[1]-$config{'get'}+1;

	my @mid=$config{'conn'}->xhdr("Message-ID", "$idx-$counts[1]");
	my @pat=$config{'conn'}->xhdr("Path", "$idx-$counts[1]");

	for (@mid) {
		chomp;
		my ($aid,$id)=split(/ /);
		$tmp{$aid}{'mid'}=$id;
	}

	for (@pat) {
		chomp;
		my ($aid,$path)=split(/ /);
		$tmp{$aid}{'path'}=$path;
	}

	undef @mid;
	undef @pat;

	foreach my $aid (keys %tmp) {
		$return{$tmp{$aid}{'mid'}}=$tmp{$aid}{'path'};
	}

	return %return;
}
