6.1 qmail-queue

The only way to pass a message into qmail is qmail-queue. All of the other relay and injection programs, for both local and remote originated mail, call qmail-queue to queue a message and schedule it for delivery. This design has two advantages: it's easy to write new frontends to inject mail because they only need to call qmail-queue to pass along the mail, and by replacing qmail-queue with another program that offers the same interface, you can create interestingly different systems, such as mini-qmail. (See Chapter 16 for details.) It also offers security advantages, because qmail-queue is one of the few set-uid programs (to qmailq, not root) in the qmail package, so it can write files in the queue directories.

qmail-queue is intended to be run from other programs, not from the command line, so it has an interface that only another program could love. It takes no command-line arguments and reads its input from two file descriptors. The first input is read from file descriptor and is the text of the message. qmail-queue treats the message as an uninterpreted block of bytes and doesn't change it at all, other than prefixing a Received: line at the front. The received line includes the PID, the message source, and a timestamp:

Received: (qmail pid invoked source); 4 Apr 2004 22:35:00 -0000

The source is by alias if the invoking user is the alias user; from network if the invoking user is qmaild, the daemon user that means the caller was the SMTP daemon; for bounce if the user is qmails, the qmail-send user; or by uid NNN otherwise.

Then qmail-queue reads the envelope information from file descriptor 1 in a concise binary format. (In most programs, that's the standard output, but this isn't most programs.)

Fsender@sender.com\0 Trcpt1@rcpt.org\0 ... Trcptn@rcpt.net\0 \0

First is the letter F, the sender's address, and a null byte. Then there is a list of recipient addresses, each preceded by the letter T and followed by a null byte. Finally there comes an extra null byte.

Once it has the message and the envelope, qmail-queue writes them in files in the queue directories and notifies qmail-send to process queued messages.

The only output from qmail-queue is the return code, which is zero if the message could be queued, and any of a long list of other values if not. (See the manpage for the list.) Because qmail-queue only queues a message, its return code says nothing about whether the message could be delivered, only that it could be queued for the rest of qmail to do something with it. If there are delivery problems, qmail reports them by sending bounce messages to the message's sender address.

6.1.1 Passing Input to qmail-queue

qmail-queue reads two input files from two file descriptors, and more often than not both input files are pipes from the calling program, so some care is needed to avoid deadlock. It's important to remember that qmail-queue reads the message from fd 0 first, then the envelope from fd 1. This isn't an implementation accident; it's part of the spec.

If you're writing programs that call qmail-queue and use pipes, be sure that you write the entire message first, then close the message pipe, and then write the envelope. If the structure of the program doesn't make that convenient, write the envelope information to a file in /tmp. (You could write the message to a temporary file instead, but the envelope is usually a lot smaller than the message.)

If you're writing programs that use the same interface as qmail-queue, read the entire input message before reading the envelope. If you want to look at the envelope before doing anything with the message, you must stash the message in a file first. In practice, this isn't often a problem, because the message needs to be stored in a file anyway.

6.1.2 Other Queueing Programs

Qmail comes with one other compatible queueing program, qmail-qmqpc, the mini-qmail QMQP client that queues the mail on another host. Because the interface is so simple, it's quite simple to add a "shim" between the calling program and qmail-queue to do tasks like making a copy of all the mail (just add the address of the log mailbox to the list of recipients) or invoking spam filters. We'll see many of these elsewhere in the book.

6.1.3 Wrapping qmail-queue

If you want to replace qmail-queue, you have three alternatives. One is to move the real qmail-queue and rename or symlink the replacement to /var/qmail/bin/qmail-queue. If you want to use the replacement every single time you normally use qmail-queue, this is the easiest approach. Mini-qmail (see Chapter 16) does this because it moves the entire mail queue to another system. More often, you only want to replace qmail-queue when a message is first introduced into the system, not every time it's forwarded, so a more flexible approach is called for. One possibility is to individually patch the code in qmail-inject and qmail-smtpd and new-inject, and whatever other programs you use to inject mail. This turns out to be extremely messy programming, because all of the programs in the qmail package use a single library routine to call qmail-queue, so you must create multiple versions of that routine.

A third approach, and the one I recommend, is the "qmailqueue" patch that takes the name of the program from the environment. Once it's applied, if the variable QMAILQUEUE is defined, it names the program to run instead of qmail-queue. There's a very short patch file at qmail.org (search for QMAILQUEUE on the home page) that's easy to apply to the qmail source. If you use the netqmail-1.05 package, it's already had the patch applied.

Several of Dan's add-on packages also call qmail-queue, using the same qmail.c library file, so you can use the same patch. These include dot-forward-0.71, fastforward-0.51, mess822-0.58, and serialmail-0.75. Either apply the patch to each of them, or copy the patched copy of qmail.c from the qmail or netqmail source directory into the source directories of the add-on packages. In each of the add-on packages, if you apply the patch file, the patch program will complain that the patch failed on Makefile, which you can ignore because in all of the add-ons, only qmail.c needs patching. Don't forget to recompile and reinstall all the packages you patched.



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