Beefy Boxes and Bandwidth Generously Provided by pair Networks Bob
good chemistry is complicated,
and a little bit messy-LW
 
PerlMonks

Trapping server responses with Net::SMTP

by fivefiftyone (Acolyte)
 | Log in | Create a new user | The Monastery Gates | Super Search | 
 | Seekers of Perl Wisdom | Meditations | PerlMonks Discussion | 
 | Obfuscation | Reviews | Cool Uses For Perl | Perl News | Q&A | Tutorials | 
 | Poetry | Recent Threads | Newest Nodes | Donate | What's New | 

on Oct 21, 2008 at 17:59 UTC ( #718552=perlmeditation: print w/ replies, xml ) Need Help??

I work for an ISP, managing a large number of mail servers dedicated to combating spam and providing content filtering solutions to our customers. During the course of an average day, I field numerous queries regarding the inner workings of mail servers from our support desk guys.

I decided to combat this by writing a Perl script which uses Net::SMTP to talk to mail servers, and spit out human readable text in place of gibberish like EXPN, VRFY and that absolute monster, SIZE, and convert RFC1893 documented errors into language that our techs can forward to customers. About 10 minutes into development, I realised that this is a project doomed to failure, but figured that playing with it would be a fun Perl learning curve anyway. A major plus in all this was that it answered a major issue I've had with writing mail scripts for a long while now.

Something that has always bugged me about Net::SMTP is the fact that I could never find a way of proactively trapping the response codes from the servers. It turns out that months of writing SMTP orientated scripts, and months of setting Debug => 1 were in vain, as the answer lay in two methods provided by Net::SMTP's parent, Net::Cmd. My butt still hurts from the vigorous kicking I administered myself after finding these:
Net::Cmd->code() Net::Cmd->message()
Yup. It's that easy. Let's take a look in context:
# Create ourselves an SMTP object my $smtp = Net::SMTP->new( Host => 'some.mailserver.de', Hello => 'my.mailserver.co.za', Timeout => 30, Debug => 0); # Talk to the server $smtp->mail("postmaster\@mailserver.co.za", Size => 20971520) or die "Oops. Server said ", $smtp->code(), " ", $smtp->message(); $smtp->to("youthere\@mailserver.de") or die "Error on RCPT TO: ", $smtp->code(), " ", $smtp->message(); $smtp->quit;
That will ensure that if an error occurs, the script will die and print out the offending error code, instead of blithely continuing as Net::SMTP normally would.

Considering my original objective, you wouldn't necessarily want to kill off the script as the error code is returned, but search for an error, and produce a pretty line explaining what had gone wrong. You'd be most interested in 4.x.x and 5.x.x errors, so you could roll out another Net::Cmd method, status():
$smtp->mail("postmaster\@mailserver.co.za", Size => 52428800); if ( $smtp->status() =~ /^[45]$/ ) { # informative error here exit(1); }
The status() method returns the first digit of the error code, allowing for a simple regex to look for an error, which you can expound upon at will. For example, I might be on the lookout for a very specific error from a specific brand of server regarding a mail size limitation:
if ( $smtp->status() =~ /^[45]$/ ) { if ( $smtp->message() eq "size limit exceeded" ) { print "Server returned a fatal error:\n"; print $smtp->code(), " ", $smtp->message(), "\n"; print "The message is too big. Boo-hoo\n"; } }
Not necessarily the best, but hey, it illustrates the point.

This, for all its simplicity, was a joy to discover. I'm continuing on my "An SMTP Script For Those Oblivious To The Existence Of RFC's And Who Are The Reason I Own A Shirt That Has RTFM Printed In Large White Letters Upon It". I ultimately fear, based the ambiguous nature of response codes that I will fail, insane, wretched and alone. Results, should I have any, will be posted here. Failing that, I trust that this little pointer helps others who turn to Net::SMTP when they need some sweet mail server interaction to brighten up their day.

Good grief, I need help! I enjoy mail waaaaaaaaay too much...

Comment on Trapping server responses with Net::SMTP
Select or Download Code
Re: Trapping server responses with Net::SMTP
by rhesa (Vicar) on Oct 21, 2008 at 21:11 UTC
    instead of
    if ( $smtp->status() =~ /^[45]$/ ) {
    you could use
    if ( ! $smtp->ok ) {
      which status value indicates success? which indicate failure (other than 4/5)? I tried $smtp->ok and it did not seem to accurately reflect success/failure.

Login:
Password
remember me
What's my password?
Create A New User

Node Status?
node history
Node Type: perlmeditation [id://718552]
Approved by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (25)
BrowserUk
GrandFather
jdporter
wfsp
johngg
atcroft
mr_mischief
kennethk
herveus
MidLifeXis
Marshall
rowdog
psini
SFLEX
jkva
ssandv
DStaal
wwe
AndyZaft
Neighbour
dxxd116
DarthWavy
graghave
ldbpm
im2
As of 2010-09-02 15:08 GMT
Sections?
Seekers of Perl Wisdom
Cool Uses for Perl
Meditations
PerlMonks Discussion
Categorized Q&A
Tutorials
Obfuscated Code
Perl Poetry
Perl News
See About the sections of PerlMonks
Information?
PerlMonks FAQ
Guide to the Monastery
What's New at PerlMonks
Voting/Experience System
Tutorials
Reviews
Library
Perl FAQs
Other Info Sources
Find Nodes?
Nodes You Wrote
Super Search
List Nodes By Users
Newest Nodes
Recently Active Threads
Selected Best Nodes
Best Nodes
Worst Nodes
Saints in our Book
Leftovers?
The St. Larry Wall Shrine
Offering Plate
Awards
Craft
Snippets Section
Code Catacombs
Quests
Editor Requests
Buy PerlMonks Gear
PerlMonks Merchandise
Planet Perl
Perlsphere
Use Perl
Perl.com
Perl 5 Wiki
Perl Jobs
Perl Mongers
Perl Directory
Perl documentation
CPAN
Random Node
Voting Booth?

My favourite poll on PerlMonks is ...

Your first Perl Book - the first one ever
Average number of caffeinated beverages per work day - the poll with the highest participation
My Thoughts on the New Voting/Experience System - the poll with the fewest votes cast
When I grow up, I want to be: - one of the polls with the fewest options
Perl 6 will primarily be: - the first one on Perl6
When I see a poll - one of the many polls about polls
this poll ;-)
yet to come
none - I hate polls. Bah.
some other

Results (49 votes), past polls