As one who has used php (without classes) but has seen cpan in operation
(I'd describe it as connecting to the internet from the c: prompt, if using
Windows) and it's impressive though complicated, only the documentation is a
bit flat on perl and beginners lists require you to have memorised Learning
Perl to understand the answers...  I got flamed for mentioning php on a perl
beginners list, so I hope php people are not so religious. Though this is
about perl it is a php-background web person trying to understand it.

> The one used here is Mail::DeliveryStatus::BounceParser.

Where does the perl module reside on the server?  I have my home space, so I
have seen modules attempting to download onto my computer but would not know
about doing it on my host server.  Perhaps it is preinstalled on the server
(a standard module) or I just need to contact my host provider.

> Once we set up the script to use the module with

This I understand - the below lines are written in a plain text file and
saved as a .pl file.

>  ### basic setup      ## {{{
>  use strict ;                                         # watch your
>  use warnings ;                                               # only
slightly kinder
>  use DBI ;                                            # talking to a
>  use DBD::mysql ;                                     # what kind of
>  use Mail::DeliveryStatus::BounceParser ;             # parsing magic
>  ## }}}

> catching the mail is literally as easy as

>  ### catch the input  ## {{{
>  my $bounce = eval { Mail::DeliveryStatus::BounceParser->new ( \*STDIN ) }
>  if ( $@ )
>  {
>    print "Whoa -- one we actually couldn't handle!\n" ;
>    exit 255 ;
>  }    ## }}}

Sorry, lost.  What wakes up this file to notice that an email has bounced
and execute the second line?  Is it its location on the server?  How does it
realise it has some input, STDIN, to look at?  (Is there a similar concept
to STDIN in php?)

> and then, once we make the DB connection, handling the message is also as
> easy as

>   ### loop thru the message   ## {{{
>   foreach my $report ( $bounce->reports )                     # loop thru
reports for each addr in the bounce
>  {
>     ### I'd love to grab the *current* M-ID: here...  maybe someday
>   my $orig_mid = $bounce->orig_message_id;            # 
>    my $email = $report->get('email') ;                        # bouncing
>    my $std_reason = $report->get('std_reason') ;              # why
>    my $reason = $report->get('reason') ;                      # other why
>    my $date = $report->get('arrival-date') ;          # bounce date
>    my ($sec,$min,$hour,$mday,$mon,$year) = localtime ; $year += 1900 ;
$mon++ ;
>    $date = $date ? $date : "$year-$mon-$mday ${hour}:${min}:$sec" ;   # be
sure we have a date
>    $ur->execute($email) ;                             # update user record
>    $br->execute($email,$std_reason,$reason,$orig_mid,$date) ; # update
bounce log
>  }    ## foreach(@reports)    ## }}}

> and we're done!  The hardest part was figuring out that I had to loop
> through $bounce->reports because it wasn't clear in the man page for the
> module *blush*.

For those new to perl, I got as far as and couldn't find the man
page for the module.  (I've never been lost in  The fact that
$bounce->reports gives a $report would be because the object $bounce from: 
 my $bounce = eval { Mail::DeliveryStatus::BounceParser->new ( \*STDIN ) } ;

has a 'report' method defined in the module.  The module documentation
should tell us what this report contains, but it must contain text with the
bounce report (obviously) including the email address which has bounced.
The line:

 my $email = $report->get('email') ;

would then be using a method 'get' as defined in the module to get the email
address, the argument 'email' must be defined in the module as the email
address...same with 'std_reason' etc.

execute (as in $ur->execute($email) ;) would work as a method of the module
we are using because of the syntax '->execute' which I suppose perl sees as
a method call.  The module will define what happens when we do this.  What
does 'update user record' mean? - this is the db bit - I realise this is a
loop, is the variable $br accummulating something, why is it redefined below
in 'my $br = $eteam->prepare($b) ;'?  Why are we connecting to the db after
the 'execute' if it is updating the db?

> Back, for a moment, to the DB connection...  perl lets you set up or
> "prepare" multiple connections and queries in advance, and then you just
> feed one the data for that iteration and off you go.  That's what $ur and
> $br are above, and the connection piece that I glossed over looks like

>  ### make DB connection       ## {{{
>  my $drh = DBI->install_driver("mysql")                       # talking

Here I see we are using a module DBI to 'talk sql from here on'... and
indeed you have specified 'use DBI' above.  Understood.  (Equivalent in php
to use of a 'mysql' type function.)

>    or die("Cannot install mysql driver!\n") ;
>  my $eteam = $drh->connect("##DBNAME","##DBACCT","##DBPASS",{AutoCommit =>
1})     # hook up
>    or die("Cannot connect to database server!\n") ;

>  ### prepare query
>  my $u = "update eteam.USER set FLAG_CONFIRM = 2 where EMAIL = ?" ;   #
user status query
>  my $b = "insert into eteam.MAIL_BOUNCE values (?,?,?,?,?)" ; # bounce
mail log query
>  my $ur = $eteam->prepare($u) ;                               # prepare
query (user)
>  my $br = $eteam->prepare($b) ;                               # prepare
query (bounce)
>  ## }}}

> where the '?' is a placeholder for the values you'll provide at execution
> time.  

and how do we provide values at execution time?

> This, IMHO, is a pretty slick feature; it essentially turns your
> query string + resource connection into a function that accepts your
> varying input and then executes the call.

> So there you have it...  This perl script is only 58 lines long and
> handles just about every sort of bounce known to man and then goes and
> updates two DB tables with the info it pulls out.  

OK.  (58 lines does not translate into thinking time though.)

> It's called from the
> apparent sender's .qmail (like .forward) file, which also dumps a copy of
> the message onto a mail spool for us to review if we ever need to.

.qmail, .forward file, mail spool are unfamiliar concepts I haven't seen.
can I see touch and smell these things?  The above is a plain text .pl file
on a server
with perl installed (as my shared host provider has)...just trying to


> :-D


> -- 
> David T-G                      * There is too much animal courage in 
> (play) [EMAIL PROTECTED] * society and not sufficient moral courage.
> (work) [EMAIL PROTECTED]  -- Mary Baker Eddy, "Science and
>      Shpx gur Pbzzhavpngvbaf Qrprapl Npg!


CONFIDENTIAL: This e-mail, including its contents and attachments, if any, are 
confidential. If you are not the named recipient please notify the sender and 
immediately delete it. You may not disseminate, distribute, or forward this e-mail 
message or disclose its contents to anybody else. Copyright and any other intellectual 
property rights in its contents are the sole property of Cantor Fitzgerald.
     E-mail transmission cannot be guaranteed to be secure or error-free. The sender 
therefore does not accept liability for any errors or omissions in the contents of 
this message which arise as a result of e-mail transmission.  If verification is 
required please request a hard-copy version.
     Although we routinely screen for viruses, addressees should check this e-mail and 
any attachments for viruses. We make no representation or warranty as to the absence 
of viruses in this e-mail or any attachments. Please note that to ensure regulatory 
compliance and for the protection of our customers and business, we may monitor and 
read e-mails sent to and from our server(s). 

For further important information, please read the  Important Legal Information and 
Legal Statement at

PHP Database Mailing List (
To unsubscribe, visit:

Reply via email to