#!/usr/bin/perl

#
# spambuster
#
# deletes unwanted mail from a POP3 server
#
# (C) Angel Ortega 1999
#

use Getopt::Long;
use Socket;
use FileHandle;

$host="localhost";
$port=110;

$user="";
$pass="";

$max_size=2500000;

$verbose=0;

$kill_file="/etc/spambuster.conf";

$usage=0;


#########################

usage() if (!GetOptions("help"		=> \$usage,
			"h|host=s"	=> \$host,
			"u|user=s"	=> \$user,
			"p|password=s"	=> \$pass,
			"o|port=i"	=> \$port,
			"m|max" 	=> \$max_size,
			"v|verbose"	=> \$verbose,
			"f|file=s"	=> \$kill_file)
	or $usage);

usage() unless ($user and $pass);

open(FILE,$kill_file) or bang("Imposible abrir $kill_file");
@victims=<FILE>;
chomp(@victims);
close(FILE);

$ip=inet_aton($host);
$addr=sockaddr_in($port,$ip);

socket(CLI,PF_INET,SOCK_STREAM,0) or bang("socket: $!");
connect(CLI,$addr) or bang("connect: $!");
CLI->autoflush();

$_=<CLI>;
print if $verbose;

bang("Connection refused (1)") unless /^\+/;

print CLI "USER $user\r\n";

$_=<CLI>;
print if $verbose;
bang("Connection refused (2)") unless /^\+/;

print CLI "PASS $pass\r\n";

$_=<CLI>;
print if $verbose;
bang("Connection refused (bad user/password?)") unless /^\+/;

print CLI "LIST\r\n";

$_=<CLI>;
print if $verbose;
bang("unexpected response from LIST") unless /^\+/;

%msgs=();
$cnt=0;

for(;;)
{
	$_=<CLI>;
	chop($_);

	last if /^\./;

	$cnt++;

	($msg,$size)=split(" ",$_);

	$m={};
	$m->{-size}=$size;

	$msgs{$msg}=$m;
}

print "$cnt mensajes\n" if $verbose;

foreach $i (keys %msgs)
{
	$m=$msgs{$i};

	if($m->{-size} > $max_size)
	{
		print CLI "DELE $i\r\n";

		$_=<CLI>;
		print if $verbose;
		bang("Error deleting (by size)") unless /^\+/;

		# borra del array
		delete $msgs{$i};

		print "Deleted message $i (size $m->{-size}>$max_size)\n"
			if $verbose;
	}
}


foreach $i (keys %msgs)
{
	$m=$msgs{$i};

	for($lines=10,$complete=0;!$complete;$lines+=10)
	{
		print CLI "TOP $i $lines\r\n";

		$_=<CLI>;
		print if $verbose;
		bang("TOP error (unimplemented?") unless /^\+/;

		for(;;)
		{
			$_=<CLI>;
			chop($_); chop($_);

			$complete=1 if /^$/;

			last if /^\.$/;

			next if /^ /;

			($token,$val)=split(" ",$_,2);

			$m->{$token}=$val;
		}
	}

	print "From: " . $m->{"From:"} . "\n" if $verbose;
}


foreach $i (keys %msgs)
{
	$m=$msgs{$i};

	foreach $n (@victims)
	{
		if($m->{"From:"} =~ /$n/ )
		{
			print CLI "DELE $i\r\n";

			$_=<CLI>;
			print if $verbose;
			bang("Error deleting (by from)") unless /^\+/;

			delete $msgs{$i};

			print "Deleted message $i (of $n)\n" if $verbose;
			last;
		}
	}
}


print CLI "QUIT\r\n";
$_=<CLI>;
close CLI;

exit(0);

sub usage
{
	print "Uso: spambuster [-h|--host={host}] [-u|--user={usuario}] \n";
	print "     [-p|--pass={password}] [-m|--max={tamaño máximo}] [-o|--port={puerto}]\n";
	print "     [-f|--file={kill file}] [-v|--verbose] [--help]\n";

	exit(1);
}


sub bang
{
	my ($error)=@_;

	print STDERR "spambuster: $error\n";
	exit(1);
}
