#!/usr/bin/perl -w
#
# Parses a maillog file to find qmail queue IDs, emaili addresses,
# IPs, and a count of messages experiencing the "Possible_duplicate!"
# problem.
#
# Usage: possible_duplicate.pl <maillog>
#
# olt 20010629 omar@clifford.inch.com
#
# Delivery IDs seem unique, so we can use them as a key.  If not, then
# increment a counter.

while (<>) {

# Line we're matching looks like this:
# Jun 28 01:12:12 bl qmail: 993705132.212309 starting delivery 838179: msg 142891 to remote john@doe.com

	if ( /starting delivery (\d+): msg (\d+) to remote (\S+\@\S+)/ ) {
		# Create a multi-dimensional array with
		# $1 = delivery,  $2 = msg,  $3 = email
		$starting{$1} = ["$2","$3"];
		#print "$starting{$1}->[0]\t$starting{$1}->[1]\n"; # msg,email

# 2nd line looks like this:
# Jun 28 08:42:57 bl qmail: 993732177.133462 delivery 862708: deferral: Connected_to_10.0.254.254_but_connection_died._Possible_duplicate!_(#4.4.2)/

	} elsif ( /delivery (\d+): deferral: Connected_to_(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})_but_connection_died._Possible_duplicate/ ) {
		# $1 = delivery,  $2 = IP
		$possible{$1} = $2;
	}
}

# Match up the Possible_duplicates with data in the "starting delivery" line
# Iteration is over delivery ids (unique) of possible dupes.
foreach $i (keys(%possible)) {
	$msg   = $starting{$i}->[0];
	$email = $starting{$i}->[1];
	$IP    = $possible{$i};
	# stringing together the qmail queue message id with the email
	# should be unique.
	$unique_result_key = $msg . $email;
	# if the element exists, increment the counter.
	if ( $results{$unique_result_key} ) {
		++$results{$unique_result_key}[3];
	# else create a new entry
	} else {
		$results{$unique_result_key} = [$msg, $email, $IP, 1];
	}
}

# Iterate through the results and print.
printf ("%8s%40s%17s%4s","qID","email","IP","#");
print "\n";
printf ("%8s%40s%17s%4s","---","-----","--","-");
print "\n";
foreach $k (keys(%results)) {
	printf ("%8s","$results{$k}->[0]");
	printf ("%40s","$results{$k}->[1]");
	printf ("%17s","$results{$k}->[2]");
	printf ("%4s","$results{$k}->[3]");
	print "\n";
}
