10.3 Program Deliveries

Qmail defines a complex but well-specified environment in which to run the programs specified in .qmail command lines. Each command is run under the user's user ID and primary group ID, in the user's home directory, via /bin/sh -c. The command's standard input is the message file, while the standard output and standard error are a pipe back to qmail-lspawn, which logs anything the command writes to its output. If the program fails (exit 100), its output is mailed back to the sender as part of the error report. The message file is guaranteed to be an actual file, so that programs can read the message, seek back to the beginning, and read it again. (This isn't very useful for individual programs, but it's quite useful for programs like condredirect that fork off a child program that reads and analyzes the message, then when the child is done, reprocess the message itself.)

The program's environment variables are inherited from the qmail-start command that originally started qmail, with quite a few added variables to help manage the delivery:


USER

The delivery username


HOME

The user's home directory


LOCAL

The local part of the recipient address


HOST

The domain part of the recipient address


RECIPIENT

The envelope recipient address, $LOCAL@$HOST


DTLINE

The Delivered-To: line, Delivered-To: $RECIPIENT\n; any newlines within the recipient address are changed to underscores


SENDER

The envelope sender address


NEWSENDER

The envelope sender, modified for mailing list deliveries; see Section 10.5


RPLINE

The Return-Path: line, Return-Path: $SENDER\n; any newlines within the sender address are changed to underscores


UFLINE

The uucp From line, the separator line that would be written to an mbox file, From $SENDER Thu Nov 29 21:33:09 1973\n. If the sender is null, it uses MAILER-DAEMON, and any spaces, tabs, or newlines within the sender address are changed to dashes (not underscores)


EXT

The address extension, the part of $LOCAL that follows the first dash; if there's no dash, the null string


EXT2

The second address extension, the part of $LOCAL that follows the second dash; if there's no second dash, the null string


EXT3

The third address extension, the part of $LOCAL that follows the third dash; if there's no third dash, the null string


EXT4

The fourth address extension, the part of $LOCAL that follows the fourth dash; if there's no fourth dash, the null string.


DEFAULT

If the .qmail file is a default file, the part of the local part that matched the default (see Section 10.4); not set if this is not a default file


HOST2

The part of $HOST preceding the last dot


HOST3

The part of $HOST preceding the penultimate dot


HOST4

The part of $HOST preceding the antepenultimate dot

Other than the translations of whitespace to underscores or dashes, there's no attempt to defend against strange or hostile characters in environment variables, so scripts should be sure to double-quote variable references and remember that hostile senders can put any characters they want, including punctuation and spaces, into a message's envelope. Programs called from .qmail files should be equally cautious if they use the environment variables either directly or as program arguments. For example, if a Perl script uses a subaddress to select a file to use, be sure it does something reasonable when a sender sends you a message where the subaddress is |rm -f.

There is no provision for continuation lines in a .qmail file, so each command has to be on a single line. There's no limit to the length of that single line, so you can put arbitrarily complex shell commands in your .qmail file. In practice, if the shell script is more than about 100 characters, it's easier to put the script in a separate file and call the script file from the .qmail file.

Any program run from .qmail files should run to completion and exit. If it forks and continues in the background, the results are unpredictable, because all program and mailbox deliveries from a .qmail file share the same input file descriptor, and the program's file reads are intermixed with those of other commands run from the same .qmail file. (qmail-local resets the seek pointer to the beginning of the file before each delivery.)

Delivery programs should not take very long to complete. Qmail normally limits itself to 10 simultaneous local deliveries, so 10 long-running delivery programs lock out all other local deliveries.

10.3.1 Delivery Utilities

Qmail provides a small set of programs intended for use in deliveries.

10.3.1.1 forward

The most useful of the programs is forward, which remails the input message to all of the addresses given on the command line, as though the addresses were each on a forward line in the .qmail file. This is useful both because forward can be embedded in shell scripts to be run conditionally and the addresses can be calculated at runtime. For example, to forward a message to a different address depending on what the day of the week is, type:

| forward "day-$(date +%a)@example.com"

Or to route mail from one sender specially, type:

| case "$SENDER" in fred@domain.com) forward fredflame ;; *) forward inquiries ;; esac
10.3.1.2 bouncesaying

Bounce a message back to the sender either unconditionally or if a program succeeds. Most often, bouncesaying is used to turn off addresses that are no longer active:

| bouncesaying "Sorry, this employee has left the company"

It's occasionally useful as a simple mail filter:

| bouncesaying "No tropical fruit, please" grep -q "guava|mango|papaya" ./Maildir/

This scans the message for forbidden words and bounces the message if the grep succeeds. Otherwise it delivers the message to the user's Maildir. Note that the -q flag keeps the grep command from producing unwanted output that would be mailed back with the bounce message.

10.3.1.3 condredirect

Conditionally remail a message to a different address. The arguments are the new address and a shell command to run. If the command succeeds and exits 0, the message is mailed to the new address, and condredirect exits 99, telling qmail to ignore any subsequent lines in the .qmail file. If the command exits 111, so does condredirect. If the command exits with any other code, condredirect exits 0:

| condredirect subscriptions grep -q -i "Subject:.*subscribe" ./Maildir/

Except in the most simple applications, it's usually easier to use procmail.

10.3.1.4 except

Reverse the exit code of a program:

| bouncesaying "Tropical fruit required here" except grep -q "guava|mango|papaya" ./Maildir/

The except command reverses the sense of the grep so the mail is bounced if the magic words don't appear in the message.[3]

[3] Yes, I could have used --v in the grep command. It's an example.



qmail
qmail
ISBN: 1565926285
EAN: 2147483647
Year: 2006
Pages: 152

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net