Qmail-Send
Qmail-send is the core of Qmail's mail delivery process. It monitors the mail queue, dispaches individual deliveries from messages to happen at bothe the local and remote channel, schedules redelivery attempts, and asks qmail-clean to clean-up (remove) messges from the queue when they are done. It also creates the Bounce messages to return messages to the sender (via the envelopeA channel refers to either the local or remote delivery queue.
The roadmap
As described, you can tell this program does a lot. At 1455 lines of C code, it is still rather compact. Still, there are several sections within the program which Bernstein has apologized for leaving the code in one large file (find the comments starting with "this file is too long").These sections are:
- Main - The main processing loop. See below
- Filenames - routines that builds the queue file names given the message inode number
- Rewriting - Converts the recipient address, implementing the VERP and the "percent hack"
- Info - Reads the Info queue file, containing the return path (Sender address) of the message
- Communication - Handles writes though the pipes to the delivery subprocesses
- Cleanups - Handles communication to qmail-clean
- Priority Queues - Deals with the internal list of messages to deliver
- Jobs - Manges information regarding jobs, each is a delivery process.
- Bounces - Handles Bounced messges to the sender
- Deliveries - High-level delivery starting and tracking
- Passes - Makes a "pass" over the messages in a channel.
- Todo - The "To do" queue is a list of new messages that must be scheduled for delivery
Qmail-send is a busy process, but will first load the queue into the priority queue and initializes the various components above. It then will start to deliver any pending messages in the queue, filling up the maximum concurrent delivery jobs as available. It then sleeps until it gets a message send into one of its pipes: from a delivery process (lspawn, rspawn), the new-message trigger (see $QMAIL_HOME/queue/lock/trigger which is a named pipe which qmail-queue kicks whenver it inserts a new message.) It then checks and handles delivery results, processing the "to do" queue, makes another "pass" over the message delivery list, then handles any message cleanup. Then is tries to sleep again.
Such is the life of qmail-send. All this hard work, and no praise or thank yous.
Note to self: Qmail makes delivery attempys by individual devileries, not individual messages. Qmail will attempt to make all deliveries to a message concurrently. This means that if a message has 1000 recipients, it will try to deliver to each of those 1000 until theey have all been tried. After that message has been exhausted, it will get the next message out of the priority queue. This batch mentality is that qmail will process deliveries at only one message at a time within the channel (local/remote)! Therefore to qmail, each recipient of each message is ahead of all receipients of the next message; they must wait to receive their mail. This can cause an apparent bottle-neck in delivery, but really shouldn't be a problem for users who have one or a few recipients for a message.