Mail Management With Procmail - No Forwarding Address (
Page 4 of 8 )
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:
:0
* ^From:.*@melonfire.com !my.other.email.address@some.other.host
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:
:0
* ^From:.*@melonfire.com
* ^To: me@melonfire.com
* < 25600
!my.other.email.address@some.other.host
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.
:0
* ^From: .*joe@annoyances.domain.com
/dev/null
Hey, it works on in-laws too. No kidding.