3

I'm using procmail with Maildir/ and easy rules like the one below to save incoming emails into directories:

:0:
* ^X-Spam-Status: Yes
Spam/

Now I would like a desktop notification on new emails in certain directories/rules, I know already how to handle notifications but how to tell procmail to save into a directory and execute a script?

I know I can pipe a |command but I would prefer to let procmail saving the file, then just run a script.

Having the email (headers at least) in pipe or the dir+file path as arguments would be nice, run the script asynchronous would also be nice.

update

So, based on @slm's answer that's the result:

:0 c:
* ^X-Spam-Status: Yes
Spam/

:0 Whi
* ^X-Spam-Status: Yes
| $HOME/install/bin/notify.sh

c copy the message in the directory but goes on with next rules

I'm not using f becase that's not a filter, if the rule match I want procmail to stop here (I hope I'm not misunderstanding the manual here)

W to suppress any program failure

h to pipe only headers

i to ignore any write error to the pipe

I'm not using w because don't want to wait the script to return

I think I don't need a lock file too (no : after Whi)

update 12/5/14

In the end I've adopted exactly the solution @tripleee proposed.

Played around also with mailutils-comsatd for few minutes before give up.

.procmailrc:

COMSAT=no

2 Answers 2

4

To run the mail through a script you can modify your rule like so using 2 rules:

:0: c
* ^X-Spam-Status: Yes
Spam/

:0: fw
* ^X-Spam-Status: Yes
| /usr/bin/python /work/scripts/process_mail.bash

Your program will receive the mail on STDIN. You'll have to 'echo' the possibly transformed mail on STDOUT.

fw means:

  • f Consider the pipe as a filter.
  • w Wait for the filter or program to finish and check its exitcode (normally ignored); if the filter is unsuccessful, then the text will not have been filtered.
  • c Generate a carbon copy of this mail. This only makes sense on delivering recipes. The only non-delivering recipe this flag has an effect on is on a nesting block, in order to generate a carbon copy this will clone the running procmail process (lockfiles will not be inherited), whereby the clone will proceed as usual and the parent will jump across the block.

References

2
  • thank you, I hoped in less redundancy but if it work will be fine, I'm trying it with a sh script, the first match work and a mail is moved into the directory but the second is ignored, not executed at all, the .sh file have execution permission and called from the shell work as expected, procmail verbose log show only one match.
    – Alex
    May 11, 2014 at 20:21
  • it work with the c flag on the first rule, thank you.
    – Alex
    May 11, 2014 at 20:48
3

Here's a slight adaptation of @slm's answer.

You should not use locking with Maildir, and the flags and the lock colon were the wrong way around. (You would effectively create a lock file named c, rather than clone the message, so the second action would never fire.)

The f flag seems out of place.

I reversed the order of the actions; while it makes sense to deliver, then notify, from the point of view of Procmail, the notification is a secondary action which is allowed to fail, so I do that in a clone and ignore its exit status.

Finally, grouping two actions under one condition is more intuitive using braces.

:0
* ^X-Spam-Status: Yes
{
    :0cWhi
    | $HOME/install/bin/notify.sh
    :0
    Spam/
}

Having said that, I also note that Procmail already generates comsat notifications out of the box. That's a legacy notification protocol, but you might be able to use it for something. Secondly, a simple notification mechanism could be built using a script which monitors your procmail.log instead. (But yeah, parsing log files sucks.)

5
  • Thank you, I had found nested block {} already and seen the problem with the c lock, all others info are really useful!
    – Alex
    May 12, 2014 at 8:06
  • 1
    Jesus, Procmail is frustrating. I have been programming for over 10 years and after staring at that gobbledygook for 15 minutes I still have no idea what it does.
    – user3356
    Feb 26, 2015 at 17:49
  • @g33kz0r If the condition matches, enter the block. Clone c the message and pipe the copy of the headers h to the external command, ignoring errors i but waiting for it to complete W. Then save the original message to the folder.
    – tripleee
    Feb 26, 2015 at 17:53
  • As a lover of all things *NIX, procmail is a ghetto.
    – user3356
    Feb 26, 2015 at 18:25
  • Bah, small potatoes compared to Sendmail configs. Procmail is terse, but still less terse than, say, sed.
    – tripleee
    Feb 26, 2015 at 18:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.