Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Manipulating mail parts from Sendmail's queue

by chanakya (Friar)
on Jun 28, 2005 at 05:45 UTC ( [id://470493]=perlquestion: print w/replies, xml ) Need Help??

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

Greetings All

My new task is to manipulate the emails from the Sendmail's queue.
The basic idea is to add image to the top and bottom of the email.
Before moving further an idea about how Sendmail stores incoming mails.

The mail queue is a directory that stores data and controls files for mail
messages that the sendmail command delivers. By default, the mail queue is /var/spool/mqueue.

Each message in the queue has a number of files associated with it. The files are
named according to the following conventions:

d The data file containing the message body without the heading information.
q The queue-control file. This file contains the information necessary, and mail header information to process the job.


The files starting withq will hold the mail header information
The q file for a message sent to amy@zeus would look similar to:
P217031 T566755281 MDeferred: Connection timed out during user open with zeus Sgeo Ramy@zeus H?P?return-path: <geo> Hreceived: by george (0.13 (NL support)/0.01) id AA00269; Thu, 17 Dec 87 10:01:21 CST H?D?date: Thu, 17 Dec 87 10:01:21 CST H?F?From: geo Hmessage-id: <8712171601.AA00269@george> HTo: amy@zeus H??X-Accept-Language: en-us, en H??MIME-Version: 1.0 H??Subject: Hello .. its a test html mail H??Content-Type: text/html; charset=ISO-8859-1 H??Content-Transfer-Encoding: 7bit
The files starting with d will hold the mail body
The d file for a message sent to amy@zeus would look similar to:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Typ +e"> <title></title> </head> <body bgcolor="#ffffff" text="#000000"> Hi shobs,<br> its test mail for html !!<br> <h1>THE PENGUIN</h1> <h2>OPEN SOURCE PRODUCTS</h2> <h3>MIMEDefang</h3> <p>...</p> <br> </body> </html>
If a user sent a mail to my host, then I'll be having 2 parts of the email in the /var/spool/mqueue, with the following format:

dfj5RAnuBt013914
qfj5RAnuBt013914

Now, coming to the task, I need to get two parts of the email in my script, get the content-type and if the type
is "text/html" or "multipart/alternative" then add an image after the <body> tag and move the two mail parts to /var/spool/mqueue_manip

Can someone give idea about getting the mail part contents (dfj5RAnuBt013914, qfj5RAnuBt013914) with the same number(ex:dxxxxxxx013914, qxxxxxx013914) into two different variables. Also, remember that there may be many files starting with d, q with different numbers.

This is what I've tried until now:
#!/usr/bin/perl use strict; use warnings; use Data::Dumper; sub __readFile; sub __getHeaders; sub __updateMailBody; ### Config my $pre_dir = "/tmp/mqueue"; my $post_dir = "/tmp/mqueue_processed"; # Two parts of one email, hardcoded for testing my @mail_parts = ("$pre_dir/qfj5RAnuBt013914", "$pre_dir/dfj5RAnuBt013 +914"); ## files with "dxx" hold the mail content my $out_file = $mail_parts[1]; my $mail_content; foreach (@mail_parts){ $mail_content = __readFile($_); my $mail_headers = __getHeaders($mail_content); } sub __readFile($){ undef $/; my $part = shift; my $part_data; open(FH, "< $part"); $part_data .= <FH>; close (FH); return $part_data; } sub __getHeaders($){ my $mail = shift; my $msg_id = $1 if ($mail =~ m{H\?\?Message-ID\: \<(.*?)\>}); my $from = $1 if ($mail =~ m{H\?\?From\: \"(.*?)\"}); my $content_type = $1 if ($mail =~ m{H\?\?Content-Type\:\s(.*?);}); #print $msg_id . " ". $from ." " .$content_type; if ($content_type eq "text/html"){ __updateMailBody($mail); } } sub __updateMailBody($){ my $mail = shift; #my @mail = $mail; #get the part between <body> </body> my $stripped_part = $2 if ($mail =~ /\<body(.*?)\>(.*?)\<\/body\>/sg +m); print $stripped_part."\n"; ## Add the image tag after <body> tag ## Adding an image this way will work.. once the Sendmail sends the +email ..?? my $line_to_add = "<div><image>/tmp/ATT135859.gif </image </div>"; open(OUT, "> $post_dir/$out_file"); ## Add code to add the image onto the top of $stripped_part ## and write out the full content to the original filename (dfj5RAnu +Bt01391) ## into $post_dir ## Add code for the same close(OUT); }
Can someone let me know how to get the matching email parts..and also how to update the email part with the embedded image data on top and bottom of the mail part..?
Thanks in advance

Replies are listed 'Best First'.
Re: Manipulating mail parts from Sendmail's queue
by rob_au (Abbot) on Jun 28, 2005 at 10:43 UTC
    I have done a lot of work with Sendmail and message manipulation in the past and as such suggest that there is a better way to achieve your goal of embedding an image at the top and bottom of the email than directly manipulating the Sendmail mail queue - Indeed, depending upon the processing rules associated with the embedding of images into emails, directly manipulating message queue files may not even provide a practical or complete solution.

    So how do I recommend you manipulate the messages in Sendmail? Use the Milter interface provided by Sendmail. Sendmail's Content Management API (milter) provides third-party programs to access mail messages as they are being processed by the Mail Transfer Agent (MTA), allowing them to examine and modify message content and meta-information. Filtering policies implemented by Milter-conformant filters may then be centrally configured and composed in an end-user's MTA configuration file. Uses for filters include spam rejection, virus filtering, and content control.

    Using this interface, you could update the content of mail messages as they pass through the SMTP interface of Sendmail , before they are injected into the mail spool. This approach side-steps any race issues which you are likely to encounter with direct manipulation of files in the mail queue.

    Further information on the milter interface can be found in the Sendmail distribution and at the Milter community website - http://www.milter.org. It is also worth noting that there are two Perl interfaces to the milter interface, Sendmail::Milter and Sendmail::PMilter, the latter of the two being that which I would recommend for usage (due to its more robust performance and better support).

     

    perl -le "print unpack'N', pack'B32', '00000000000000000000001000000000'"

Re: Manipulating mail parts from Sendmail's queue
by cajun (Chaplain) on Jun 28, 2005 at 06:36 UTC
    Have you any sample code? This should be an easy task.

    Try reading the directory and getting the names of the "q..." files.
    After you have that, the rest is easy.
    There is a matching "d..." file for every "q..." file.

    Please post your attempt and someone will give you more assistance.

Re: Manipulating mail parts from Sendmail's queue
by Anonymous Monk on Jun 28, 2005 at 06:00 UTC

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (5)
As of 2024-04-23 20:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found