Solved

Get information out of a message header

Posted on 1998-06-19
9
157 Views
Last Modified: 2010-03-04
I am programming a script that will be able to fetch mail from a remote pop3 server etc.

Now, I have come so far so my script is able to connect to a remote pop3 server, login, and execute whatever command and get the output of that command from the pop3 server.

Below I have included a part of code that I am having trouble with. The pop3 command "TOP $msg_check 0" gives the message header of message number $msg_check in return. The &check_pop3_server_reply subroutine just checks if the pop3 server responds with "+OK...bla...bla".

$msg_check = "1";
$msg_in_mailbox = 44;

while ($msg_check < $msg_in_mailbox) {
      print SOCKET "TOP $msg_check 0\n";
      &check_pop3_server_reply;

      while (<SOCKET> =~ /(\d+)\: (\d+)/) {
            if ($1 == "Date\:") { $msg_date = $2; }
            if ($1 == "From\:") { $msg_from = $2; }
            if ($1 == "Subject\:") { $msg_subject = $2; }
      }

print "Msg. no. $msg_check<br>\n";
print "Date: $msg_date<br>\n";
print "From: $msg_date<br>\n";
print "Subject: $msg_subject<br>\n";

$msg_check++;
}

I want to list all messages´ from, date, subject information by later using $msg_date, $msg_from and $msg_subject. Currently, with the above code, it doesn´t work.
0
Comment
Question by:thornbush
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 2
  • +1
9 Comments
 

Author Comment

by:thornbush
ID: 1207900
Edited text of question
0
 
LVL 84

Expert Comment

by:ozo
ID: 1207901
perl -Mdiagnostics=verbose -we 'if ($1 == "Date\:") { $msg_date = $2; }'
Argument "Date:" isn't numeric in eq at -e line 1.
   
    (W) The indicated string was fed as an argument to an operator that
    expected a numeric value instead.  If you're fortunate the message
    will identify which operator was so unfortunate.

0
 

Author Comment

by:thornbush
ID: 1207902
I have earlier tried with eq instead of == without any results.

One strange thing that happen, when I try to just look at the <SOCKET> output after the command "TOP $msg_check 0" (the 0 stands for that I just want to see the header of the message and $msg_check for which of the 43 messages I want to look at), like this....

    $msg_check = "1";
    $msg_in_mailbox = 44;

    while ($msg_check < $msg_in_mailbox) {
    print SOCKET "TOP $msg_check 0\n";
    &check_pop3_server_reply;

   $reply = <SOCKET>;
   print $reply;

    $msg_check++;
}

.the script gives the first line of message number 1:s header....and then when
$msg_check = 2 it gives the second line of message number 1:s header (second line of number 1:s header when $msg_check = 2 ?!?!). Hmmmm..... :/
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:thornbush
ID: 1207903
I have earlier tried with eq instead of == without any results.

One strange thing that happen, when I try to just look at the <SOCKET> output after the command "TOP $msg_check 0" (the 0 stands for that I just want to see the header of the message and $msg_check for which of the 43 messages I want to look at), like this....

    $msg_check = "1";
    $msg_in_mailbox = 44;

    while ($msg_check < $msg_in_mailbox) {
    print SOCKET "TOP $msg_check 0\n";
    &check_pop3_server_reply;

   $reply = <SOCKET>;
   print $reply;

    $msg_check++;
}

.the script gives the first line of message number 1:s header....and then when
$msg_check = 2 it gives the second line of message number 1:s header (second line of number 1:s header when $msg_check = 2 ?!?!). Hmmmm..... :/
0
 
LVL 2

Expert Comment

by:mlev
ID: 1207904
About your last comment - of course it does, because '$reply=<SOCKET>' fetches a single line each time.

About the question - I think you got the loop condition wrong (it looks for pattern <number>:<number> as it is)
Try this:
while (not ($reply=<SOCKET) eq ".\r\n")) {
      $reply =~ /(\w+)\:\s(.*)/;
      ...
0
 
LVL 1

Accepted Solution

by:
RoboBob earned 200 total points
ID: 1207905
The problem with eq (which you should use instead of ==) is that the regular expression you are using does not include the : in the expression, but your check does, also, your check is case sensitive, which will often cause it to fail, try this instead:


$msg_check = "1";
$msg_in_mailbox = 44;

while ($msg_check < $msg_in_mailbox) {
    print SOCKET "TOP $msg_check 0\n";
    &check_pop3_server_reply;

    while (<SOCKET>) {
        ($label,$value) = split(':',$_,2);
        if ($label =~ /^Date/) { $msg_date = $value; }
        if ($label =~ /^From/) { $msg_from = $value; }
        if ($label =~ /^Subject/) { $msg_subject = $value; }
    }

    print "Msg. no. $msg_check<br>\n";
    print "Date: $msg_date<br>\n";
    print "From: $msg_date<br>\n";
    print "Subject: $msg_subject<br>\n";

    $msg_check++;
}

Also, you could save yourself a lot of trouble by using the POP3Client module so you dont have to deal with the low level networking yourself, POP3Client is available from http://www.perl.com/CPAN/modules/by-module/Mail/POP3Client-1_15.tar.gz
0
 
LVL 2

Expert Comment

by:mlev
ID: 1207906
Or to deal with EOF and blank lines:
while ($reply=<SOCKET>) {
 last if $reply eq ".\r\n";
 next unless $reply =~ /(\w+)\:\s(.*)/;
 ...
0
 
LVL 84

Expert Comment

by:ozo
ID: 1207907
\d+ matches digits.  Not many digins in "Date:"
and the only way you're going to get == is with "0"

perl -dwe 1
  DB<1> while( <> =~ /(\d+):(\d+)/ ){ print "($1):($2)\n" }
Date: Friday, June 19 1998 - 12:51PM PDT
(12):(51)
Date: Friday, June 19 1998 - 01:07PM PDT
(01):(07)
From: thornbush

  DB<2>
0
 
LVL 84

Expert Comment

by:ozo
ID: 1207908
perl -Mdiagnostics -ce 'while ( $reply= < SOCKET > ) {}'
Value of glob construct can be "0"; test with defined() at -e line 1 (#1)
   
    (W) In a conditional expression, you used <HANDLE>, <*> (glob), each(),
    or readdir() as a boolean value.  Each of these constructs can return a
    value of "0"; that would make the conditional expression false, which is
    probably not what you intended.  When using these constructs in conditional
    expressions, test their values with the defined operator.


#Or just
  while( <SOCKET> ){ next unless /(\w+:)(.*)/;
#would allow
  if( $1 eq "Date:" ){ $msg_date = $2; }
#to work.

#for a case insensitive check
  $msg_date = $2 if( lc($1) eq lc("Date:") );

#or in RoboBob's version
  if( $label =~ /^Date/i ){ $msg_date = $value; }
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
I have been pestered over the years to produce and distribute regular data extracts, and often the request have explicitly requested the data be emailed as an Excel attachement; specifically Excel, as it appears: CSV files confuse (no Red or Green h…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Six Sigma Control Plans

617 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question