The article
introduces header editing with sed. Here's
another sed example.
As the article shows, your system may make the first line of each
incoming message a
"From " separator. The
email address and date on that line can be useful information, but it
can be lost when the message is forwarded. Here's a procmail
recipe with two sed commands to fix that:
# Copy "From user date" into a header field:
:0 f
| sed -e 1p -e '1s/^From/X-Envelope-From:/'
The procmail f flag means "use this recipe as a
filter"; that is, "filter the message through this shell command, and
don't consider the message delivered after this
recipe completes." The first sed
expression, -e 1p, tells
sed "on line 1, execute print." This maintains the
existing "From " separator
by outputting a copy of the unedited line. Next, we edit the original
line (not the copy we just outputted) so it
becomes a header field. The second editing expression tells sed
"on line 1, substitute the string From with the string
X-Envelope-From:". (You can
define your own legal header fields by starting the name with X-. So, to add random header
fields to messages -- for tracking purposes, for instance -- precede the
name with X- unless you're
sure it's a valid field name.) So, our recipe will convert an incoming
message from this:
From a@b Thu Jun 26 05:03:59 2003
Received: from mail.foo.xyz ([2.75.12.109])
...
to this:
From a@b Thu Jun 26 05:03:59 2003
X-Envelope-From: a@b Thu Jun 26 05:03:59 2003
Received: from mail.foo.xyz ([2.75.12.109])
...
sed Script Files
You can also put sed
editing commands into a script file, and give its filename
in your .procmailrc file.
(Be sure, though, that the script file is on a filesystem
that's available from the mail server or whatever host procmail is running on, though! For
example, if the script file is on a filesystem available only over NFS,
and the NFS server is down, the mail server may not be able to access
the script.) Here's the revised recipe:
# Copy "From user date" into a header field:
:0 f
| sed -f /somedir/env-sender-field.sed
and the env-sender-field.sed
script file would look like this:
1 {
p
s/^From/X-Envelope-From:/
}
That script-file syntax is especially handy when you want to apply a
series of commands to the message header, which is matched by the
address range 1,/^$/. You
only need to write the address range once; all commands that apply to
the header go between the curly-braces:
1,/^$/ {
s/^Subject:/Subject: [spam] /
}
Trouble with Multi-line Header Fields
sed doesn't understand
header fields that are continued onto another line. Matching multi-line
fields is possible, but it's not very straightforward.
To work around this, you can pipe messages through formail -c
before piping them to sed.
You might want to use a scripting language with more features than
sed.
One advantage of sed, though, is that it's small and fast.
Large program interpreters -- for Perl or Python, for example --
may take much longer to start and run, which could add a significant
load (and delay) on a busy mail server host.
[To return to the place where you left the article, use your
browser's "back" button. You can also go to
the start
of the article.]