tags:

views:

169

answers:

4

Edited

Now my code is like this:

#!/usr/bin/perl

# import packages
use Net::POP3;
use Getopt::Long;
use Mail::Message;
use strict;
use warnings;

# read command line options
# display usage message in case of error
GetOptions ('h|host=s' => \$host,
            'u|user=s' => \$user,
            'p|pass=s' => \$pass) or die("Input error. Try calling me with: -h <host> -u <username> -p <password>");

# file operations
open($email_file, ">>", "Mail.txt");

# initiate connection
# default timeout = 120 sec
$conn = Net::POP3->new($host) or die("ERROR: Unable to connect.\n");

# login
$numMsg = $conn->login($user, $pass) or die("ERROR: Unable to login.\n");

# get message numbers
# iterate over list and print first 20 lines of each
if ($numMsg > 0) {
    $msgList = $conn->list();
    foreach $msg (keys(%$msgList)) {
        $rawdata = $conn->get($msg);
        my $msg_obj = Mail::Message->read($rawdata);
        my $body = $msg_obj->body;
        print $email_file @body;
        print $email_file "\n====================================================\n";
    }
} else {
    print "Mailbox is empty.\n";   
}

# close connection
$conn->quit();
close($email_file);

But when i try to execute it i'm getting this:

[ubuntu@eeepc:~/Desktop/mail] ./get.pl -h pop.vix.terra.com.br -u nathanpc -p secret
Global symbol "$host" requires explicit package name at ./get.pl line 12.
Global symbol "$user" requires explicit package name at ./get.pl line 13.
Global symbol "$pass" requires explicit package name at ./get.pl line 14.
Global symbol "$email_file" requires explicit package name at ./get.pl line 17.
Global symbol "$conn" requires explicit package name at ./get.pl line 21.
Global symbol "$host" requires explicit package name at ./get.pl line 21.
Global symbol "$numMsg" requires explicit package name at ./get.pl line 24.
Global symbol "$conn" requires explicit package name at ./get.pl line 24.
Global symbol "$user" requires explicit package name at ./get.pl line 24.
Global symbol "$pass" requires explicit package name at ./get.pl line 24.
Global symbol "$numMsg" requires explicit package name at ./get.pl line 28.
Global symbol "$msgList" requires explicit package name at ./get.pl line 29.
Global symbol "$conn" requires explicit package name at ./get.pl line 29.
Global symbol "$msg" requires explicit package name at ./get.pl line 30.
Global symbol "$msgList" requires explicit package name at ./get.pl line 30.
Global symbol "$rawdata" requires explicit package name at ./get.pl line 31.
Global symbol "$conn" requires explicit package name at ./get.pl line 31.
Global symbol "$msg" requires explicit package name at ./get.pl line 31.
Global symbol "$rawdata" requires explicit package name at ./get.pl line 32.
Global symbol "$email_file" requires explicit package name at ./get.pl line 34.
Global symbol "@body" requires explicit package name at ./get.pl line 34.
Global symbol "$email_file" requires explicit package name at ./get.pl line 35.
Global symbol "$conn" requires explicit package name at ./get.pl line 42.
Global symbol "$email_file" requires explicit package name at ./get.pl line 43.
Execution of ./get.pl aborted due to compilation errors.
[ubuntu@eeepc:~/Desktop/mail]


Original

Hello,

I'm learning Perl and at the same time doing a home made project that i will use it to events of my family, but when i used Mail::Message to get only the body of the eMails i'm getting nothing. See my code:

#!/usr/bin/perl

# import packages
use Net::POP3;
use Getopt::Long;
use Mail::Message;

# read command line options
# display usage message in case of error
GetOptions ('h|host=s' => \$host,
            'u|user=s' => \$user,
            'p|pass=s' => \$pass) or die("Input error. Try calling me with: -h <host> -u <username> -p <password>");

# file operations
open(file, ">>", "Mail.txt");

# initiate connection
# default timeout = 120 sec
$conn = Net::POP3->new($host) or die("ERROR: Unable to connect.\n");

# login
$numMsg = $conn->login($user, $pass) or die("ERROR: Unable to login.\n");

# get message numbers
# iterate over list and print first 20 lines of each
if ($numMsg > 0) {
    $msgList = $conn->list();
    foreach $msg (keys(%$msgList)) {
        my $msg_obj = Mail::Message::->read($rawdata);
        my $body = $msg_obj->body;
        print file @body;
        print file "\n====================================================\n";
    }
} else {
    print "Mailbox is empty.\n";   
}

# close connection
$conn->quit();
close(file);

And the file that i'm using to store the eMails:

====================================================

====================================================

====================================================

What i'm doing wrong? Thanks.

+2  A: 

Where does $rawdata come from? Did you forget to say something like

    $rawdata = $conn->get($msg);

?

use strict and use warnings at the top of your script might have helped you to catch this.

mobrule
I got the same thing.
Nathan Campos
Why don't you use strict and use warnings, fix your code, and update the code sample in your question? I'm no expert on Mail::Message, but I am an expert at creating bugs by using uninitialized variables ;)
mobrule
+2  A: 

There's nothing in $raw_data because you never assign to it.

There's nothing in @body (an array variable). You put things in $body (a scalar variable).

These are the sorts of problems that use strict finds for you. :)

brian d foy
`use strict` and `use warnings` until you understand why you are using them. Then keep using them.
mobrule
+1  A: 

I am not familiar with this module. What does Mail::Message::->read do?

Sinan Ünür
A: 

All the messages of the form:

Global symbol "$host" requires explicit package name at ./get.pl line 12.

Come from the fact that you enabled strict variables with use strict, which requires you to declare variables before you use them.

Try adding use diagnostics to get expanded explanations for error messages.

You can also run splain to explain error messages. Run you script and capture stderr into a file get.pl 2> errors then run splain errors.

For your error splain says:

Global symbol "$host" requires explicit package name at ./get.pl line 12 (#1) (F) You've said "use strict vars", which indicates that all variables must either be lexically scoped (using "my"), declared beforehand using "our", or explicitly qualified to say which package the global variable is in (using "::").

Check out perldoc strict, perldoc warnings, perldoc perllexwarn, and finally perldoc -f my.

The first bit of your script (after all the use statements) fixed:

# read command line options
# display usage message in case of error

# predeclaring all variables with `my`
my $host = 'localhost';  # you can set default values for Getopt::Long this way. 
my $user;
my $pass;

GetOptions ('h|host=s' => \$host,
            'u|user=s' => \$user,
            'p|pass=s' => \$pass,
) or die("Input error. Try calling me with: -h <host> -u <username> -p <password>");
daotoad