HPlogo Sendmail 8.13.3 Programmer's Guide: HP-UX 11i v1 and HP-UX 11i v2 > Chapter 2 Milter APIs

Callbacks

» 

Technical documentation

Complete book in PDF

 » Table of Contents

A filter application must implement one or more of the following callbacks, which are registered through the smfi_register() API:

  • xxfi_connect()

  • xxfi_helo()

  • xxfi_envfrom()

  • xxfi_envrcpt()

  • xxfi_header()

  • xxfi_eoh()

  • xxfi_body()

  • xxfi_eom()

  • xxfi_abort()

  • xxfi_close()

NOTE: You can replace the xx portion in the callback name with the name of your Milter program.

The following sections discuss these callbacks in detail.

The xxfi_connect() Callback

The xxfi_connect() callback returns the SMFIS_CONTINUE value to the calling filter application. xxfi_connect() is called once during the start of each SMTP connection.

The declaration of xxfi_connect() is as follows:

#include <libmilter/mfapi.h>
sfsistat (*xxfi_connect)(
            SMFICTX *ctx,
            char *hostname,
             _SOCK_ADDR *hostaddr);

If an earlier filter application rejects a connection in its xxfi_connect() callback, the current filter does not call xxfi_connect().

Arguments

You must call xxfi_connect() with the following arguments:

ctx

Specifies an opaque context structure.

hostname

Specifies the host name of the message sender, as determined by a reverse lookup on the host address. If the reverse lookup fails, hostname contains the IP address of the message sender enclosed in square brackets. For example, [a.b.c.d], where a.b.c.d denotes the IP address.

hostaddr

Specifies the host address, as determined by a getpeername() call on the SMTP socket. The value of hostaddr is NULL if the type is not supported in the current version or if the SMTP connection is made through stdin.

The xxfi_helo() Callback

The xxfi_helo() callback handles the HELO and EHLO commands. xxfi_helo() returns the SMFIS_CONTINUE value to the calling filter application. xxfi_helo() is called when the client sends a HELO or EHLO command. You can therefore call xxfi_helo() multiple times or you can also refrain from calling this callback.

The declaration of xxfi_helo() is as follows:

#include <libmilter/mfapi.h>
sfsistat (*xxfi_helo)(
         SMFICTX * ctx,
          char * helohost
);

Arguments

You must call xxfi_helo() with the following arguments:

ctx

Specifies an opaque context structure.

helohost

Specifies the value that is passed to HELO or EHLO, which must be the domain name of the sending host.

The xxfi_envfrom() Callback

The xxfi_envfrom() callback handles the envelope FROM command. xxfi_envfrom() returns the SMFIS_CONTINUE value to the calling filter application. xxfi_envfrom() is called once during the beginning of each message and before calling the xxfi_envrcpt() callback.

The declaration of xxfi_envfrom() is as follows:

#include <libmilter/mfapi.h>
sfsistat (*xxfi_envfrom)(
           SMFICTX * ctx,
           char ** argv
);

Arguments

You must call xxfi_envfrom() with the following arguments:

ctx

Specifies an opaque context structure.

argv

Specifies null-terminated SMTP command arguments. argv[0] denotes the address of the sender. Later arguments, such as argv[1], argv[2], denote ESMTP arguments.

For more information on ESTMP responses, see RFC 1869 (SMTP Service Extensions).

Return Values

xxfi_envfrom() returns the following values:

SMFIS_TEMPFAIL

Rejects the sender and message with a temporary error. The filter application does not call the xxfi_abort() callback to abort the message and you can specify a subsequent new message.

SMFIS_REJECT

Rejects the sender and message. The filter application does not call the xxfi_abort() callback to abort the message and you can specify a subsequent new message.

SMFIS_DISCARD

Accepts and silently discards a message. The filter application does not call the xxfi_abort() callback to abort the message.

SMFIF_ACCEPT

Accepts the message. The filter application does not call the xxfi_abort() callback to abort the message.

The xxfi_envrcpt() Callback

The xxfi_envrcpt() API handles the envelope RCTP command. xxfi_envrcpt() returns SMFIS_CONTINUE to the calling filter application. You can call xxfi_envrcpt() once for every recipient. If a message contains multiple recipients, you can call xxfi_envrcpt() multiple times, immediately after the xxfi_envfrom() callback.

The declaration of xxfi_envrcpt() is as follows:

#include <libmilter/mfapi.h>
sfsistat (*xxfi_envrcpt)(
          SMFICTX * ctx,
           char ** argv
);

Arguments

You must call xxfi_envrcpt() with the following arguments:

ctx

Specifies an opaque context structure.

argv

Specifies null-terminated SMTP command arguments. argv[0] denotes the address of the recipient. Later arguments, such as argv[1], argv[2], denote ESMTP arguments.

For more information on ESTMP responses, see RFC 1869 (SMTP Service Extensions).

Return Values

xxfi_envrcpt() returns the following values:

SMFIS_TEMPFAIL

Fails temporarily for a recipient but the filter application processes further recipients because the filter application does not call the xxfi_abort() callback to abort the message.

SMFIS_REJECTS

Rejects a recipient but the filter application processes further recipients because the filter application does not call the xxfi_abort() callback to abort the message.

SMFIS_DISCARD

Accepts and discards the message. The filter application does not call the xxfi_abort() callback to abort the message.

SMFIS_ACCEPT

Accepts the recipient. The filter application does not call the xxfi_abort() callback to abort the message.

The xxfi_header() Callback

The xxfi_header() handles the message header and returns the SMFIS_CONTINUE value to the calling filter application. You can call xxfi_header() multiple times after calling the xxfi_envrcpt() callback and before calling the xxfi_eoh() callback, and once for each message header. Later filter applications can observe the header changes or additions made by earlier filter applications.

The declaration of xxfi_header() is as follows:

#include <libmilter/mfapi.h>
sfsistat (*xxfi_header)(
         SMFICTX * ctx,
          char * headerf,
          char * headerv
);

Arguments

You must call xxfi_header() with the following arguments:

ctx

Specifies an opaque context structure.

headerf

Specifies the header field name.

headerv

Specifies the header field value. The header content can include folded white space, that is, multiple lines followed by a white space. The filter application removes the trailing line terminator (CR or LF).

The xxfi_eoh() Callback

The xxfi_eoh() callback handles the end of message headers and returns SMFIS_CONTINUE to the calling filter application. You must call xxfi_eoh() only once after all the headers are sent and processed.

Argument

You must call xxfi_eoh() with the ctx argument, which specifies an opaque context structure.

The xxfi_body() Callback

The xxfi_body() callback handles a portion of message body and returns the SMFIS_CONTINUE value to the calling filter application. The filter application calls xxfi_body() multiple times after calling the xxfi_eoh() callback and before calling the xxfi_eom() callback.

The declaration of xxfi_body() is as follows:

#include <libmilter/mfapi.h>
sfsistat (*xxfi_body)(
          SMFICTX * ctx,
           unsigned char * bodyp,
           size_t len
);

Following are some points to consider regarding xxfi_body():

  • The bodyp argument points to a sequence of bytes and it is not a C string that is a sequence of characters terminated by a null character (\0). You must not use the normal C string functions, such as strlen() to modify the block of data. The byte sequence in the block can also contain \0 characters. If you add a trailing \0 character, C string functions can still fail to work in the block.

  • Because message bodies can be large, defining xxfi_body() significantly impacts the filter performance.

  • The filter application represents end-of-lines as received from the SMTP transaction (normally as CR or LF).

  • Later filter applications observe body changes made by earlier filter applications.

  • You can send message bodies in multiple portions with one call to xxfi_body() per portion.

Arguments

You must call xxfi_body() with the following arguments:

ctx

Specifies an opaque context structure.

bodyp

Specifies a pointer to the beginning of a block of body data. bodyp is not valid outside a call to the xxfi_body() callback.

len

Specifies the amount of data pointed by bodyp.

The xxfi_eom() Callback

The xxfi_eom() callback denotes the end of a message and returns the SMFIS_CONTINUE value to the calling filter application. xxfi_eom() is called once after all calls to the xxfi_body() callback for a given message.

The declaration of xxfi_eom() is as follows:

#include <libmilter/mfapi.h>
sfsistat (*xxfi_eom)(
         SMFICTX * ctx
);

A filter application must make all its modifications to the message headers, body, and envelope in xxfi_eom() callback. These modifications are made through the smfi_* APIs.

Argument

You must call xxfi_eom() API with the ctx argument, which specifies an opaque context structure.

The xxfi_abort() Callback

The xxfi_abort() callback handles the messages that are aborted. xxfi_abort() returns the SMFIS_CONTINUE value to the calling filter application. You can call xxfi_abort() any time while processing the message, that is between a message-oriented API and the xxfi_eom() callback.

The declaration of xxfi_abort() is as follows:

#include <libmilter/mfapi.h>
sfsistat (*xxfi_abort)(
          SMFICTX * ctx
);

Following are some points to consider regarding xxfi_abort():

  • xxfi_abort() must reclaim any resource allocated on a per-message basis and must be tolerant of being called between any two message-oriented callbacks.

  • Calls to xxfi_abort() and xxfi_eom() are mutually exclusive.

  • xxfi_abort() is not responsible for reclaiming connection-specific data because xxfi_close() is always called when a connection is closed.

  • Because xxfi_abort() aborts the message, the filter application ignores the return value of xxfi_abort().

  • xxfi_abort() is called only if the message is aborted outside the control of the filter application and if the filter application has not completed its message-oriented processing. For example, if a filter has already returned the values SMFIS_ACCEPT, SMFIS_REJECT, or SMFIS_DISCARD from a message-oriented routine, xxfi_abort() is not called even if the message is aborted later outside its control.

Argument

You must call xxfi_abort() with the ctx argument, which specifies an opaque context structure.

The xxfi_close() Callback

The xxfi_close() callback denotes that the current connection is closed. It returns the SMFIS_CONTINUE value to the calling filter application. The filter application always calls xxfi_close() once at the end of each connection.

The declaration of xxfi_close() is as follows:

#include <libmilter/mfapi.h>
sfsistat (*xxfi_close)(
         SMFICTX * ctx
);

Following are some points to consider regarding xxfi_close():

  • You can call xxfi_close() in any order, that is, you can call xxfi_close() even before calling xxfi_connect(). After establishing a connection with the filter application, if Sendmail decides to discard the traffic of a connection, Sendmail does not pass data to the filter application until the client closes down the connection. This is this time when xxfi_close() is called to close the connection.

  • xxfi_close() is called on close even if the previous mail transaction was aborted.

  • xxfi_close() is responsible for freeing any resource allocated on a per-connection basis.

  • The filter application ignores the return value of xxfi_close() because after the connection is closed, the return value does not hold any importance.

Argument

You must call xxfi_close() with the ctx argument, which specifies an opaque context structure.