I have a postfix server which mailbox_command's into this perl script:
#!/usr/bin/perl use MIME::Parser; srand; $parser = new MIME::Parser; $foldername = time().int(rand(10)).int(rand(10)).int(rand(10)).int(ran +d(10)).int(rand(10)); mkdir("/var/smtp/my/recv/".$foldername); $parser->output_dir("/var/smtp/my/recv/".$foldername); $parser->tmp_dir("/var/smtp/tmp"); eval{$parser->parse(\*STDIN);};

It works very well, EXCEPT for mails which contain inline attachments. I need to get the CID of these attachments. It should work "unlimited" deep into the hiearchy, so even if the mail contains a another mail which contains a third mail which contains... and so on and so on it should work.

The attachments are printed with their original filenames. Is there any way to:

-either get the MIME::Parser's filename of a inline attachment with the CID (like "1290910643.25733.0.camel@sebastian-desktop", stored in a variable) converted to the filename (like "image.png").

-or get a list of all CIDs found in a mail, and with their corresponding filenames "invented" by MIME::Parser.

-or be able to input a filename created by MIME::Parser, and get it corresponding CID.

The best would be the second option, if I could get a list of all CIDs found in a MIME mail, with their corresponding filenames "created" by MIME::Parser. Note that MIME::Parser creates a file with the name + a -1 like image-1.png, if theres multiple files with the same name. This needs also to be taken in consideration.

I can then write this list into a text file placed in the mail folder for the webmail system to pick up, for it to replace the CIDs in the IMG tags with their corresponding correct paths to the images.

I also would want to get a list of the MIME content types for all the attachments which MIME::Parser writes along with their MIME::Parser filenames.

If you wonder, im building a webmail system in perl which does NOT go through the POP3, instead it goes straight from SMTP server into the webmail folder, and it is parsed and complete so the only thing the webmail system has to do is to display the mails and eventual attachments.

******************************************************************

Solved

******************************************************************

Solved it now thanks to Anonymous Monk. The script now looks like this, and it works very well:

#!/usr/bin/perl use MIME::Parser; use MIME::Base64; srand; $parser = new MIME::Parser; $foldername = time().int(rand(10)).int(rand(10)).int(rand(10)).int(ran +d(10)).int(rand(10)); mkdir("/var/smtp/my/recv/".$foldername); $parser->output_dir("/var/smtp/my/recv/".$foldername); $parser->tmp_dir("/var/smtp/tmp"); $returnentity = eval{$parser->parse(\*STDIN);}; @writetofile = dump_entity($returnentity); open(INDEXFILE, ">/var/smtp/my/recv/".$foldername."/mailindex.txt"); flock(INDEXFILE,2); print INDEXFILE @writetofile; close(INDEXFILE); sub dump_entity { my ($entity) = @_; my @filedata = (); my @parts = $entity->parts; if (@parts) { my $i; foreach $i (0 .. $#parts) { push(@filedata, dump_entity($parts[$i])); } } else { my $filepath = $entity->bodyhandle->path; $filepath =~ s/^(.*)\/([^\/]*)$/$2/si; $filepath = encode_base64($filepath); $filepath =~ s/\n//sgi; $filepath =~ s/\r//sgi; $filepath =~ s/\t//sgi; my $fileid = encode_base64($entity->head->get('content-id')); $fileid =~ s/\n//sgi; $fileid =~ s/\r//sgi; $fileid =~ s/\t//sgi; my $filetype = encode_base64($entity->head->mime_type); $filetype =~ s/\n//sgi; $filetype =~ s/\r//sgi; $filetype =~ s/\t//sgi; push(@filedata, $filepath."::".$fileid."::".$filetype."\n"); } return @filedata; }

I get the attachments as binary files in $foldername, a convient file called mailindex.txt in the $foldername with the following content:

bXNnLTMyNTUwLTEudHh0::::dGV4dC9wbGFpbg== bXNnLTMyNTUwLTIuaHRtbA==::::dGV4dC9odG1s Ym90LnBuZw==::PDEyOTA5ODUxNTMuMzIxNDMuMC5jYW1lbEBzZWJhc3RpYW4tZGVza3Rv +cD4K::aW1hZ2UvcG5n
Decoded:
msg-32550-1.txt :: :: text/plain msg-32550-2.html :: :: text/html bot.png :: <1290985153.32143.0.camel@sebastian-desktop> :: image/png
msg-32550-2.html looks like this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN"> <HTML> <HEAD> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8"> <META NAME="GENERATOR" CONTENT="GtkHTML/3.28.1"> </HEAD> <BODY> s&#246;n 2010-11-28 klockan 23:59 +0100 skrev sebastian:<BR> <BLOCKQUOTE TYPE=CITE> <IMG SRC="cid:1290985153.32143.0.camel@sebastian-desktop" ALIGN="b +ottom" BORDER="0"><BR> </BLOCKQUOTE> test </BODY> </HTML>

As you see, it will be very easy to replace the "cid:1290985153.32143.0.camel@sebastian-desktop" src with something like http://www.mydomain.com/webmail/getattachment.cgi?attachment=bot.png

Everything solved.


In reply to Get CID inline attachments with MIME::Parser by sebastiannielsen

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.