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

I am writing a web based email app. I have everything working except the part about filtering MIME parts and attachments. I have figured out how to use MIME::Entity to send a message with an attachment (thanks to earlier posts) but I haven't figured out how to receive an email with MIME parts and attachments. If you have a good example I would greatly appreciate it. I found tons of examples on sending attachments.

-- rogueFalcon
Why do you people insist on doing things sdrawkcab?

Replies are listed 'Best First'.
Re: Receiving an email attachment
by perldoc (Scribe) on Jul 12, 2001 at 04:08 UTC
    #!/usr/bin/perl -w ###################################################################### +######## ## -*-perl-*- ## ## metamail - My slightly more secure metamail workalike. ## ## Courtesy of Gerard's Perl Page, ## http://www.geocities.com/gerardlanois/perl/ ## REVISION HISTORY ## ## version 1.0 2001/07/12 gerard@lanois.com - Initial release. ## version 1.1 2002/01/31 gerard@lanois.com - parts_DFS instead of r +ecursion ###################################################################### +######## use strict; use MIME::Parser; use File::Path; use File::Copy; use File::Basename; sub yesno($) { my $question = shift; print $question, " (y/n) [n]: "; my $key = <STDIN>; print "\n"; return $key =~ /^y/i; } my $tempdir = "metamail-tmp"; (-d $tempdir) or mkdir $tempdir,0755 or die "mkdir: $!"; (-w $tempdir) or die "can't write to directory"; my $parser = MIME::Parser->new; $parser->output_dir($tempdir); $parser->extract_uuencode(1); defined $ARGV[0] or die "usage: metamail filename\n"; my $entity = $parser->parse_open($ARGV[0]) or die "couldn't parse file "; my $head = MIME::Head->from_file($ARGV[0]); my @hdrs = qw( Subject Reply-to From ); foreach (@hdrs) { my $header = $head->get($_); if (defined $header) { chomp $header; print " $_:", $header, "\n"; } } $entity->dump_skeleton(\*STDOUT); print "-"x40, "\n"; foreach my $part ($entity->parts_DFS) { # Process only those entities which have bodies. next if (!$part->bodyhandle); # If there are evil chars in the bodyhandle path, then MIME::Parse +r # will choke and give a null file name, but the recommended # file name will always have the file name, evil characters # included. my $filename = $part->head->recommended_filename; if (!$filename) { $filename = $part->bodyhandle->path; } fileparse_set_fstype("MSWin32") if ($^O =~/MSWin32/); my ($file, $dir, $ext) = fileparse($filename, '\.[^.]*'); if (yesno("\n\n".$file.$ext." - want it?")) { if ((!-f "./".$file.$ext) || (-f "./".$file.$ext && (yesno("File exists, overwrite?"))) +) { move($part->bodyhandle->path, $file.$ext) ; print "Saved ", $file.$ext, "\n"; } } } $parser->filer->purge; rmtree $tempdir;
Re: Receiving an email attachment
by tachyon (Chancellor) on Jul 12, 2001 at 02:28 UTC

    Hi, MIME::Entity is part of MIME::Tools. Another part of MIME::Tools is MIME::Parser which will probably do what you want and better still you are likely to already have this module installed. You can read the docs here http://search.cpan.org/doc/ERYQ/MIME-tools-5.411/lib/MIME/Tools.pm

    Got to sleep now, but I'll see if I can dig out an example for you later.

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: Receiving an email attachment
by runrig (Abbot) on Jul 12, 2001 at 03:34 UTC
    <shameless plug> If you're ever unfortunate enough to receive TNEF attachments (and the sender is too clueless to stop it), take a look at Convert::TNEF. There's also an example there in the perldocs for reading from a POP3 server and parsing MIME and TNEF attachments.</shameless plug>
Re: Receiving an email attachment
by rogueFalcon (Beadle) on Jul 12, 2001 at 19:33 UTC
    I ran the code that you posted but I can only get it to take a mime message and write a txt file with the same exact content. What am I doing wrong. I am pasting the test message below that I am passing it. It has text, html, and an attachment sent from netscape messenger. The function isn't recursing. $entity->parts always equals 0 Thanks for your help.

    This is a multi-part message in MIME format.
    --------------B8A046EFF7EDB5DE9549664F
    Content-Type: multipart/alternative;
    boundary="------------12FC523FDAD8D46FC3E99678"


    --------------12FC523FDAD8D46FC3E99678
    Content-Type: text/plain; charset=us-ascii
    Content-Transfer-Encoding: 7bit

    this is a test of the attachment functionality.



    --
    Thanks,
    Kenny



    --------------12FC523FDAD8D46FC3E99678
    Content-Type: text/html; charset=us-ascii
    Content-Transfer-Encoding: 7bit

    <!doctype html public "-//w3c//dtd html 4.0 transitional//en">
    <html>
    this is a test of the attachment functionality.
    <br>
    <br>
    <pre>--
    Thanks,
    Kenny

    </html>

    --------------12FC523FDAD8D46FC3E99678--

    --------------B8A046EFF7EDB5DE9549664F
    Content-Type: application/x-gzip;
    name="investing.tar.gz"
    Content-Transfer-Encoding: base64
    Content-Disposition: inline;
    filename="investing.tar.gz"

    H4sICDprSzsAA2ludmVzdGluZy50YXIA7dLBisIwEAbgXO1TzGEPekiZSWNjBR8mi6kURaWN
    wr79puKW3YWiHkSE/7sMZH4mgUyzP4cuNvuNeh4W5rK0ihPn5E/tWS4Vu4KdOGf6czHWFor4
    iW8anLroWyJ1/PIxbsdzt/pvSkRLqU36BdJk5vmlfpi8qmgaW78OVIcwy9hosX1MUnvOozGr
    ufiJjU/LVnfJ4iH6HTWXFQ1r+gz1oQ00DFpSWqx0x/+cr2Nof8eokpwLuuaGRrecTGiRVy57
    9S8AAAAAAAAAAAAAAAAAAAAAAAA87huu6CnZACgAAA==
    --------------B8A046EFF7EDB5DE9549664F--

    -- rogueFalcon

    Why do you people insist on doing things sdrawkcab?

      You have to provide the entire message, including ALL the headers, not just the message body. MIME::Parser needs all of it. I got burned on this very badly myself the first time I tried to use MIME::Parser.
        Thank you! Thank you! Thank you!

        That was the ticket... You are now my hero :-)

        -- rogueFalcon

        Why do you people insist on doing things sdrawkcab?