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

Library Control APIs

» 

Technical documentation

Complete book in PDF

 » Table of Contents

This section describes the library control APIs that Sendmail 8.13.3 includes.

Filter applications use the library control APIs to provide the required information to Sendmail. Each of the library control APIs returns either MI_SUCCESS or MI_FAILURE to indicate the status of the operation. The library control APIs do not directly communicate with Sendmail, but they alter the state of the library.

Before handing control to libmilter (by calling smfi_main()), a filter application can call the following library control APIs to set the libmilter parameters:

  • smfi_register()

  • smfi_opensocket()

  • smfi_setconn()

  • settimeout()

  • smfi_setbacklog()

  • smfi_setdbg()

  • smfi_stop()

  • smfi_main()

The following sections discuss the library control APIs in detail.

The smfi_register() API

You can use the smfi_register() API to register a set of filter callbacks. You must call smfi_register() before calling the smfi_main() API. The smfi_register() API creates a filter using the information supplied by the smfiDesc argument. Do not call smfi_register() multiple times within a single process.

The declaration of smfi_register() is as follows:

#include <libmilter/mfapi.h>
int smfi_register(
        smfiDesc descr
);

Arguments

You must call smfi_register() with the following argument:

descr

Specifies a filter descriptor of type smfiDesc, which describes the functions of the filter. The smfiDesc contains the following members:

struct smfiDesc
{
      char*xxfi_name;    /* filter name */
      intxxfi_version;/* version code -- do not change */
      unsigned longxxfi_flags;/* flags */

     /* connection info filter */
     sfsistat(*xxfi_connect)(SMFICTX *, char *, _SOCK_ADDR *);
     /* SMTP HELO command filter */
     sfsistat(*xxfi_helo)(SMFICTX *, char *);
     /* envelope sender filter */
     sfsistat(*xxfi_envfrom)(SMFICTX *, char **);
     /* envelope recipient filter */
     sfsistat(*xxfi_envrcpt)(SMFICTX *, char **);
     /* header filter */
     sfsistat(*xxfi_header)(SMFICTX *, char *, char *);
     /* end of header */
     sfsistat(*xxfi_eoh)(SMFICTX *);
     /* body block */
     sfsistat(*xxfi_body)(SMFICTX *, unsigned char *, size_t);
     /* end of message */
     sfsistat(*xxfi_eom)(SMFICTX *);
      /* message aborted */
      sfsistat(*xxfi_abort)(SMFICTX *);
      /* connection cleanup */
      sfsistat(*xxfi_close)(SMFICTX *);
};

A NULL value for any callback indicates that the filter does not want to process the given type of information and the callback returns only SMFIS_CONTINUE.

For more information on callbacks, see “Callbacks”.

Table 2-1 “The xxfi_flags Field Values” describes the bitwise OR of zero or more values, which the xxfi_flags field can contain. The table also describes the possible actions of the filter.

Table 2-1 The xxfi_flags Field Values

FlagDescription
SMFIF_ADDHDRSAdds headers.
SMFIF_CHGHDRSChanges and deletes headers.
SMFIF_CHGBODYReplaces the body of the messageduring filtering. This can have significant performance impact if other filters filter the body after this filter.
SMFIF_ADDRCPTAdds recipients to the message.
SMFIF_DELRCPTRemoves recipients from the message.

 

Return Values

The smfi_register() API returns MI_FAILURE because of the following reasons:

  • Memory allocation failure

  • Incompatible version or illegal value of flags

The smfi_setconn() API

You can use the smfi_setconn() API to set the socket through which a filter must communicate with Sendmail. You must call setconn() before calling the smfi_main() API.

The declaration of smfi_setconn() is as follows:

#include <libmilter/mfapi.h>
int smfi_setconn{
       char *oconn;
};

Do not run filters as a root user when communicating over UNIX® or local domain sockets.

If you use the Sendmail RunAsUser option, you must set the permissions for UNIX or local sockets to 0600 (read/write permission only for the owner of the socket) or 0660 (read/write permission for the owner and group of the socket). To determine the permission for a UNIX or local domain socket, you can use the umask command and set umask to 007 or 077.

Arguments

You must call smfi_setconn() with the following argument:

oconn

Specifies the address of the desired communication socket. The address must be a NULL-terminated string in the following proto:address format:

  • {unix|local}:/path/to/file - Specifies a named pipe.

  • inet:port@{hostname|ip-address} - Specifies an IPV4 socket.

  • inet6:port@{hostname|ip-address} - Specifies an IPV6 socket.

Return Value

The smfi_setconn() API does not fail on an invalid address. The failure is only detected in the smfi_main() API.

The smfi_settimeout() API

You can use the smfi_settimeout() API to set the connection timeout value of the filter. The connection timeout value specifies the number of seconds the libmilter library must wait for an MTA connection before timing out a socket. If the filter application does not call smfi_settimout(), the filter application uses a default timeout value of 7210 seconds.

The declaration of smfi_settimout() is as follows:

#include <libmilter/mfapi.h>
int smfi_settimeout(
         int otimeout
);

Arguments

You must call smfi_settimeout() with the following argument:

otimeout

Specifies the timeout value in seconds. You must specify a timeout value greater than 0 (zero). A value of 0 signifies that a filter does not to wait and, it does not signify that a filter must wait forever.

Return Value

The smfi_settimeout() API always returns MI_SUCCESS to the filter program.

The smfi_main() API

You can use the smfi_main() API to transfer control to the libmilter event loop. You must call smfi_main() after initializing a filter.

The declaration of smfi_main() is as follows:

#include <libmilter/mfapi.h>
int smfi_main(
);

The smfi_main() API does not contain any arguments.

Return Value

When smfi_main() fails to establish a connection, it returns MI_FAILURE to the filter application. The failure can occur because of many reasons, such as invalid address passed to smfi_setconn(). The reason for the failure is logged in the syslog file.

The smfi_main() API returns MI_SUCCESS on success.

The smfi_opensocket() API

You can use the smfi_opensocket() API to create the interface socket that MTAs use to connect to the filter.

You can call smfi_opensocket() only from the program mainline, before calling smfi_main(). You can use smfi_opensocket() to create the socket previously specified by a call to the smfi_setconn() API, which is the interface between MTAs and the filter. This allows the calling application to ensure that the socket can be created.

If you do not call smfi_opensocket(), smfi_main() will do so implicitly.

The declaration for smfi_opensocket() is as follows:

#include <libmilter/mfapi.h>
int smfi_opensocket(
bool rmsocket
);

Arguments

You must call smfi_opensocket() with the following argument

smfi_opensocket

Specifies the flag that indicates whether the library must try to remove any existing UNIX domain socket before trying to create a new one.

Return Value

smfi_opensocket() fails and returns MI_FAILURE because of the following reasons:

  • The interface socket is not created.

  • rmsocket is true and either the socket is not examined or exists, and is not removed.

  • smfi_setconn() is not called.

smfi_opensocket() returns MI_SUCCESS on success.

The smfi_setdbg() API

You can use smfi_setdbg() to set the internal debugging or tracing level of the milter library to a new level to track the code details. You can use the smfi_setdbg() API to set the debugging or tracing level for the milter library. A level of 0 (zero) turns off debugging. If you increase the debugging level (more positive number), the details included in debugging also increases. A debugging value of 6 is the current, highest and useful debugging value.

The declaration of smfi_setdbg() is as follows:

#include <libmilter/mfapi.h>
int smfi_setdbg(
int level;
);

Argument

You must call smfi_setdbg() with the argument level, which specifies a new debugging level.

Return Value

By default, smfi_setdbg() returns MI_SUCCESS to the filter application.

The smfi_stop() API

You can use the smfi_stop() API to start an orderly shutdown of the Milter program. You can call smfi_stop() from any of the callbacks or any of the error-handling routines at any time. smfi_stop() causes each thread to finish its current connection and then exit the connection. When all the threads have exited, the call to the smfi_main() API returns to the calling program, which may then exit or warm restart the function (?). A filter application does not accept any new connection after calling smfi_stop().

The declaration of smfi_stop() is as follows:

#include <libmilter/mfapi.h>
int smfi_stop(void);

Argument

You must call smfi_stop() with the argument void, which specifies that smfi_stop() does not accept any argument.

Return Values

smfi_stop() always returns SMFI_CONTINUE to the Milter program.

Following are additional points regarding smfi_stop():

  • Another internal routine may have already requested the Milter program to abort.

  • Another routine may already have requested the Milter program to stop.

  • You cannot cancel the stop process when it has begun.