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

Message Modification APIs

» 

Technical documentation

Complete book in PDF

 » Table of Contents

The message modification APIs change the contents and attributes of a message. These APIs include additional communication with the MTA and return either MI_SUCCESS or MI_FAILURE to indicate the status of the operation. You can call these APIs only in the xxfi_eom() callback.

A filter program must set the appropriate flag in the description passed to the smfi_register() API to call any message modification function. The MTA treats a call to the function as a failure of the filter program and terminates its connection when a filter program does not set the appropriate flag.

The status returned indicates only whether the message of the filter was successfully sent to the MTA and does not indicate whether the MTA has performed the requested operation. For example, when the smfi_addheader() API is called with an illegal header name, smfi_addheader() returns MI_SUCCESS even though the MTA can later refuse to add the illegal header.

Following are the message modification APIs:

  • smfi_addheader()

  • smfi_chgheader()

  • smfi_insheader()

  • smfi_addrcpt()

  • smfi_delrcpt()

  • smfi_replacebody()

  • Other message modification APIs

The following sections discuss the message modification APIs in detail.

The smfi_addheader() API

You can use the smfi_addheader() API to add a header to the current message. You can call smfi_addheader() only from the xxfi_eom() callback.

The declaration for smfi_addheader() is as follows:

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

Following are some points to consider regarding smfi_addheader():

  • smfi_addheader() does not change existing headers of a message. To change the current value of a header, use smfi_chgheader().

  • A filter which calls smfi_addheader() must set the SMFIF_ADDHDRS flag in the smfiDesc_str passed to the smfi_register() API.

  • For smfi_addheader(), the order of the filter program is important. Later filters will observe the header changes made by earlier filters.

  • The filter program does not check the name and the value of the header for standards compliance. However, each line of the header must be less than 2048 characters. If you require longer headers, use multiline headers. To make a multiline header, insert a LF (ASCII 0x0 character or \n in C language) followed by at least a white space character, such as a space (ASCII 9x20) or a tab (ASCII 0x09 or \t in C language) character.

    You must not precede the LF with a CR (ASCII 0x0d character) because the MTA adds the CR automatically. You must ensure that you do not violate any standards.

Arguments

You must call smfi_addheader() with the following arguments:

ctx

Specifies an opaque context structure.

headerf

Specifies the header name, which is a non-NULL string.

headerv

Specifies the header value. headerv is a non-NULL, null-terminated string. headerv can also be an empty string.

Return Values

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

  • headerf or headerv value is NULL.

  • Adding headers in the current connection state is invalid.

  • Memory allocation fails.

  • Network error occurs.

  • SMFIF_ADDHDRS is not set when the smfi_register() API is called.

smfi_addheader() returns MI_SUCCESS on success.

Example

Following is an example for smfi_addheader():

int ret;
    SMFICTX *ctx;

...

ret = smfi_addheader(ctx, "Content-Type", 
    "multipart/mixed;\n\tboundary='foobar'");

The smfi_chgheader() API

You can use the smfi_chgheader() API to change or delete a message header. You can call smfi_chgheader() only from the xxfi_eom() callback.

The declaration of smfi_chgheader() is as follows:

#include <libmilter/mfapi.h>
int smfi_chgheader(
         SMFICTX *ctx,
         char *headerf,
         mi_int32 hdridx,
         char *headerv
);

Following are some points to consider regarding smfi_chgheader():

  • While you can use smfi_chgheader() to add new headers, it is efficient to use the smfi_addheader() API.

  • A filter program that calls the smfi_chgheader() API must set the SMFIF_CHGHDRS flag in the smfiDesc_str passed to the smfi_register() API.

  • The filter order is important for the smfi_chgheader() API. A filter application placed later in the sequence observes the changes already done by earlier filters.

  • The filter program does not check the name and the value of the header for standards compliance. However, each line of the header must be less than 2048 characters. If you require longer headers, use multiline headers. To make a multiline header, insert a LF (ASCII 0x0 character or \n in C language) followed by at least a white space character, such as a space (ASCII 9x20) or a tab (ASCII 0x09 or \t in C language) character.

    You must precede the LF with a CR (ASCII 0x0d character) because the MTA adds the CR automatically. You must ensure that you do not violate any standards.

Arguments

You must call smfi_chgheader() with the following arguments:

ctx

Specifies an opaque context structure.

headerf

Specifies the header name, which is a a non-NULL, null-terminated string.

hdridx

Specifies the header index value (1-based). A hdridx value of 1 modifies the first occurrence of a header named headerf. If hdridx is greater than the number of occurrences of headerf, a new copy of headerf is added.

headerv

Specifies the new value of the given header. A value of NULL to headerv implies that you must delete the header.

Return Values

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

  • headerf is NULL.

  • Modifying headers in the current connection state is invalid.

  • Memory allocation failure.

  • Network error occurs.

  • SMFIF_CHGHDRS is not set when smfi_register() is called.

smfi_chgheader() returns MI_SUCCESS on success.

Example

Following is an example of smfi_chgheader():

int ret;
SMFICTX *ctx;

...

ret = smfi_chgheader(ctx, "Content-Type", 1,
                     "multipart/mixed;\n\tboundary='foobar'");

The smfi_insheader() API

You can use the smfi_insheader() API to prepend a header to the current message. You can call smfi_insheader() only from the xxfi_eom() callback.

The declaration of smfi_insheader() is as follows:

#include <libmilter/mfapi.h>
int smfi_insheader(
          SMFICTX *ctx,
           int hdridx,
            char *headerf,
             char *headerv
);

Following are some points to consider regarding smfi_insheader():

  • smfi_insheader() does not change the existing headers of a message. To change the current value of a header, use the smfi_chgheader() API.

  • A filter application that calls the smfi_insheader() API must set the SMFIF_ADDHDRS flag in smfiDesc_str passed to the smfi_register() API.

  • For smfi_insheader(), the order in which you place filter applications is important. Filter applications placed later in the sequence observe changes already done by earlier filter applications. If the value of hdridx is larger than the number of headers in the message, the header is simply appended. The filter application does not check the name and the value of the header for standards compliance. However, each line of the header must be less than 2048 characters. If you need longer headers, use a multiline header. To make a multiline header, insert a LF (an ASCII 0x0a character, or \n in C) followed by at least one white space character, such as, a space (an ASCII 0x20 character) or tab (an ASCII 0x09 character, or \n in C).

    You must precede the LF with a CR (an ASCII 0x0d character) because the MTA adds this automatically. You must ensure that you do not violate any standards.

Arguments

You must call smfi_insheader() with the following arguments:

ctx

Specifies an opaque context structure.

hdridx

Specifies the location in the internal header list where you must insert this header. If the value is set to 0, hdridx is the first header.

headerf

Specifies the header name, which is a non-NULL, null-terminated string.

headerv

Specifies the header value, which is a non-NULL, null-terminated string. You can set headerv to an empty argument.

Return Values

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

  • The headerf value or headerv value is NULL.

  • Adding headers in the current connection state is invalid.

  • Memory allocation fails.

  • Network error occurs.

  • SMFIF_ADDHDRS is not set when the smfi_register() is called.

smfi_insheader() returns MI_SUCCESS on success.

Example

Following is an example of smfi_insheader():

int ret;
SMFICTX *ctx;

...

ret = smfi_insheader(ctx, 0, "First", "See me?");

The smfi_addrcpt() API

You can use the smfi_addrcpt() API to add a recipient for the current message. You can call smfi_addrcpt() only from the xxfi_eom() callback.

The declaration for smfi_addrcpt() is as follows:

#include <libmilter/mfapi.h>
int smfi_addrcpt(
        SMFICTX *ctx,
        char *rcpt
);

A filter program that calls smfi_addrcpt() must set the SMFIF_ADDRCPT flag in the smfiDesc_str structure passed to smfi_register().

Arguments

You must call smfi_addrcpt() with the following arguments:

ctx

Specifies an opaque context structure.

rcpt

Specifies the new address of the recipient.

Return Values

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

  • The rcpt value is NULL.

  • Adding recipients in the current connection state is invalid.

  • Network error occurs.

  • The SMFIF_ADDRCPT flag is not set when the smfi_register() routine is called.

The smfi_delrcpt() API

You can use the smfi_delrctp() API to delete a recipient from the envelope of the current message. You can call smfi_delrcpt() only from the xxfi_eom() callback.

The declaration for smfi_delrctp() is as follows:

#include <libmilter/mfapi.h>
int smfi_delrcpt(
        SMFICTX *ctx;
        char *rcpt;
);

The address is not deleted if an address and its expanded form do not match.

Arguments

You must call smfi_delrcpt() with the following arguments:

ctx

Specifies an opaque context structure.

rcpt

Specifies the recipient address to be removed. The recipient address is a non-NULL, null-terminated string.

Return Values

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

  • The rcpt variable is NULL.

  • Deleting recipients in the current connection state is invalid.

  • Invalid error occurs.

  • The SMFIF_DELRCPT is not set when the smfi_register() routine is called.

smfi_delrcpt() returns MI_SUCCESS on success.

The smfi_replacebody() API

You can use the smfi_replacebody() API to replace the data in the message body. Use smfi_replacebody() only from the xxfi_eom() callback.

You must not call smfi_replacebody() more than once. If you call smfi_replacebody() more than once, the subsequent smfi_replacebody() calls append data to the new body of the message.

The declaration of smfi_replacebody() is as follows:

#include <libmilter/mfapi.h>
int smfi_replacebody(
        SMFICTX *ctx,
        unsigned char *bodyp,
        int bodylen
);

Following are some points to consider regarding smfi_replacebody():

  • As the message body can be very large, setting SMFIF_CHGBODY can significantly affect the performance of the filter program.

  • If a filter program sets SMFIF_CHGBODY but does not call smfi_replacebody(), the original body remains unchanged.

  • The filter order is important for smfi_replacebody(). Filters placed later in the sequence observe the changes created by earlier filters.

Arguments

You can call smfi_replacebody() with the following arguments:

ctx

Specifies an opaque context structure.

bodyp

Denotes a pointer to the start of the new body data, which need not be null-terminated. If you set bodyp to NULL, the length of the body is considered to be 0 (zero). The body data must be in CR or LF form.

bodylen

Specifies the number of data bytes pointed by bodyp.

Return Values

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

  • The value of bodyp is equal to NULL and the value of bodylen is greater than 0.

  • Changing the body in the current connection state is invalid.

  • Network error occurs.

  • The SMFIF_CHGBODY is not set when the smfi_register() routine is called.