http://www.perlmonks.org?node_id=282544
Category: E-Mail Programs
Author/Contact Info Elfyn McBratney <elfyn at emcb dot co dot uk>
Description: Well, mutt died on me (ncurses upgrade) and I was waiting for a really important e-mail ...So I wrote this up in 10 minutes, and got me that e-mail. :-) Thought it might help someone else, or even teach them (in a simplific style) how to use Net::POP3 .
#!/usr/bin/perl -w
# -*- perl -*-
#
# popcheck: quick, cheap and dirty mail checker
#
#   Quick and cheap perl script to check mail on a remote
#   POP3 server. Born when mutt died ...
#
# Under the do what you like with it BUT don't blame me,
# type license.

BEGIN {
  use strict;
  use warnings;
  use vars qw(%opts $pop $pop_host $pop_user $pop_pass
              $pop_msgnum $ans $version $nopts);

  use File::Basename;
  use Getopt::Std;
  use Net::POP3;

  # Set-up the default server, user and password vars
  $pop_host = '';
  $pop_user = '';
  $pop_pass = '';

  # The program's version
  $version = '$Revision: 1.1 $';
}

# Check if we've been given any arguments. If not, just (goto)
# `mailcon'.
if ($#ARGV == -1) {
  goto mailcon;
  $nopts = 1;
} else {
  $nopts = 0;
}

# Now let getopt() process our arguments.
getopts ('s:u:p:g:d:rhv', \%opts);

# Check (and action) our given options
if (exists ($opts{'h'})) {
  &usage ();
  exit (0);
}
if (exists ($opts{'v'})) {
  &print_verinfo ($version);
  exit (0);
}
if (exists ($opts{'s'})) {
  $pop_host = $opts{'s'};
}
if (exists ($opts{'u'}) && exists ($opts{'p'})) {
  $pop_user = $opts{'u'};
  $pop_pass = $opts{'p'}
}

mailcon:
# Try and connect to the POP3 server
$pop = Net::POP3->new ($pop_host, Timeout => 30) or do {
  # Ut-oh! failed to connect for some reason ...
  printf ("Failed to connect to server `%s': $!\n", $pop_host);
  exit (1);
};
# Now, try and login
$pop_msgnum = $pop->login ($pop_user, $pop_pass) or do {
  # Failed to login... why?
  printf ("Failed to login on server `%s' as user `%s': $!\n", $pop_ho
+st, $pop_user);
  exit (1);
};
# If there were no options passwd we jump the `mcheck'
if ($nopts == 1) {
  goto mailck;
}

# Now we check what was returned from $pop->login(). If the
# return value equals the string "EOE", that means the mailbox
# is empty. If it returns undef, login failed. Otherwise, it
# returns the number of messages in the mailbox.
if ($pop_msgnum eq "0E0") {
  printf ("No messages on server\n");
} elsif (!$pop_msgnum) {
  printf ("Login failed\n");
} else {
  # No run through pur get and delete options and see if they
  # have been requested by the user. First `g' (get) and then
  # `d' (delete).
  if (exists ($opts{'g'})) {
    # Check if the given message number is above the total number
    # of messages in the mailbox (and thus not get()'able.
    if ($opts{'g'} > $pop_msgnum) {
      printf ("message number `%d' too high! (%d max)\n", $opts{'g'}, 
+$pop_msgnum);
    } else {
      # (Try to) fetch the message contents for the given message
      # number.
      $msg = $pop->get ($opts{'g'});
      # Check that we successfully fetched the message
      if (!$msg || $msg eq "") {
        printf ("failed get()'ing message number `%d': %s\n", $opts{'g
+'}, $!);
      } else {
        # Set the temporary filename.
        $tmp_fn = '/tmp/popcheck.'.$$.'.'.time ();
        # Try and open the file
        open (TMP, ">$tmp_fn") or do {
          die ("Failed to open `%s': $!\n", $tmp_fn);
        };
        # Now dump the message into the temporary file
        foreach (@{$msg}) {
          print TMP $_;
        }
        close (TMP) or do {
          die ("`%s' did not close nicely: $!\n", $tmp_fn);
        };
        # Now we open the file with the less pages, and let you
        # see the message. :-)
        system ("less $tmp_fn");
        # If we've been asked to remove temporary files, we
        # better do so.
        if (exists ($opts{'r'})) {
          unlink ($tmp_fn);
        }
      }
    }
  } elsif (exists ($opts{'d'})) {
    # Check if the given message number is above the total number
    # of messages in the mailbox (and thus not delete()'able.
    if ($opts{'d'} > $pop_msgnum) {
      printf ("message number `%d' too high! (%d max)\n", $opts{'d'}, 
+$pop_msgnum);
    } else {
      # We prompt the user for conformation before deleting the
      # message. If their answer matches '/y|ye|yes/i' then we
      # delete, otherwise we leave the message and alert the user
      # to that fact.
      printf ("delete message number `%d' [yes|no]: ", $opts{'d'});
      $ans = <STDIN>;
      if ($ans =~ /y|ye|yes/i) {
        $pop->delete ($opts{'d'});
      } else {
        printf ("not deleting message number `%d'\n", $opts{'d'});
      }
    }
  } else {
    mailck:
    printf ("%d messages on server\n", $pop_msgnum);
  }
}

$pop->quit ();

sub usage {
  printf ("usage: %s [-g msgnum] [-d msgnum] [-h]\n", basename ($0) ||
+ $0);
  printf ("\n");
  printf ("  -s   Set POP3 server\n");
  printf ("  -u   Set POP3 username\n");
  printf ("  -p   Set POP3 password\n");
  printf ("  -g   Get message\n");
  printf ("  -d   Delete message\n");
  printf ("  -r   Remove temporary files\n");
  printf ("  -v   Display version information\n");
  printf ("  -h   Display help information\n");
  printf ("\n");
  printf ("The usage of (alternate) usernames and passwords are\n");
  printf ("conditional on both the username and password being\n");
  printf ("specified (on the command line).\n");
  printf ("\n");
  printf ("Written by Elfyn McBratney <elfyn\@emcb.co.uk>\n");
}

sub print_verinfo {
  my $version = shift;
  if ($version =~ /\s+([\d\.]+)\s+/) {
    printf ("%s (version %s)\n", basename ($0) || $0, $1);
  } else {
    printf ("%s (%s)\n", basename ($0) || $0, $version);
  }
}