Postfix enhanced status code implementation notes ================================================= RFC 3463 Enhanced status code support is implemented in stages. In the first stage, the goal is to minimize code changes (it's several hundred pages of context diffs already). For this reason, the pre-existing status variables (success, defer, etc.) are still updated separately from the diagnostic text and the RFC 3463 enhanced status code. All this means that one has to be careful when updating the code, to keep things in sync. Specific issues that one should be aware of: - In the SMTP client, update the enhanced status code and text whenever smtp_errno or resp->code are updated, or place an explicit comment that says no update is needed. - In the SMTP client, don't worry about the initial enhanced status digit when reporting failure to look up or connect to a host. For convenience, the SMTP client top-level code automatically changes the initial digit into '4' or '5' as appropriate. - In the SMTP server, don't worry about the initial enhanced status code digit when an smtpd_mumble_restriction rejects access. For convenience, the smtpd_check_reject() routine automatically changes the initial digit into '4' or '5' as appropriate. - Some low-level support routines update the diagnostic text but not the enhanced status code. To identify these, search for functions that are called with why->vstring as output parameter, and make sure that the caller updates the enhanced status code in all appropriate cases. - By design, the pipe, local and virtual delivery agent code never update the diagnostic text separately from the enhanced status code. - Don't rely on the system errno value after calling a routine that performs or prepares for mail delivery. Instead, have that routine update the enhanced status code (and text) when the error happens. This was an issue with mailbox, maildir and file delivery. Currently there remains one exception to this errno usage rule; the maildir delivery routines log a helpful warning when delivery fails with EACCES. The latter happens to work because mbox_open() does not need to unlock the output file, so it won't clobber the errno value. - Avoid passing around strings that combine enhanced status code and diagnostic text. Instead, use separate variables for status code and text, so that the compiler can enforce that everything has a status code. Currently there are two exceptions to this rule: the cleanup server status reply, and the delivery agent status reply. Once these protocols are updated we can remove the dns_prepend() routine. The third exception, enhanced status codes in external command output, is a feature. - The bounce/defer/sent library modules will catch the cases where an enhanced status code does not match the reject/defer/success status. They log a warning message, and replace the incorrect enhanced status code by a generic one.