http://www.perlmonks.org?node_id=679164

hecroce has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks: I'm trying to do some parsing of bounced email messages. I'm using qmail as MTA (although I think this should not be relevant). My approach is to traverse the directories with File::Find and the callback function would take care of the rest.
my $directory = '/home/vpopmail/domains/somedomain.net'; opendir DH, $directory or die $!; my @users = grep {!/^\.+/ && !/\.bak$/ && !/postmaster/} readdir DH; closedir DH; $_ = "$directory/$_" for @users; find (\&process_file, @users); sub process_file { return if -d; my $full_name="$File::Find::dir/$_"; my $cmd_res=`file $full_name`; return unless $cmd_res =~ /smtp mail text$/; open K, "<$full_name" or die $!; #my @safe_file_copy=<K>; #my $file_content=join("\n",<K>); #@safe_file_copy); #print $file_content; # ............ #my $bounce = eval { Mail::DeliveryStatus::BounceParser->new($file +_content); }; my $bounce = eval { Mail::DeliveryStatus::BounceParser->new(\*K); +}; if ($bounce->is_bounce) { for my $report ( $bounce->reports() ) { print "email: ".$report->get('email')."\n"; print "reason: ".$report->get('std_reason')."\n"; } } else { print "Does not look like a bounced msg!\n"; } close K; }
After a few attempts to use my own regexps, etc I found that this module Mail::DeliveryStatus::BounceParser; could save me some work, and if fact, everything goes ok until i try to do anything (see commented lines in the callback function) with the file handle before passing it to the constructor of Mail::DeliveryStatus::BounceParser. Any help will be highly appreciated

Replies are listed 'Best First'.
Re: Parsing email
by olus (Curate) on Apr 09, 2008 at 09:29 UTC

    Just guessing, but maybe Mail::DeliveryStatus::BounceParser wants the handle positioned at the beginning of the file, and that is not so after you read its contents into @safe_file_copy. Try using seek to reposition the filehandle back to the beginning.

    seek K, 0, 0;
      Thank you olus, that was the reason, as soon as i added that line everything worked as expected.
Re: Parsing email
by CountZero (Bishop) on Apr 09, 2008 at 09:36 UTC
    Just a wild guess: what happens if you open the file with a lexical variable to hold the filehandle and pass that variable to the constructor?

    open my $bounced_message, '<', $full_name" or die $!; ... my $bounce = eval { Mail::DeliveryStatus::BounceParser->new($bounced_m +essage); +};

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: Parsing email
by samtregar (Abbot) on Apr 09, 2008 at 18:36 UTC
    You don't say what actually happens when you try to use Mail::DeliveryStatus::BounceParser after futzing with the file. How exactly does it not work? And why are you wrapping it in an eval block and ignoring any errors it throws? Try adding this after your call to new():

    warn "Call to new failed: $@" if $@;

    Then tell us what it says - quite likely it will contain a description of the problem!

    -sam

      Well, it just appeared as there was no information to process, no error but no output either. The solution was to position the filehandle at the beginning as indicated by olus