Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

MIME Attachment Extractor

by httptech (Chaplain)
on May 18, 2000 at 06:31 UTC ( #12287=snippet: print w/replies, xml ) Need Help??
Description: This is a short piece of code I wrote to enhance a online helpdesk system. It parses incoming emails, finds any attachments and saves them, then inserts into the email a link to where the saved attachments can be downloaded from.

In this code, the email is being read from STDIN, and the "cleaned" message (headers and body) is returned as a scalar.

You should take precautionary security measures on the directory that will hold the attachments; you obviously don't want to allow anyone to email you arbitrary code and run it from your public html directories.

use MIME::Parser;

sub read_email {
  my $dir = "/home/foo/public_html/attachments";
  my $url = "http://www.foo.bar/attachments";

  my $parser = new MIME::Parser;
  $parser->output_dir($dir);
  my $entity = $parser->read(\*STDIN) || die "couldn't parse MIME stre
+am";
  my $head = $entity->head;
  my $content = $head->as_string . "\n";

  my @parts = $entity->parts;
  my $body = $entity->bodyhandle;

  $content .= $body->as_string if defined $body;
  my $part;
  for $part (@parts) {
    my $path = ($part->bodyhandle) ? $part->bodyhandle->path : undef;
    if ($path =~ /msg-\d+.*\.doc/) {
      open(IN, $path) || warn "Couldn't open $path\n";
      local $/ = undef;
      $content .= <IN> . "\n";
      close IN;
      unlink ($path) || warn "Couldn't unlink $path\n";       
    }   
    else {
      my $file = $path;
      $file =~ s/$dir//o;
      $content .= "\n--\nSaved attachment: $url$file\n--\n"; }
    }

return $content;
}
Replies are listed 'Best First'.
RE: MIME Attachment Extractor
by Punto (Scribe) on Jun 01, 2000 at 19:26 UTC
    I have 1 question: if the e-mail has only 1 part (the body of the msg), the .doc file is created, @parts is empty, and the file never gets deleted on the "for $part (@parts)" loop. Is there a way to get the name of the file when there are no attachments?
      I got it! :)
      Instead of using:
      $content .= $body->as_string if defined $body;
      I do:
      if (defined $body) { $content .= $body->as_string; $filename = $body->path; unlink($filename); };
      and it works fine.. Thanks..
      Yes, the bodies are always saved with the prefix "msg-" (unless you override it). So you can just unlink anything that starts with that prefix to clean out the message bodies.
        What if while I'm deleting, another program is creating a file, and it's not done with it yet? The module Mime::Parse may lock the file, but then the sub open the file..
Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2023-06-10 21:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    How often do you go to conferences?






    Results (39 votes). Check out past polls.

    Notices?