#!/usr/bin/perl

use Socket;

if($ARGV[0] eq "cron") { $cron = 1; } else { $cron = 0; }

$memach = "username";
$mailer = "mail.myisp.com";
$passwd = "password";

$port = getservbyname('pop3','tcp') || 110;
$saddr = inet_aton($mailer) || die "Couldn't get server: $!\n";
$servdat = sockaddr_in($port, $saddr);
$proto = getprotobyname('tcp') || 6;

socket(SERV,PF_INET,SOCK_STREAM,$proto) || die "socket: $!";
connect(SERV,$servdat) || die "connect: $!\n";

select((select(SERV),$| = 1)[0]);

while(<SERV>)
{
   last if /^\+OK/;
}
s/^\+OK //;
print "$_\n" if(!$cron);

print SERV "USER $memach\n";
$ok = <SERV>;
print SERV "PASS $passwd\n";
$stat = <SERV>;
print SERV "LIST\n";
$ok = <SERV>;
$msg = 0;

if($ok =~ /^-ERR/) {
  print "No messages, probably : $ok" if(!$cron);
  goto abandon;
}
while(<SERV>)
{
   last if /^\.\r?$/;
   $msg++;
   ($num,$size) = /^(\d+)\s+(\d+)\r?$/;
   print "Message $num has size $size" if(!$cron);
   if($num != $msg) { print " (Weirdness)" if(!$cron); }
   print "\n" if(!$cron);
}

if($msg == 0)
{
   print "No messages - quitting\n" if(!$cron);
}
else
{
   open(CRONOUT,">/dev/tty10") if($cron);
   $n = 1; while(-e "/tmp/pulled$n") { $n++; }
   $n--;
   print "\n" if(!$cron);
   if($cron) {
     print CRONOUT "Time        To         From                    Subject\n" .
                   "----        --         ----                    -------\n";
   } else {
     print "Msg To         From                    Subject\n" .
           "--- --         ----                    -------\n";
   }

   for($i=1;$i<=$msg;$i++)
   {
      $x = $i + $n;
      $shown = 0;
      $subj = 0;
      $to = 0;
      $from = 0;
      if($i<10) { if(!$cron) { print " "; } }
      if(!$cron) { print " $i "; }

      open(FILE,">/tmp/pulled$x");
      print SERV "RETR $i\n";
      $ok = <SERV>;
      while(<SERV>)
      {
         last if /^\.\r?$/;
         if(/^\r?$/ && !($shown))
         {
            &showinfo;
            $shown = 1;
         }
         if(/^X-Frontier-To:/ || /^Apparently-To:/ || /^To:/)
         {
            if(!($to)) { &getto($_); }
         }
         if(/^From:?/i && (!($from)))
         {
            &getfrom($_);
            $from = substr($from,0,25);
         }
         if(/^Subject:/i && (!($subj)))
         {
            ($subj) = /^Subject:\s+(.*)\r?$/;
            $subj = substr($subj,0,40);
         }
         if(/^From /) { s/^F/>F/; }

         print FILE ;
      }
      close(FILE);

     ($to eq "(nobody)") && ($to = "postmaster");
     $to =~ tr/A-Z/a-z/;
     open(FILE2,">>/var/spool/mail/$to");
     chop($date = `date`);
     $date =~ s/ BST//;
     print FILE2 "From $realfrom $date\n";
     print FILE2 "Received: from $mailer by $memach.ftech.co.uk via pop-puller for $to\@$memach.ftech.co.uk; $date\n";
     close(FILE2);
     system("cat /tmp/pulled$x >> /var/spool/mail/$to");
     print SERV "DELE $i\n";
     $ok = <SERV>;
   }
}

print CRONOUT "\n" if($cron);
close(CRONOUT) if($cron);

abandon:

print SERV "QUIT\n";
$ok = <SERV>;

close(SERV) || die "close: $!\n";

sub showinfo
{
      if(!($to)) { $to = "(nobody)"; }
      $to = substr($to,0,10);
      if(!($subj)) { $subj = "(none)"; }
      $subj = substr($subj,0,40);
      if(!($from)) { $from = "(nobody)"; $realfrom = "(nobody)"; }
      $from = substr($from,0,23);
 
      if($cron) {
        ($sec,$min,$hour,$mday,$mon,@stuff) = localtime(time);
        $mon++; # silly 0-11-ness
        printf(CRONOUT "%02d/%02d %02d:%02d %s\n", $mday, $mon, $hour, $min,
         "$to" . " " x (11-length($to)) .
         "$from" . " " x (24-length($from)) .
         "$subj");
      } else {
        print "$to" . " " x (11-length($to)) .
              "$from" . " " x (24-length($from)) .
              "$subj\n";
      }
}

sub getto
{
   ($text) = @_;
   ($to,$mach) = ($text =~ /^.*:\s+(.+)@(.*)$/);
   $to =~ s/^\./-/;
   $to =~ s#/#\.#g;
}

sub getfrom
{
   $_ = $_[0];
  
   if(/^From:? .+\s+<.+>/)
   {
      ($from,$realfrom) = /^From:\s+(.+)\s+<(.+)>/;
      if($from =~ /^".+"$/) { ($from) = ($from =~ /^"(.+)"$/); }
   }
   elsif(/^From:?\s+.+\s+\(.+\)/)
   {
      ($realfrom,$from) = /^From:?\s+(.+)\s+\((.+)\)/;
   }
   else
   {
      ($from) = /^From:?\s+(\S+)/;
      $realfrom = $from;
   }
}
