Search code examples
emailsedprocmail

Configure procmail to match an external email address list when filtering emails


My fetchmail scripts retrieves emails from an email box and puts them into a file, called mario, and dumps it into my /var/mail/ folder. I am trying to set up a procmail script to process mario; by processing, this is what I mean: the procmail script should filter against an external text file (fromlist) containing a list of known email addresses. Once there is a match mario/fromlist, the message is pulled out from mario and stored into my local nbox/ folder.

Online, I found a piece of code, including a recipe, that I have entered into my procmail control file (.procmailrc) but it doesn't seem to be working. This is the code:

FROMFL=$MAIL/fromlist

FROMLS=formail -xFrom: | sed -e 's/*(.*)//;s/>.*//;s/.*[:]*//'`

:0

* ? fgrep -xi $FROMLS $FROMFL

$MAIL/inbox

I think I have addressed the sed (see my question Sed command and unknown patterns found online), but I still haven't been able to address the formail and fgrep parts. So when I run the procmail script, the logs I obtain are:

$ mailstat var/log/procmail.log
/bin/sh: 0: Can't open fgrep
/bin/sh: 1: grep: not found
/bin/sh: 1: sed: not found
/home/user/var/mail/reginbox/
procmail: [6880] Sat Jun 16 16:57:32 2018
procmail: Acquiring kernel-lock
procmail: Assigning "FROMFL=/home/user/var/mail/fromlist"
procmail: Assigning "FROMLS="
procmail: Assigning "LASTFOLDER=/home/user/var/mail/reginbox/msg.XXX"
procmail: Assigning "SHELL=/bin/sh"
procmail: Executing "fgrep,-xi,/home/user/var/mail/fromlist"
procmail: Executing "formail -xFrom: | sed -e `'s/.*<//; s/>.*//'`"
procmail: No match on "fgrep -xi /home/user/var/mail/fromlist"
procmail: Non-zero exitcode (127) from "fgrep"
procmail: Notified comsat: "user@0:/home/user/var/mail/reginbox/msg.XXX"
procmail: Opening "/home/user/var/mail/reginbox/msg.XXX"

It looks as if formail cannot quite extract the lines where "From:" is located, which means that the email addresses in those lines are not carved out of the rest by the SED command and are not compared against the text file with the list of emails (fromlist), that's why the log show a "No match" message.

How can I find out where these things break down?


Solution

  • The syntax for running an external command is

    VARIABLE=`command to run`
    

    You are missing the opening backtick, so you are running effectively

    FROMLS="formail"
    -xFrom: | sed etc is a syntax error
    

    Anyway, the recipe to extract the sender is a bit inexact, because it doesn't cope correctly with various variations in email address formats. A more robust but slightly harder to understand solution is

    FROMLS=`formail -rtzxTo:`
    

    which makes formail generate a reply -rt, then from the generated reply extract the To: address, which of course now points back to the original sender. By design, formail only puts the actual email address of the sender of the input message in the To: header when it generates the reply, so that's what you will be extracting.

    With that out of the way, your script should technically work to the point where it can extract the matching messages and copy them to the destination folder you want. Here's a quick demo:

    tripleee$ cd /tmp
    
    tripleee$ echo [email protected] >fromlist
    
    tripleee$ cat one.rc
    # temporary hack
    SHELL=/bin/sh
    MAILDIR=/tmp
    MAIL=.
    VERBOSE=yes
    
    FROMFL=$MAIL/fromlist
    
    FROMLS=`formail -rtzxTo:`
    
    :0
    * ? fgrep -xi "$FROMLS" "$FROMFL"
    $MAIL/inbox
    
    
    tripleee$ procmail -m one.rc <<\:
    From: [email protected]
    To: [email protected]
    Subject: no match
    
    hello
    :
    procmail: [16406] Wed Jun 27 13:41:35 2018
    procmail: Assigning "FROMFL=./fromlist"
    procmail: Executing "formail,-rtzxTo:"
    procmail: Assigning "[email protected]"
    procmail: Executing "fgrep,-xi,[email protected],./fromlist"
    procmail: Non-zero exitcode (1) from "fgrep"
    procmail: No match on "fgrep -xi [email protected] ./fromlist"
     Subject: no match
      Folder: **Bounced**                                                        61
    
    tripleee$ procmail -m one.rc <<\:
    From: [email protected]
    To: [email protected]
    Subject: match
    
    hello
    :
    procmail: [16410] Wed Jun 27 13:41:37 2018
    procmail: Assigning "FROMFL=./fromlist"
    procmail: Executing "formail,-rtzxTo:"
    procmail: Assigning "[email protected]"
    procmail: Executing "fgrep,-xi,[email protected],./fromlist"
    procmail: Match on "fgrep -xi [email protected] ./fromlist"
    procmail: Assigning "LASTFOLDER=./inbox"
    procmail: Opening "./inbox"
    procmail: Acquiring kernel-lock
     Subject: match
      Folder: ./inbox                                                            68    
    

    There is no way really for procmail to remove anything from the input folder. If you want to do that, a common solution is to have Procmail write the non-matching messages to another output folder, then copy that back over the input file. The net effect is that the messages from the original input folder are now partitioned into two files, one with matching, and one with non-matching messages.