Automatic client or server mail filtering

Aug 20, '04 09:29:00AM

Contributed by: iljitsch

If you have an account on a Unix system, you may be familiar with Procmail. This is a very advanced piece of mail processing software. One of its main uses is to sort incoming mail into different folders. The same can be done with Apple Mail's rules. However, there is a big difference (and I'm not talking about user friendliness): procmail generally runs on the server, while Mail runs on the computer you read your mail on (the client).

I'm sure this need isn't universal, but for me it's very convenient to be able to have mail put into the right folders on the server, both because it saves a lot of time downloading mail over slow connections, and because I sometimes actually read the mail on the server (that's the beauty if IMAP: you can read your mail from different computers without them getting in each other's way). So that's why I use Procmail to filter my mail.

However, there is a disadvantage to having the server filter mail: Apple Mail only checks the In folder for new mail. So when Procmail puts new messages into different folders, this isn't visible in Mail. The solution is filtering incoming mail in Mail rather than Procmail. But why not do both? In an ideal world, Mail would filter my mail when I'm online, and Procmail does it when I'm not. This was of course a challenge I couldn't resist, with the following result...

Whenever I receive mail, Procmail runs a shell script to determine whether I'm online and if I have Mail running. This line in my .procmail file runs the shell script:

FILTER=`/usr/home/iljitsch/mailfilter.sh`
The script itself looks like this:
#!/bin/sh
case `netstat -Wn | egrep -c "\.143 +10.0.0.20.*EST"` in
0)
  echo "server" ;;
*)
  echo "client" ;;
esac
The script executes the Unix netstat command that (among other things) lists all active TCP sessions. The -Wn option makes sure address are listed rather than host names, and the addresses aren't truncated. The egrep command matches anything with .143 (the TCP port for UDP) in it, followed by one or more spaces and my IP address (listed as 10.0.0.20 in the above script -- replace it with your real IP address!), and then EST (the session must be ESTABLISHED). Note that you could just as easily check the process table for instances of the imap daemon run under your name, so a static IP address isn't necessary. You don't want to check for your domain name, though, as the domain name lookups can get very slow.

If the result of the check is zero, the script replies server; in all other cases it says client. This result is put in the FILTER variable by Procmail. Then later in the .procmailrc, I can simply check the contents of this variable and only run the required filters when FILTER contains server:

:0
* FILTER ?? ^server$
{
  :0
  * ^from: .*webmaster@bgpexpert.com
  bgpexpert
}
For instance, this filter will put all messages from webmaster@bgpexpert.com into the folder 'bgpexpert' -- but only when I'm not online. When I am, Mail does this and I get a nice little beep to indicate that I have new mail.

Comments (6)


Mac OS X Hints
http://hints.macworld.com/article.php?story=20040819140718860