Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Help with IO::Scalar and piping

by jakev383 (Initiate)
on Sep 26, 2009 at 17:46 UTC ( [id://797712]=perlquestion: print w/replies, xml ) Need Help??

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

I am trying to write an "email checker" and perform some checks against the message being sent. I'm getting hung up on getting the message into Mail::DKIM::verifier though. Here is the loading part of my script:
# slurp the email from STDIN my( $raw ); { local $/ = undef; local *FILE; open FILE, "-"; $raw = <FILE>; close +FILE } defined( $raw ) or die( "Nothing read from STDIN!\n" ); # Create an IO::Handle for Mail::DKIM::Verifier to read message from my( $raw_iohandle ) = new IO::Scalar( \$raw ); # Read from the IO::Handle my( $mail ) = load Mail::DKIM::Verifier->new(); $mail->load( \$raw_iohandle ); $mail->CLOSE; # Import message to Email::Simple my( $incoming ) = Email::Simple->new( \$raw );
And I get this error:
Use_of_uninitialized_value_in_<HANDLE>_at_/usr/lib/perl5/site_perl/5.8 +.8/Mail/DKIM/Common.pm_line_87./readline()_on_unopened_filehandle_at_ +/usr/lib/perl5/site_perl/5.8.8/Mail/DKIM/Common.pm_line_87./Can't_use +_string_("Mail::DKIM::Verifier")_as_a_HASH_ref_while_"strict_refs"_in +_use_at_/usr/lib/perl5/site_perl/5.8.8/Mail/DKIM/MessageParser.pm_lin +e_88./
It's almost painfully obvious that I am trying to get the message into $mail incorrectly, but I do not see what I am doing wrong. Can someone show (and explain!) what I am doing wrong?

Replies are listed 'Best First'.
Re: Help with IO::Scalar and piping
by Corion (Patriarch) on Sep 26, 2009 at 17:50 UTC

    Shouldn't that be the following?

    my( $mail ) = Mail::DKIM::Verifier->new(); $mail->load( $raw_iohandle );

    Because

    my( $mail ) = load Mail::DKIM::Verifier->new();

    is the same as

    my( $mail ) = Mail::DKIM::Verifier->load->new();

    which passes no handle and no object to the load function.

      Thanks. I figured I was piping it incorrectly. When you explained it I can see where I made my mistake. It is still either being interpreted incorrectly or I am really off somewhere as I cannnot get Mail::DKIM::Verifier to provide results as defined in the example. Here is my full code:
      #!/usr/bin/perl use strict; use warnings; use Data::Dumper; use Email::Simple; use Email::Simple::Creator; use Email::Send; use IO::Scalar; use Mail::DKIM::Verifier; use constant SENDER => 'test@circularbucket.com'; use constant SUBJECT => 'Email Message Report'; ## Main # slurp the email from STDIN my( $raw ); { local $/ = undef; local *FILE; open FILE, "-"; $raw = <FILE>; close +FILE } defined( $raw ) or die( "Nothing read from STDIN!" ); # Create an IO::Handle for Mail::DKIM::Verifier to read message from my( $raw_iohandle ) = new IO::Scalar( \$raw ); # Read from the IO::Handle my( $mail ) = Mail::DKIM::Verifier->new(); $mail->load( $raw_iohandle ); $mail->CLOSE; # Import message to Email::Simple my( $incoming ) = Email::Simple->new( \$raw ); ###################################################################### +################################## # Message checks ###################################################################### +################################## ############### # Are we spam? my( $XSpamStatus ) = 0; if ( $incoming->header( 'X-Spam-Status' ) =~ /^Yes.*score=([\S*])\s+/ +) { # we're spam, save the score $XSpamStatus = $1; } ############### # Check DKIM status my( $result ) = $mail->result; ############### # Gather who the message was from so we can send it back my( $from_header ) = $incoming->header("From"); ############################## # Gather spam stats from the message my $spam_stats1 = $incoming->header( 'X-Spam-Status' ); ############################## # Get SPF result from headers my( $SPFStatus ) = 0; if ( $incoming->header( 'Received-SPF' ) =~ /^pass.*/ ) { # we have a valid SPF record, so save the status $SPFStatus = 1; } ############################## # What MUA was used to send the message? my $user_agent = $incoming->header( 'User-Agent' ); ###################################################################### +#################################### # Generate the message to be sent back ###################################################################### +#################################### my( $body ) = <<BODY; This is a test message. The test results will follow below. ----------------------------------------------------------- BODY if ( $XSpamStatus ) { $body .= "Message was scored as spam, with a score of $XSpamStatus +\n"; } else { $body .= "Message was not scored as spam.\n"; } if ( $result ) { $body .= "Result1 was: $result\n"; } else { $body .= "Result2 was: $result\n"; } $body .= "Return path was: $from_header\n"; $body .= "Original test request was sent using: $user_agent\n"; if ( $SPFStatus ) { $body .= "\n\nSPF Record: PASS\n"; } else { $body .= "\n\nSPF Record: FAIL\n"; } foreach my $signature ($mail->signatures) { $body .= "signature identity: $signature->identity . \n"; $body .= "verify result: $signature->result_detail . \n"; } my( $outgoing ) = Email::Simple->create( header => [ From => SENDER, To => $from_header, Subject => SUBJECT, ], body => $body, ); $outgoing->header_set( 'X-Processor' => 'email test script' ); ###################################################################### +#################################### # Send the message back to the original sender ###################################################################### +#################################### my( $sender ) = Email::Send->new; $sender->send( $outgoing );
      Any nudges in the right direction are appreciated!

        As you don't tell where exactly you get the errors, it's kinda hard to guess what might be going wrong.

        • Standard input is already opened for your as STDIN, so
          # slurp the email from STDIN my( $raw ); { local $/ = undef; local *FILE; open FILE, "-"; $raw = <FILE>; close +FILE }
          is an overly complex way of doing
          # slurp the email from STDIN my $raw; { local $/; $raw = <STDIN>; }
        • Why are you forcing a list assignment?

          my( $raw_iohandle ) = new IO::Scalar( \$raw );
          should be
          my $raw_iohandle = new IO::Scalar( \$raw );

          But then again, IO::Scalar is not nearly as robust as the native support for scalar handles added to 5.8

          open(my $raw_iohandle, '<', \$raw );
        • Finally, if the module expects a system file handle (e.g. if it attempts a child process to read from it), it'll be disappointed by your attempts since none of the Perl file handles you are producing have a system file handle associated with it.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://797712]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (2)
As of 2024-04-19 01:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found