Litech Mail Filtering Setup

It is possible to do server-side mail filtering of Litech mail on marduk using Exim. This filtering can be used instead of or in addition to any client-side filtering that is done by Outlook, Netscape, or another mail client. The advantage of doing the filtering on the server is that all filtering is performed as soon as the message is received, which is often within seconds of the message leaving the sender's email system. Your email client does not have to be reading mail for the processing to work.

Another advantage to filtering is that you can append a "suffix" to your email address and use this to filter your mail. For example, I subscribed to daily Infobeat news updates with the address lutchann-infobeat@litech.org. Exim will identify this address as mine and pass the message to my filter script. My script is set up to recognize the "-infobeat" on the end of my address and handle Infobeat messages in a special way.

Filtering is specified by writing an Exim filter file and storing it named .forward in your marduk home directory. The complete specification for the format is on the Exim site, but here is a short tutorial/example and some information specific to our setup. The last section gives some commands for testing the filter file.

The first line

        # Exim filter

This line is critical! It designates that the rest of the file is in Exim-filter format instead of in the traditional format expected of .forward files. Capitalization and spacing don't matter and you can place any text you like on the line after the word "filter", but I recommend using this line as-is.

General format

Blank lines are ignored. Anything after a # sign is considered a comment and is ignored (except for the first line).

Variables

There are some variables available to compare and test, and they are referenced with a $ sign in front of their name. If the variable name is not followed by whitespace, you need to enclose the name of the variable in curly-braces. Here are some of the variables:

$sender_address
Contains the address of the sender of the message.
$reply_address
Contains the address specified in the message as the reply address, which may be different than the sender.
$tod_full
Contains the time and date that the message was received.
$local_part_suffix
Contains the suffix (including the "-") that was appended to your email address. Empty if no suffix was used.

All of the message's headers are stuffed into special variables. The names are composed of the header tag (e.g. "Subject:") in lower-case, prepended with "header_". For example, $header_subject: contains the subject-line from the message. Note that the colon after the tag in the variable name is optional.

Commands

These are some of the message-processing commands.

deliver email address
Forwards the email to a different address, which is specified on the line. Only one address is allowed per deliver command, but the deliver command may be repeated as often as necessary.
save file path
Saves the message to the specified path. If the path does not begin with a slash, the path is assumed to be relative to your home directory. If the path ends with a slash, the path is assumed to be a Maildir-format directory, which can be read by the IMAP daemon. To deliver into IMAP-accessable folders, check the section further down this document.
finish
Terminates processing of the filter file. If no deliver or save commands have been processed yet, the message will be delivered to your Inbox as usual.
seen finish
Terminates processing of the filter file, but causes the message to be thrown away if no deliver or save commands have been run yet.

Conditions

To test conditions, use one or more of these:

a begins b (negative: does not begin)
Tests whether b is the beginning of a.
a ends b (negative: does not end)
Tests whether b is the end of a.
a is b (negative: is not)
Tests whether a is equal to b.
a contains b (negative: does not contain)
Tests whether b is contained within a.
personal
Tests whether the message is directly address to you.
error_message
Tests whether the message is an error message from another mail system.

An example file

        # Exim filter

Don't forget that line!

        if error_message
        then
                finish
        endif

This statement halts processing if it is running on an error message. Since error messages are pretty important (usually indicating a delivery error for a message your sent), we stop processing to make sure they don't accidentally get lost. I recommend that you check for error messages at the very beginning of your filter file.

        if $local_part_suffix is -infobeat
        then
                save infobeat-news
        elif $local_part_suffix is -junk or
             $local_part_suffix is -spam
        then
        	seen finish
        endif

Two conditions have been sequenced here using the "elif" form of the "if" command. Messages to lutchann-infobeat@litech.org (assuming that I am using this filter file) will be saved into a file named /home/lutchann/infobeat-news and messages to lutchann-junk@litech.org or lutchann-spam@litech.org will be thrown away.

        if $sender_address ends @cornell.edu
        then
                deliver nl43@cornell.edu
        endif

Any mail that comes from a person at Cornell will be forwarded to my email address there instead of being delivered locally.

        if $header_subject contains "urgent"
        then
                seen finish
        endif

This throws away all messages with the word "urgent" in the subject line.

Saving to IMAP mailboxes

Since our IMAP server uses Maildir-format mailboxes, you'll need to use a special format if you want messages to be saved directly to folders that can be accessed with your mail client. All mail is stored in your Maildir folder, and subdirectories are preceeded with a period. The path for a folder named "November-2000" inside a folder named "Classes" would then be "Maildir/.Classes/.November-2000". When you're specifying a path like this in a "save" command, don't forget to add the slash to the end to specify that it is a Maildir mailbox. A save command for this path would look like this:

        save Maildir/.Classes/.November-2000/

Exim will not deliver to directories that do not already exist, so make sure you create a folder with the appropriate name before you set up your filter file!

Testing a filter file

Of course, testing your filter file before enabling it is always a good idea. To do this, make sure you create your file initially with a different name (like, say, forward-test) and then only rename it to .forward after you've checked that it works the way you want.

To test, you'll need to have a message saved to a file that Exim will filter. You can find lots of test messages in your Maildir/cur directory. I'll assume you've named it test-message and that it's in the current directory. Test the filter file with a command like this:

        $ sendmail -bf [filter file] < [test message file]

For example:

        $ sendmail -bf forward-test < test-message

If you're testing filtering on sender, you need to specify the appropriate address with a -f flag:

        $ sendmail -bf forward-test -f test@foo.com < test-message

If you're testing filtering on a suffix, you need to specify that too:

        $ sendmail -bf forward-test -bfs -foo < test-message

More complex filtering

If you want to do anything more complicated, or even if you don't, I recommend you read the full filtering documentation on the Exim site.


Last modified 12-31-2001 by lutchann.