The FreeBSD Diary

The FreeBSD Diary (TM)

Providing practical examples since 1998

If you buy from Amazon USA, please support us by using this link.
[ HOME | TOPICS | INDEX | WEB RESOURCES | BOOKS | CONTRIBUTE | SEARCH | FEEDBACK | FAQ | FORUMS ]

Things look quiet here. But I've been doing a lot of blogging at dan.langille.org because I prefer WordPress now. Not all my posts there are FreeBSD related. I am in the midst of migrating The FreeBSD Diary over to WordPress (and you can read about that here). Once the migration is completed, I'll move the FreeBSD posts into the new FreeBSD Diary website.

Using foo+bar@ email addresses with Postfix and procmail 11 April 2003
Share
Need more help on this topic? Click here
This article has 2 comments
Show me similar articles

Mail addresses can be expressed as localpart@example.org. The key point of this article is that the localpart is indeed local. This provides a wide array of possibilities. I will explore just one of those possibilities.

Address extensions have been around for some time. They are a conceptual entity and are not actually defined in any RFC. Convention dictates what an address extension is and how it is used. Let us use foo+bar@example.org as our primary example. The user name in this example is foo. The extension part is bar and can be used for variety of purposes, but the most common usage is folder delivery. It is important to note that the delimiter can be anything you want. That is because delivery is a local matter. We can do whatever we want. Common delimiters include '+' and '-'. I have chosen to use '+'. Postfix allows you to set this value using the recipient_delimiter setting.

For reference, the following may be useful:

Yeah, well, why bother?

Why am I doing this? Why bother with address extensions? The answer is simple: because it makes life easier.

In this particular case, I am setting up a new development box for FreshPorts and FreshSource. This box is much faster than the existing environment. It will contain a development, a test, and a beta environment. I will want cvs-all messages going to each of those databases. I do this by sending the messages to dan+dev, dan+test, and dan+beta respectively[1]. I use procmail to process the incoming mail. This is very useful as it allows me to process the mail into the appropriate FreshPorts database. Without this ability, I would resort to different users for each database. Having just one user (me!) makes this all very easy and simple.

[1] - no, I don't have three subscriptions to the cvs-all mailing list. I have one. I use local aliases to copy that single message to three local addresses.

What's in it for me?

You might be asking that question now. Let me give you an example. Let's guess that you are subscribed to three different mailing lists. It's nice to keep all the messages for a particular list in a separate folder. There are many different ways to do this. I will not list them. Let's assume all the mailing lists have nothing in common and therefore you need three different entries such as these:

:0
* ^Sender: owner-cvs-all@FreeBSD.ORG
lists/cvs-all

:0
* ^Sender: Sender: procmail-bounces@lists.RWTH-Aachen.DE
lists/procmail

:0
* ^Sender: pgsql-advocacy-owner@postgresql.org
lists/postgresql-advocacy
Worse still, there is nothing in the mailing list email messages which is easy to identify. Rather than check To:, From:, and possible CC:, you can avoid all this by adding your very own key; your subscription address. Let's assume I subscribe to the above lists using the following email addresses:
  • dan+cvs-all@example.org
  • dan+procmail@example.org
  • dan+postgresql-advocacy@example.org
If you did that, then your procmail recipe becomes:
:0
$ARG
where ARG is the address extension.

But how do you get that extension? Postfix to the rescue!

Address extensions with Postfix

The Postfix MTA supplies many environment variables when local delivery is being performed. man 8 local contains the information you need. Specifically, this extract from the EXTERNAL COMMAND DELIVERY section:

EXTENSION
       The optional recipient address extension.
This variable is available to you within your ~/.forward script, which is the normal method for invoking procmail. Here is what I'm using:
"|exec /usr/local/bin/procmail -t -a ${EXTENSION}"

Read man procmail for more information. on these options.

  • -t instructs procmail to fail softly.
  • -a specifies an argument (in this case, the address extension).
In case anyone is wondering, I looked at using Procmail for system-wide local delivery but decided against it. Although I am the only user on this system, I didn't want to invoke procmail for every single email delivery.

See also the man page section titled ADDRESS EXTENSION where it documents that ~name/.forward+foo is tried first, by default. This setting can be changed via the forward_path setting (see sample-local.cf for an example).

The new procmail recipe

Here is how to use the address extension (as supplied by Postfix) within procmail. I found this gem in the procmail tips.

ARG = $1

:0
* ARG ?? ^^cvs-all^^|^^procmail|^^postgresql-advocacy^^
$ARG
The address extension is passed in as $1 by the .forward script. You can add more parameters to .forward as needed. The first is always $1, the second will be $2, etc. You cannot access this variable directly and you must assign it to a variable.
Passing the extension along

Sometimes you need to forward an email and include the extension you were given. This recipe does that:

ARG = $1

:0
* ARG ?? ^^^^
    !dan@things.example.org


:0
    !dan+$ARG@things.example.org

^^^^ represents an empty string. In this case, we do not include an extension.

Other references

I found Procmail Quick Reference Guide useful when devising my recipes.

The last word

My thanks to those on the procmail and Postfix mailing lists for pointing me in the right direction.

Share
Need more help on this topic? Click here
This article has 2 comments
Show me similar articles