Listing 2: better-print-mail.pl, an improved version of print-mail.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 = ("To" => 1, "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"); my $to_view = $query->param("to_view") || 0; # Print a nice beginning print $query->start_html(-title => "Your mail"); print "

Your mail

\n"; # ------------------------------------------------------------ # Create a new POP object print "

Connecting to server \"$mailserver\" as \"$username\"

\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); # Tell the user what messages are waiting print "You have $num_messages message", ($num_messages == 1) ? "" : "s", " waiting.\n"; # View a particular message, or all of them? my @message_indices; if ($query->param("to_view")) { @message_indices = $query->param("to_view"); } else { @message_indices = (1 .. $num_messages); } # ------------------------------------------------------------ # Iterate through each message, printing it foreach my $index (@message_indices) { print "

Message $index

\n"; print "
\n";

    # 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//>/g;

    # Make e-mail addresses clickable
    $contents =~ 
	s|([\w-.]+@[\w-.]+\.[a-z]{2,3})|$1|gi;

    # Make URLs clickable
    $contents =~ 
	s|(\w+tps?://[^\s&\"\']+[\w/])|$1|gi;

    # ------------------------------------------------------------
    # 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 the message
    print "\n\n", $body, "\n

\n"; } # Log off from the POP server $pop->quit; # Finish the CGI program print $query->end_html;