This process consists of three parts: message data is read by a handler from the standard input, processed by the handler, and the result of the operation is written to the standard output.
The message is fed to the handler on the standard input. The handler should not expect the standard input to be seekable.
The input contains the message headers, an empty line, and the message body. The message ends when end-of-stream is encountered. The envelope information is not included here.
Lines are separated by bare LF in the message.
The handler is expected to produce the following output on standard error:
PASS The message should be passed further. The handler should write the message, possibly modified, on the standard output.
STOP The message should not be passed further and this is not an error. This should be used when the handler implements its own custom delivery instead of the delivery provided by the MTA. Subsequent handlers won't be called.
DEFERThe message should not be passed further. A temporary error condition should be indicated. Subsequent handlers won't be called.
REJECTThe message should not be passed further. A permanent error condition should be indicated. Subsequent handlers won't be called.
LOG text The line of text should be treated as a warning or error message and added to the appropriate log.
Each line of output on the standard error should be terminated with LF. After the first PASS, STOP, DEFER, or REJECT line, further output is not accepted, so any LOG lines must precede the above.
The exit code from the handler should be 0 on PASS or STOP and not 0 in other cases.
The handler should only write to its standard output after writing PASS or REJECT on the standard error.
For PASS, the output should be a message in the same format as found on input.
The exit code from the handler should be 0 on PASS or STOP and not 0 in other cases.
The handler will be invoked with the rights defined for its owner, regardless of those with which MTA is running. If specific rights for file system access are required, the handler should be given the SETUID bit.
The current working directory is undefined.
Most environment variables are removed, only the essential ones are left: PATH and LANG. The latter will be set to the value C.