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

Fellow Monasterians,

I've had good success using Mail::Sendmail when just sending simple text e-mails. I want to expand my working knowledge to sending attachments. I found some helpful code at Mail::Sendmail FAQs, but frankly, I don't understand everything I'm seeing there.

My confusion starts at:

$file = $^X; open (F, $file) or die "Cannot read $file: $!"; binmode F; undef $/; $mail{body} = encode_base64(<F>); close F;

I don't get the $^X even after perusing perlvar. Or what happens in the open (F, $file).. line and the 3 lines that follow.

Can someone walk me through exactly what happens here, so I can figure out where and how to get the file attached. Do I upload it to the server first? How does this code know what file to attach? Thanks in advance.


—Brad
"The important work of moving the world forward does not wait to be done by perfect men." George Eliot

Replies are listed 'Best First'.
Re: Wisdom sought re:mail:sendmail attachments
by hsinclai (Deacon) on Jan 24, 2005 at 04:29 UTC
    That example you point to appears to be a complete script, but is not.. you have to devise a way to get your desired attachment into $file, and also devise a way to attach more than one file...

    About $file = $^X; it appears the author just picked a random file to assign to $file for this particular example, so why not pick the perl executable itself, and hey why not use one of the builtin shorthands instead of typing "/usr/bin/perl".. Trés Geeky, non?

    So to follow on the rest of this block:
    open (F, $file) or die "Cannot read $file: $!"; binmode F; undef $/; $mail{body} = encode_base64(<F>); close F;
    - Open $file for reading, with handle F.

    - Treat it as a binary file (we know it probably wil not contain line ending characters), intending the attachment to be encoded as one input stream.

    - Remove the normal assignment of the input record separator $/ (usually newline), this input won't need it. IMO that should be done within a sub, since it's never reset when the operation there finishes..

    -The hash %mail already exists, assign new element "body" to contain the base64 encoded stream of $file.

    There are a few Perl modules usable to create file attachments .. I keep recommending Mail::SendEasy because it is so simple and cool.. no dependencies, it takes about 3 minutes to learn what it does and be up and running...

    -Harold
Re: Wisdom sought re:mail:sendmail attachments
by YetAnotherDave (Beadle) on Jan 24, 2005 at 04:07 UTC
    the code from the FAQ works for me, but it's a bit messy.

    I'd think they should have used $file everywhere after they set it, instead of using $^X all over the place...

    $^X gives the full path to the perl executable, so that's what's attached...

    in the sample, from line 25 on, s/$^X/$file/ - then set file to whatever you want to attach and you're off to the races...

      Thanks YetAnotherDave. To clarify: I need to have the attachment uploaded to the web host already, right? That I do with traditional means.


      —Brad
      "The important work of moving the world forward does not wait to be done by perfect men." George Eliot
        yes, this just takes a file directly from the machine the script works on.

        note that the file as named in the attachment has nothing to do with the name of the file as you read it, so you can use mktemp (see File::Temp) to generate a temp file without penalty.

Re: Wisdom sought re:mail:sendmail attachments
by greenFox (Vicar) on Jan 24, 2005 at 06:27 UTC

    You may want to also take a look on CPAN for modules which will do this for you, I happen to like Mime::Lite.

    --
    Do not seek to follow in the footsteps of the wise. Seek what they sought. -Basho