#!/usr/bin/perl # pop -- retrieve (new) messages via POP3 use strict; use warnings; use Net::POP3; use POSIX; use Term::ReadKey; use Sys::Hostname; # Flush STDERR select STDERR; $|++; select STDOUT; # Process arguments if (@ARGV != 2) { print STDERR "usage: $0 mbox mbox.i\n"; exit 1; } # Get UIDs of existing messages my ($mbox, $index, @existing_uids); if (-e $ARGV[1]) { open $index, '<', $ARGV[1] or die "Could not open $ARGV[1]: $!"; { local $/ = ''; # paragraph mode while (<$index>) { push @existing_uids, $1 if /^UID: (.*)$/m; } } close $index; } # Open mbox and index files for appending open $mbox, '>>', $ARGV[0] or die "Could not open $ARGV[0]: $!"; open $index, '>>', $ARGV[1] or die "Could not open $ARGV[1]: $!"; # Get POP3 server, username and password my $server = 'pop3.mailbox.org'; my $ssl = 1; my $timeout = 5; my $username = 'john@ankarstrom.se'; my $password; if (not $password) { print 'Enter password: '; ReadMode 'noecho'; chomp($password = ReadLine(0)); print "\n"; ReadMode 0; } # Connect to POP3 server my $pop = Net::POP3->new($server, SSL => $ssl, Timeout => $timeout) or die "Could not connect to POP3 server $server: $!\n"; $pop->login($username, $password) or die "Could not log into server\n"; # Retrieve ids and uids of all messages my @ids = sort { $a <=> $b } keys %{$pop->list}; my %uids = %{$pop->uidl}; # Handle SIGINT my $sigint = 0; $SIG{INT} = sub { print STDERR "\nSafely ending retrieval...\n"; $sigint = 1; }; # Append new messages to mbox and index files chomp(my $date = asctime(localtime(time))); my $offset = 0; my $i = 0; for my $id (@ids) { next if grep { $_ eq $uids{$id} } @existing_uids; print STDERR "\r$id/$ids[-1]"; my @msg; { local $/ = "\r\n"; chomp(@msg = @{$pop->get($id)}); } # Make From_ line my ($from, $from_alt); my $j = 0; # index of empty line before message body for (@msg) { last if /^$/; $j++; $from = $1 if /^From: (.*)$/; $from_alt = $1 if /^from: (.*)$/; } $from = $from_alt if $from_alt and not $from; $from = $1 if $from and $from =~ /^.* <(.*?@.*?)>$/; $from = 'MAILER-DAEMON@' . hostname if not $from; my $from_ = "From $from $date"; # Calculate message length my ($head_length, $body_length, $message_length); $head_length += length($_)+1 for (@msg[0..$j-1]); $body_length += length($_)+1 for (@msg[$j..$#msg]); $message_length = length($from_) + 1 + $head_length + $body_length; # Append message to mbox and index files local $" = "\n"; print $mbox <quit;