#!/usr/bin/perl
#
# spam_processor.pl: Extract from spam email the originating ip this garbage
#                    came from.

use Net::IP;  # Useful for converting IPv4 strings to binary numbers.  
$ips_listed=0;               # Total spam IP addresses listed.
$ip_list[0]=0b0;             # Start off IP list with 0d0.
$ip_addr="000.000.000.000";  # A default IPv4 string.

open ( SPAM, "./mail/spam") || die "Can't open spam $!";

if ( -e "ip_list" )
{ # Then there is a preexisting list that needs to be fed in first...

     open ( IN_IP, "ip_list" ) || die "Can't open ip_list $!";

     while ($data_line=<IN_IP> )
     {
            chomp ($data_line);

            if ( $ips_listed == 0 )
            {
            	$ip_list[0]=$data_line;
            }
            else
            {
            	$ip_list[$ips_listed]=$data_line;
            }

            ++$ips_listed; 
     }

     close (IN_IP) || die "Error: can't close ip_list $!";
}

open ( OUT_IP, ">ip_list") || die "Can't open ip_list $!"; 

$exclude="^Received: from ((web|xerxes|goose)\.robinson-west\.com |localhost )";
$received_to_skip=5;

&main;  # Program's first function called here ;-)

sub main
{ # This is the first routine that should be called.


     while ($origin=<SPAM>)
     {	   
            chomp;

            # Time to convert the correct Received from: line...
            if ( $origin=~/$exclude/ )
            { 
                 --$received_to_skip; 
            }

            elsif ( $origin=~/^Received: from .*\[/ )
            {
                    if ( 0 < $received_to_skip )
                    { # Must be a later received from line, should ignore...
                         
                         $received_to_skip=5;
                         cont;
                    }

                    $origin=~s/^Received: from .*\[/X-Originating-IP: /;
                    $origin=~s/\].*$//;
                    chomp ($origin);
                    $received_to_skip=5;
            }
            else
            { cont; }
            
            if ( $origin =~ /^X-Originating-IP: / )
            {
                 # Extract ip address from $origin...
                 $ip_addr = substr ( $origin, 19 ); 

                 $status=&no_dup_enter_into_list;

            } # End of process acceptable line...

     } # End of while loop...

     # Sort the SPAM source IP addresses...
     my @sorted_ips=sort @ip_list;

     # Print them in order to a file...
     for ( $counter=0 ; $counter < $ips_listed ; ++$counter )
     {
           print OUT_IP "$sorted_ips[$counter]\n";
     }
     
     close ( OUT_IP ) or die "Error--cannot close OUT_IP $!";

     close ( SPAM ) or die "Error--cannot close SPAM $!";

     unlink ("./mail/spam");

     open ( SPAM, ">./mail/spam" );

     close ( SPAM ) or die "Error--cannot close SPAM $!";

} # END main function.

#-------------------------------------------------------------------------------

sub no_dup_enter_into_list
{ # Check for duplicates before inserting candidate IP address.
  # Return a string indicating what happened.

        # Convert IP string representation to binary integer representation...
        $binip=Net::IP::ip_iptobin($ip_addr,4);

        for ( $count=0 ; $count < $ips_listed ; ++$count )
	{

	      if ( $binip eq $ip_list[$count] )
              {
                   return ( "Sorry, duplicate found." );
              }
        }

        &enter_into_list;

        return ( "Inserted new address!" );

} # END no_dup_enter_into_list function.



sub enter_into_list
{ # Unique spam source found, put IP address in the list...

    if ( $ips_listed == 0 )
    {
         $ip_list[0] = $binip; 
    }
    else
    {
         $ip_list[$ips_listed] = $binip; 
    }

    ++$ips_listed;

} # END enter_into_list function.
