Sendmail has got a very flexible and fully-featured mail filtering system, of which the plug-in part is called Milter.
The current method that Sendmail employs with Milter is to send the envelope information to the filter while the message is still "on-the-wire". Once the envelope information is received, Sendmail calls the "collect()" function to transfer the message body to a file. After the message body has been collected, the filter is called blockwise with the data in this file.
The obvious side-effect is that envelope information can be used "on-the-wire", but message body (including message headers, etc.) can only be processed after the whole mail has been collected. This project implements an option that allows the body to be sent to the filter "on-the-fly".
A flag in the sendmail.mc INPUT_MAIL_FILTER function sets the filter's mf_flags to allow on-the-fly scanning ('I', for "inline").
smtp_data(), collect(), milter_data() and milter_body() are modified to be interleaved, in stead of pipelined.
Everything happens the same until right before the body needs to be collected.
All the filters with the `F=I' flag are called with the body chunks as they are being received. The current copy-to-file mechanism is still be used (i.e. collect() copies the data to a file, butthe file is forwarded on a chunk-by-chunk basis through to the filters).
Then all the filters without the `F=I' flag are called on the collected data and body.
Finally, the rest of the milter functions are called on all filters.