bobano has asked for the wisdom of the Perl Monks concerning the following question:

I am writing a POP3 Client program in Perl but can't figure out how to split up the e-mail messages required in "List Messages" in Menu Option 1 of my program to display a list of the messages displaying ONLY the message number, who the message is from and the subject. I am not displaying the entire text of the message in Option 1.

Here is the code for the program so far:
#!/usr/bin/perl -w use strict; use IO::Socket qw(:DEFAULT :crlf); my $host = shift || 'pop3.isp.ca'; my $port = shift || '110'; # port 110 for POP3 my $socket = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port) or die "no sock $!"; my $choice; # line 10 my $answer; my $username; my $mypass; my $msgnum; my $msgcount = 0; $username = "x9xxxx99"; # format masks for user name $mypass = "99xxx9x9"; # and password of ISP log-in print $mypass; $answer = <$socket>; print "$answer\n"; # send username, pass print $socket "user " . $username,CRLF; $answer = <$socket>; print $socket "pass " . $mypass,CRLF; $answer .= <$socket>; print "$answer\n"; #line 30 system("cls"); print "=======================================================\n"; print "POP3 Mail Client you have " . $msgcount. "messages waiting.\n"; print "======================================================="\n; while (1) { # menu print " 1 List Messages\n"; print " 2 Display body\n"; print " 3 Display header and body\n"; print " 4 Write message to a file\n"; print " 5 Delete message on the server\n"; print " 6 Quit\n\n"; print "Enter choice: "; chomp ($choice = <STDIN>); # option 1 selected- List all messages (message # number, who it is from and subject of the message) if ($choice =~ /^1$/) { print $socket "LIST",CRLF; $answer = <$socket>; print "$answer\n\n"; if ($msgcount > 0) { for (my $i = 0; $i < $msgcount; $i++) { print "\n\n"; $msgnum = $i; print $socket "RETR ".$msgnum,CRLF; $answer = <$socket>; if ($answer =~ /^\-ERR/) { print "Messages could not be displayed"; } else { while (1) { # regular expression to list messages # with message number, from and subject /^(From|Subject):\s+/i and print $_, "\n"; } print "\n"; } else { print "\n\nYou currently have no messages."; <STDIN>; next; } next; } if ($choice =~ /^2$/) { # print "\nPlease enter message number: "; # chomp($msgnum = <STDIN>); # print $socket "RETR ".$msgnum,CRLF; # $answer = <$socket>; # if ($answer =~ /^\-ERR/) { # print "Error: invalid message number"; # <STDIN>; # next; # } # else { # } next; } if ($choice =~ /^6$/) { print $socket "QUIT",CRLF; $answer = <$socket>; print "$answer\n"; print "exiting\n" and last; } }
Can someone also tell me for Option 3 where I need to display the header and body of the e-mail based on the message number typed in by the user how I can differentiate between the header and body of each message using regular expressions? I should also point out that I am prohibted from using any of the Net::POP3 Perl modules or POP3Mail Perl modules to complete this so I need to use regular expressions and the IO::Socket Perl module only.

Anyone who can give me some assistance on this problem would be greatly appreciated by me. Thanks.

Edit: g0n - readmore tags

Replies are listed 'Best First'.
Re: POP3 Mail Client using IO::Socket module only
by jdtoronto (Prior) on Apr 11, 2006 at 05:55 UTC
    Why?

    Kinda sounds like a homework problem to me.

    But you are going to need more than just a few regular expressions. The first thing you should do is to understand the Post Office Protocol itself. You should, therefore, read RFC1725 and Internet Standard STD53. Once you understand those and you understand the structure of the headers, then you will be able to code it.

    jdtoronto

Re: POP3 Mail Client using IO::Socket module only
by nferraz (Monk) on Apr 11, 2006 at 08:45 UTC

    Start by reworking your interface: "Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface." (This is the Unix philosophy.)

    When you have those small programs working, then you can start building an interactive interface. Otherwise you won't be able to concentrate on the important things.

Re: POP3 Mail Client using IO::Socket module only
by bobano (Novice) on Apr 11, 2006 at 18:54 UTC
    I am close to getting all of the messages in the mailbox listed with their message number, who the message is from and the subject but it is messing up and giving me ALL the header information of the message even though I only want the message number defined in the program as well as the "From" and "Subject" fields. It also seems to be only displaying the header info for one of the messages which means something is faulty with the "for" loop that I created that should work because someone else showed me how to arrange that. Here is my updated code for Option 1 "List Messages":
    if ($choice =~ /^1$/) { print $socket "STAT",CRLF; $answer = <$socket>; print "$answer\n\n"; if ($answer =~ /^\+OK\s(\d{1,}).*/) { $msgcount = $1; print "You have " . $msgcount . " messages"; } if ($msgcount > 0) { for (my $i = 0; $i < $msgcount; $i++) { print $socket "STAT",CRLF; $answer = <$socket>; print "$answer\n\n"; $msgnum = $i; print "Message Number: " . $msgnum; print $socket "RETR " . $msgnum,CRLF; $answer = <$socket>; if ($answer =~ /^\-ERR/) { print "ERROR"; } else { # these are regular expressions to parse # out and display only the From and Subject # fields from the message header # information which I get using the RFC # 1939 protocol and I backreference the # expressions with "$1" and "$2" scalar # variables if ( $answer =~ /^From:(.*)/ ) { print "From: $1\n"; } if ( $answer =~ /^Subject:(.*)/ ) { print "Subject: $2\n"; } } print "\n"; } } else { print "\n\nYou currently have no messages."; <STDIN>; next; } next; }
    If anyone has any suggestions for how to fix this or attempt to clean it up, it would be greatly appreciated. I DO NOT expect people to start writing the code for me. I just want a few snippets here and there of things that any of you think I may be missing or things that I need to include. Once, I get one part working with the regular expressions, I can easily get the others going because Option 2 is similar to Option 1 except I parse out the body of the message using a regular expression and Option 3 is just displaying both header and body which is everything I parsed out in Option 1 for the header (message number, from, subject) and Option 2 (body of the message). I'm also gambling on the fact that people actually know a lot about socket programming and communicating with a POP3 server using the RFC 1939 protocol but it's a chance I am willing to take. I printed out the RFC 1939 protocol and understand how the RFC commands work but it's just parsing it to display just a particular portion that is throwing the program off.

    Thanks.