1

For a couple of days, I've been trying to write procmail script.

I want to forward messages, and inject some text into message contents.

What I want to accomplish :

  • someone send me e-mail, with word "weather" in the subject
  • email is forwarded to address "mymail@somedomain.com"
  • every forwarded email gets some added text in contents

But so far, no success.

In .procmail.log, there's a message "procmail: Missing action"

SHELL=/bin/bash
VERBOSE=off
LOGFILE=/home/test/.procmail.log
LOGDATE_=`/bin/date +%Y-%m-%d`

:0
* ^Subject:.*weather

:0 bfw
| echo "This is injected text" ; echo "" ; cat

:0 c
! mymail@somedomain.com

When I looked into email source, I saw that text is injected. But the place is wrong ...

Take a look:

MIME-Version: 1.0
Content-Type: multipart/mixed;
 boundary="------------148F3F0AD3D65DD3F3498ACA"
Content-Language: pl
Status:   
X-EsetId: 37303A29AA1D9F60667466

This is injected text

This is a multi-part message in MIME format.
--------------148F3F0AD3D65DD3F3498ACA
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit

CONTENT CONTENT CONTENT
*********************************************************

Injected text should be placed, where content is. Now it is above ...

tripleee
  • 175,061
  • 34
  • 275
  • 318
Marek MW
  • 11
  • 1
  • Like the error message, says, you don't have an action on the recipe which has the condition `^Subject:.*weather`. Unfortunately, code which doesn't work is a terrible way to explain what you *do* want, but perhaps you are looking for braces? http://www.iki.fi/era/procmail/mini-faq.html#recipe-block – tripleee May 09 '18 at 08:06

1 Answers1

1

You don't explain your code, but it looks like that you are attempting to use multiple actions under a single condition. Use braces for that.

:0
* ^Subject:.*weather
{
  :0 bfw
  | echo "This is injected text" ; echo "" ; cat

  :0 c
  ! mymail@somedomain.com
}

Just to summarize, every recipe must have a header line (the :0 and possible flags) and an action. The conditions are optional, and there can be more than one. A block of further recipes is one form of action so that satisfies these requirements (the other action types are saving to a folder, piping to a command, or forwarding to an email address).

To inject text at the top of the first MIME body part of a multipart message, you need to do some MIME parsing. Procmail unfortunately has no explicit support for MIME, but if you know that the incoming message will always have a particular structure, you might get away with something fairly simple.

:0
* ^Subject:.*weather
{
  :0fbw
  * ^Mime-version: 1\.0
  * ^Content-type: multipart/
  | awk '/^Content-type: text\/plain;/&&!s {n=s=1} \
      n&&/^$/{n=0; p=1} \
      1; \
      p{ print "This is injected text.\n"; p=0 }'

  :0 c
  ! mymail@somedomain.com
}

The body (which contains all the MIME body parts, with their headers and everything) is passed to a simple Awk script, which finds the first empty line after (what we optimistically assume is) the first text/plain MIME body part header, and injects the text there. (Awk is case-sensitive, so the regex text might need to be adapted or generalized, and I have assumed the whitespace in the input message is completely regular. For a production system, these simplifying assumptions are unrealistic.)

If you need full MIME support (for example, the input message may or may not be multipart, or contain nested multiparts), my recommendation would be to write the injection code in some modern script language with proper MIME support libraries; Python would be my pick, though it is still (even after the email library update in 3.6) is slightly cumbersome and clumsy.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • As an aside, for efficiency, you might want to use a single `sed` script instead of multiple shell commands in the pipe action. The precise syntax for inserting something on line 1 differs a bit between `sed` implementations, but something like `1i (text to insert)`. Embedding literal newlines in the `sed` script is a significant challenge under Procmail, though. (Search the page I linked in the answer for "Getting a newline into the action") – tripleee May 09 '18 at 08:12
  • If you only want the changes to be made in the forwarded message, try moving the `c` flag to the condition outside the braces. – tripleee May 26 '18 at 09:00