Listing 3: mail-index.pl.

#!/usr/bin/perl -wT

use strict;
use diagnostics;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
use Net::POP3;

# Force flushing
$| = 1;

# What headers should we display?
my %KEEP = ("From" => 1,
	    "Subject" => 1,
	    "Date" => 1);

# ------------------------------------------------------------
# Create a new CGI object
my $query = new CGI;

# Send a MIME header
print $query->header("text/html");

# Get a bunch of information
my $mailserver = $query->param("mailserver");
my $username = $query->param("username");
my $password = $query->param("password");

# Print a nice beginning 
print $query->start_html(-title => "Your mail");
print "<H1>Your mail</H1>\n";

# ------------------------------------------------------------
# Create a new POP object
print "<P>Connecting to server \"$mailserver\" as \"$username\"</P>\n";
my $pop = new Net::POP3($mailserver,
			-Timeout => 20);
die "Error connecting" unless (defined $pop);

# Log into the server
my $num_messages = $pop->login($username, $password);
die "Error logging in" unless (defined $num_messages);

# How many messages?
print "You have $num_messages message",
    ($num_messages == 1) ? "" : "s", " waiting.\n";

# Create the form
print '<Form method="POST" action="/cgi-bin/better-print-mail.pl">', "\n";

# Carry over the user's information
print "<input type='hidden' name='mailserver' value='$mailserver'>\n";
print "<input type='hidden' name='username' value='$username'>\n";
print "<input type='hidden' name='password' value='$password'>\n";

# Pre-format the header information
print "<pre>\n";

# ------------------------------------------------------------
# Iterate through each message, printing it
foreach my $index (1 .. $num_messages)
{
    # Set up a radio button for this message
    print "\n\n<input type='checkbox' name='to_view' value='$index'> ";

    # Grab the message contents
    my $message_ref = $pop->get($index);

    # Get the entire message as a scalar
    my $contents = join "", @$message_ref;

    # ------------------------------------------------------------
    # Turn special characters into entities
    $contents =~ s/</&lt;/g;
    $contents =~ s/>/&gt;/g;

    # ------------------------------------------------------------
    # Break the message into headers and body
    my ($headers, $body) = split "\n\n", $contents, 2;

    # Print the message headers
    my @headers = split "\n", $headers;
    my $previous = "";

    foreach my $line (@headers)
    {
	# If this is a new header, put its name in $previous
	# If we are on a continuation line, this won't match
	if ($line =~ m/^([\w-]+):/i)
	{
	    $previous = $1;
	}

	# Print the line, if it is in %KEEP
	print $line, "\n" if $KEEP{$previous};
    }

}

print "</pre>\n";
print '<input type="submit" value="Read checked messages"', "\n";

# Log off from the POP server
$pop->quit;

# Finish the CGI program
print $query->end_html;
