Tired of the sixteen terabytes of spam that confront you everymorning? Looking for a way to automatically manage and filter youremail? Say hello to procmail, automated message processing that's socool, it makes you want to believe in magic again.
Let's start with a very simple example - setting up procmail to forward all your incoming mail to a different email address.
Switch to your home directory and use your favourite text editor to create a file named ".procmailrc". Enter the following lines into this file (replace the second line with the email address your messages should be forwarded to):
:0
!my.other.email.address@some.other.host
Save the file, and change its
permissions so that it is owned by you, writable only by you, and readable by everyone else (procmail may barf if this file is secured in any other manner).
Now, send yourself some email and keep an eye on your mail queue. Once sendmail processes your message and hands it over to procmail for local delivery, procmail will read the instructions in your ".procmailrc" file and forward the message to the specified destination email address.
Simple, huh? Let's look at the engine that made this happen:
:0
!me@some.other.host
This snippet is a single procmail "recipe". Each recipe
must conform to the following format:
:0 <flags>
* <pattern>
<action>
As you can see, a recipe is simply a regular expression that
procmail searches for in the header of incoming email. If a message matches a recipe, procmail looks in the action line of the recipe to figure out what to do with the message; if it doesn't match, procmail proceeds to the next recipe. If no recipes match, procmail delivers the message in the default manner.
The line
:0 <flags>
marks the beginning of a recipe. It may include one
or more flags that alter the way procmail handles the recipe - for example, generating a copy of the message first, performing regular expression matching on the body instead of the header, matching in a case-sensitive manner, and so on.
This is followed by one or more
* <pattern>
lines, which mark the beginning of a procmail
condition. These conditions are typically regular expressions, which procmail uses when scanning the headers of incoming email. A single recipe can contain multiple conditions (note that, in the example above, I've omitted this line altogether, since I want to match *all* incoming email; however, I'll shortly demonstrate how this pattern-matching capability can come in handy for matching specific message types).
Messages that match the specified condition(s) are handled via the last line of the recipe, which specifies the action to be taken.
<action>
Typically, this <action> is a mailbox name, to
which the matched message(s) are to be delivered; however, it may also be another program or (as in the example above) another email address. An exclamation (!) at the beginning of the action line indicates that the message should be forwarded to the email address(es) following it, while a pipe (|) indicates that it should be piped as input to the specified program; anything else is treated as a literal mailbox name.
Once the action line of the recipe is successfully executed, procmail considers its job done, exits, and goes back to waiting for another incoming message.
The example above would work only for *your* mail, since the ".procmailrc" file resides in *your* home directory. If you're a system administrator, you might want to apply a recipe to *all* users on the system - in this case, you should use procmail's global recipe file, usually located in "/etc/procmailrc".{mospagebreak title=Of Wheat And Chaff} Let's look at another recipe, this one a little more complex. Let's suppose I wanted to forward only email from the domain "melonfire.com" to my second email address. Here's what my recipe would look like:
In this
case, only messages containing the expression "melonfire.com" in the "From" header line would get processed by this recipe and forwarded to my second email address - all other messages would be delivered in the default manner.
Wanna filter it a little more? Let's make sure I only forward messages that are addressed to me directly, and that are less than 25K in size:
I can also send mail to a specific
mailbox instead of forwarding it to another address - all I need to do is specify the mailbox name in the recipe's action line.
:0
* ^TO_webmaster@melonfire.com
WEBMASTER
In this case, all messages directed to "webmaster@melonfire.com"
get diverted to a mailbox named "WEBMASTER" in my home directory. The ^TO_ construct is a special expression that tells procmail to scan the "To", "Cc" and other destination headers for a match.
If you're on a lot of mailing lists, it's pretty simple to adapt this recipe so that messages from each mailing list end up in separate folders. Take a look at my sample configuration:
:0:
* From:.*redhat-list@redhat.com
LISTS
:0:
* From:.*php-general@lists.php.net
LISTS
:0:
* From:.*oracle-request@cs.indiana.edu
FUN
:0:
* From:.*list@lockergnome.com
FUN
Note the second colon (:) at the beginning of the recipes above - this
tells procmail to use a lock file while processing these recipes to ensure that the mailbox to which mail is being delivered does not get mangled if two processes try to access it at the same time.
Finally, here's a wicked little recipe I devised especially to help me filter out my annoying cousin Joe, who insists on forwarding me stale jokes every few days.