procmail save into a dir and execute a script?

9,402

Solution 1

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.)

Solution 2

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

Share:
9,402

Related videos on Youtube

Alex
Author by

Alex

Updated on September 18, 2022

Comments

  • Alex
    Alex almost 2 years

    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
    
  • Alex
    Alex about 10 years
    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
    Alex about 10 years
    it work with the c flag on the first rule, thank you.
  • Alex
    Alex about 10 years
    Thank you, I had found nested block {} already and seen the problem with the c lock, all others info are really useful!
  • Mehdi
    Mehdi over 9 years
    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.
  • tripleee
    tripleee over 9 years
    @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.
  • Mehdi
    Mehdi over 9 years
    As a lover of all things *NIX, procmail is a ghetto.
  • tripleee
    tripleee over 9 years
    Bah, small potatoes compared to Sendmail configs. Procmail is terse, but still less terse than, say, sed.