Reputation: 1232
I'm having some trouble with Net::SMTP when used in a for loop. The first iteration works, but on the second iteration the script dies with Can't call method "mail" on an undefined value at..., the line referred to being
$smtp->mail('[email protected]'); #from.
Any ideas?! Thanks for your time!
use strict;
use warnings;
use Net::SMTP;
my $smtp;
#@data is defined and populated somewhere
foreach my $line (@data) {
my @linearray = split /,/, $line;
my $host = $linearray[2];
$host =~ s/\r|\n//g;
next unless ($host =~ m/([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3}).([0-9]{1,3})/); # skip if it's not an IP (i.e. it's the header row)
print "Connecting to $host...";
# create object
$smtp = Net::SMTP->new(
Hello => 'hacker.net',
Timeout => 3,
Host => $host,
Debug => 1,
);
$smtp->mail('[email protected]'); #from
my $tocheck = $smtp->recipient('[email protected]'); #to
if ($tocheck == 0) {
print "$host is NOT an open relay\n";
#$smtp->quit;
next;
}
$smtp->data();
$smtp->datasend("Test\n");
$smtp->datasend("\n");
$smtp->datasend("A simple test message\n");
$smtp->dataend();
$smtp->quit;
}
Upvotes: 0
Views: 496
Reputation: 1232
Resolved. Tail slightly between the legs on this one. It turns out that the list of IPs given to me had already been contacted about the issue and therefore some has started putting measures in place to fix the problem. One such measure was blocking TCP port 25 with a source IP different to a trusted relay (not my IP just to clarify). Therefore creation of the Net::SMTP was simply failing. So reintroduction of the block suggested by Borodin (which I'd removed while trying to debug this issue) fixed it all up. Thanks for your help guys - much appreciated.
Upvotes: 0
Reputation: 126742
I would guess that your $host
doesn't hold a valid SMTP server address. The regex checks only whether it contains something that may be a valid IP address somewhere. 999.999.999.999
isn't valid, for instance. Also whitespace will probably break things, so ' 127.0.0.1 '
won't work either. Finally there may be no working SMTP server at that address, even if it is a legal IP address so your contructor may fail anyway.
This alternative regex checks that the entire string matches a valid IP address with only 0..255 values in each field.
/\A(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\z/
You should check the return value of the constructor and warn if it has failed:
$smtp = Net::SMTP->new(
Hello => 'hacker.net',
Timeout => 3,
Host => $host,
Debug => 1,
);
unless ($smtp) {
warn "Unable to connect to to SMTP server '$host'";
next;
}
Upvotes: 1