The MTA SDK is explicitly initialized. This call is not really necessary as the MTA SDK will implicitly initialize itself when mtaDequeueStart() is called. However, for debugging purposes, it can be useful to make this call at the start of a program so that an initialization failure will show clearly in the diagnostic output. If the call is omitted, initialization failure will be less obvious. The failure will still be noted in the diagnostic output, but it will be obscured through the routine call that triggered implicit initialization.
Channel options are loaded via a call to the load_options() routine. That routine is part of this example and, as discussed later, uses the SDK routines for obtaining channel option values from the channel’s option file.
The message dequeue processing loop is initiated with a call to mtaDequeueStart().
For each queued message to be processed, process_message() will be called by mtaDequeueStart().
A message enqueue is started. This enqueue is used to re-enqueue the queued message currently being processed. As the message is processed, its non-harmful content will be copied to the new message being enqueued.
The envelope recipient list is copied from the queued message to the new message being enqueued.
Since this is an intermediate channel, that is, it doesn’t effect final delivery of a message, successful processing of a recipient address is associated with a disposition of MTA_DISP_RELAYED.
After processing the message’s envelope, mtaDecodeMessage() is invoked to decode the message, breaking it into individual MIME message parts. mtaDecodeMessage() is told to use the current dequeue context as the input source for the message to decode. This supplies the queued message being processed as input to the MIME decoder. Further, the current enqueue context is supplied as the output destination for the resulting message. This directs mtaDecodeMessage() to output the resulting parsed message to the message being enqueued, less any harmful attachments that are explicitly deleted by the inspection routine. The routine decode_inspect() is supplied as the inspection routine. If the call to mtaDecodeMessage() fails, the CHECK() macro causes the queued message to be deferred and the message enqueue to be cancelled.
After a successful call to mtaDecodeMessage(), the message enqueue is committed. It is important that this be done before committing the dequeue. If the operation is done in the other order– dequeue finish followed by enqueue finish– then mail may be lost. For example, the message would be lost if the dequeue succeeds and then deletes the underlying message file before the enqueue, and then the enqueue fails for some reason, such as insufficient disk space.
The inspection routine, decode_inspect(). This routine checks the MIME header lines of each message part for indication that the part may contain harmful content.
Message parts with harmful content are discarded with a call to mtaDecodeMessagePartDelete(). The discarded message part is replaced with a text message part containing a warning about the discarded harmful content.
Message parts with safe content are kept by copying them to the output message with mtaDecodeMessagePartCopy().
Using the configured channel options, this routine determines if a message part’s media type is in the list of harmful types.
Using the configured channel options, this routine determines if a filename appearing in the MIME header lines has an extension considered harmful.
The load_options() routine is used to load the channel’s site-configured options from a channel option file.
The channel option file, if any, is opened and read by mtaOptionStart(). Since an explicit file path is not supplied, the file path specified with the PMDF_CHANNEL_OPTION environment variable gives the name of the option file to read.
After loading the channel’s options, the option file context is disposed of with a call to mtaOptionFinish().