I have the following scenerio:
SMTP server on the GNU/Linux machine is accepting mails. Accepted mail is being sent to procmail for further processing. Here's my .procmailrc:
VERBOSE=yes
LOGFILE=$HOME/procmail.log
SUBJECT=`formail -xSubject: | tr -d '\n' | sed -e 's/^ //' | /usr/bin/perl -MEncode -ne 'print encode ("utf8",decode ("MIME-Header",$_ )) '`
FROM=`formail -rt -xTo:`
DATE=`formail -xDate:`
BODY=`formail -I ""`
:0fbW
* ^From.*some_special_name@special_server.com
| echo "FROM:$FROM" > $HOME/res.txt; \
echo "DATE:$DATE" >> $HOME/res.txt; \
echo "SUB:$SUBJECT" >> $HOME/res.txt; \
echo "BODY:" >> $HOME/res.txt; \
echo $BODY >> $HOME/res.txt; process.py
This little script first creates a local file $HOME/res.txt and then launches another script called process.py. Now, the $HOME/res.txt is populated with the following entries:
FROM:some_special_name@special_server.com
DATE:Mon, 06 Oct 2014 13:14:32 +0200
SUB:Some subject
BODY:
This is a multi-part message in MIME format. --------------030006020609010705060803 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hello, Some kind of long tekst where I cannot see the line feed chars nor any other control chars...
The body contains the raw string without the original format of the body. What I mean by this is that \n or \t characters are filtered out. The process.py script demands the body part of the message to maintain the original format of the email message.
How can I achieve this?
As always in shell scripts, you need to properly duoble-quote variables unless you specifically require the shell to perform token splitting and wildcard expansion on the value. See e.g. this answer for a detailed explanation.
echo "$BODY" >>$HOME/res.txt; \
Additionally, I don't understand why you mix multiple actions like that. Between the lines, I guess you mean that process.py
reads res.txt
instead of its standard input; if it were reading standard input, it would receive the correct, unmangled message.
Without context, I'll go out on a limb and speculate that the f
flag is also wrong. Unless process.py
prints a new message on standard output which should replace the incoming message for the remainder of your Procmail recipe file, you should simply take it out.
There is also a race condition here: if multiple messages arrive at roughly the same time (where "same time" can be a rather wide window if your system is under heavy load), they will overwrite res.txt
and trample over each others' results in unpredicable ways. The customary solution to that is to use a local lock file; but the vastly superior solution is to remove the need for a temporary file, and change process.py
so that it reads standard input instead.
Since you are using Python anyway, I would do all the header parsing in Python, with the possible exception of formail -rtzxTo:
, which is rather complex to reimplement; this would simplify your Procmail recipe significantly, and probably improve process.py
(or the wrapper you create, if you cannot modify it).