Sun Java System Messaging Server 6 2005Q4 MTA Developer's Reference

Chapter 6 MTA SDK Reference

The Sun Java System Messaging Server MTA SDK consists of numerous routines used to facilitate the enqueuing and dequeuing of messages. This reference chapter contains definitions of all of the SDK routines, and has the following sections:

Summary of SDK Routines

This sections contains a series of tables, one for each of the following logical groups of commands:

Each table lists the routines that comprise the group and gives a brief description of each.

Address Parsing

Address parsing routines are used to parse and extract message addresses.

Routine Name  

Description  

mtaAddressFinish()

Dispose of an address context 

mtaAddressGetN()

Extract the Nth individual address from a list of parsed addresses 

mtaAddressParse()

Parse a list of addresses, producing an address context 

Dequeue

Dequeue routines are used for dequeuing messages.

Routine Name  

Description  

mtaDequeueInfo()

Obtain information about a queued message 

mtaDequeueLineNext()

Obtain the next message line from a queued message 

mtaDequeueMessageFinish()

Complete or cancel a message dequeue 

mtaDequeueRecipientDisposition()

Set the disposition of a recipient address 

mtaDequeueRecipientNext()

Obtain the next recipient address from a queued message 

mtaDequeueRewind()

Move the read point for a queued message back to the start of its outermost header 

mtaDequeueStart()

Begin processing queued messages 

mtaDequeueThreadId()

Return the thread ID associated with the specified dequeue context. 

Enqueue

Enqueue routines are used for enqueuing messages.

Routine Name  

Description  

mtaEnqueueCopyMessage()

Copy a message from a dequeue context 

mtaEnqueueFinish()

Complete or cancel a message submission 

mtaEnqueueInfo()

Obtain information about a message submission 

mtaEnqueueStart()

Begin a message submission 

mtaEnqueueTo()

Add recipients to a message 

mtaEnqueueWrite()

Output a line to the message header or body 

mtaEnqueueWriteLine()

Output a line to the message header or body 

Error Handling

Error handling routines used for error status retrieval.

Routine Name  

Description  

mtaErrno()

Obtain the value of the last error status for this thread 

mtaStrError()

Map an error status code to a printable string 

Initialization

These routines are used for initialization.

Routine Name  

Description  

mtaDone()

Release resources used by the MTA SDK 

mtaInit()

Initialize the MTA SDK 

Logging and Diagnostics

Logging and diagnostics routines are used to write diagnostic messages to debug log files.

Routine Name  

Description  

mtaDebug()

Write internal diagnostic information to the debug log file 

mtaLog()

Write to the debug log file 

mtaLogv()

Write to the debug log file 

MIME Parsing and Decoding

These routines are used to parse and decode a MIME formatted message.

Routine Name  

Description  

mtaDecodeMessage()

Decode a MIME formatted message; can also convert non-MIME formats to MIME 

mtaDecodeMessagePartCopy()

Copy a message part 

mtaDecodeMessagePartDelete()

Delete a message part 

mtaDecodeMessageInfoInt()

Obtain the value of an integer-valued parameter 

mtaDecodeMessageInfoString()

Obtain the value of a string-valued parameter 

mtaDecodeMessageInfoParams()

Obtain the Content-type or Content-disposition parameter list

Miscellaneous

These routines are used for miscellaneous tasks.

Routine Name  

Description  

mtaAccountingLogClose()

Close the MTA accounting log file 

mtaAddressToChannel()

Determine which channel an address rewrites to 

mtaBlockSize()

Obtain the value of the MTA BLOCK_SIZE option

mtaChannelGetName()

Obtain the channel name for the running program 

mtaChannelToHost()

Determine the host name associated with a channel 

mtaDateTime()

Generate a date-time string for use in an RFC 822 Date: header line

mtaPostmasterAddress()

Obtain the postmaster’s address 

mtaStackSize()

Obtain the minimum thread stack size needed for arbitrary SDK operations 

mtaUniqueString()

Generate a unique string 

mtaVersionMajor()

Obtain the major version number of the MTA SDK 

mtaVersionMinor()

Obtain the minor version number of the MTA SDK 

mtaVersionRevision()

Obtain the revision number of the MTA SDK 

Option File Processing

The following table lists the routines used to process option files and gives a brief description of each.

Routine Name  

Description  

mtaOptionStart()

Open and read a channel option file 

mtaOptionInt()

Obtain the value associated with an integer-valued option 

mtaOptionFloat()

Obtain the value associated with a real-valued option 

mtaOptionString()

Obtain the value associated with a string-valued option 

mtaOptionFinish()

Dispose of an option file context 

MTA SDK Routines

This section describes each MTA SDK routine, including its syntax, arguments and return values, and gives a description of the routine. The following table lists the routines in alphabetical order, as they are found in this section:

Routine Name and Page  

mtaAccountingLogClose()

mtaAddressFinish()

mtaAddressGetN()

mtaAddressParse()

mtaAddressToChannel()

mtaBlockSize()

mtaChannelGetName()

mtaChannelToHost()

mtaDateTime()

mtaDebug()

mtaDecodeMessage()

mtaDecodeMessageInfoInt()

mtaDecodeMessageInfoParams()

mtaDecodeMessageInfoString()

mtaDecodeMessagePartCopy()

mtaDecodeMessagePartDelete()

mtaDequeueInfo()

mtaDequeueLineNext()

mtaDequeueMessageFinish()

mtaDequeueRecipientDisposition()

mtaDequeueRecipientNext()

mtaDequeueRewind()

mtaDequeueStart()

mtaDequeueThreadId()

mtaDone()

mtaEnqueueCopyMessage()

mtaEnqueueError()

mtaEnqueueFinish()

mtaEnqueueInfo()

mtaEnqueueStart()

mtaEnqueueTo()

mtaEnqueueWrite()

mtaEnqueueWriteLine()

mtaErrno()

mtaInit()

mtaLog()

mtaLogv()

mtaOptionFinish()

mtaOptionFloat()

mtaOptionInt()

mtaOptionStart()

mtaOptionString()

mtaPostmasterAddress()

mtaStackSize()

mtaStrError()

mtaUniqueString()

mtaVersionMajor()

mtaVersionMinor()

mtaVersionRevision()

mtaAccountingLogClose()

Close the MTA accounting log file, mail.log_current.

Syntax

void mtaAccountingClose(void)

Arguments

None

Description

Long running programs should periodically close the MTA accounting log file with this routine. Interactive programs that use the MTA SDK should use the mtaInit() item code when initializing the SDK with mtaInit().

Return Values

None

Example

None

mtaAddressFinish()

Dispose of an address context.

Syntax

void mtaAddressFinish(mta_adr_t *adr_ctx);

Arguments

Argument  

Description  

adr_ctx

An address context created by a previous call to mtaAddressParse().

Description

Address contexts created with mtaAddressParse() must be disposed of by calling mtaAddressFinish(). Failure to do so will result in memory leaks.

Return Values

None

Example

None

mtaAddressGetN()

Extract an address from a list of parsed addresses.

Syntax


int mtaAddressGetN(mta_adr_t   *adr_ctx,
                   size_t       address_index,
                   const char **address,
                   size_t      *address_len,
                   int          elements);

Arguments

Arguments  

Description  

adr_ctx

An address context created by a previous call to mtaAddressParse().

address_index

Index of the address to retrieve. It is an index into a list of addresses. The first address has an index of 0. 

address

Pointer to receive the selected address (a pointer to a buffer within the address context). The address will be NULL terminated. A NULL may be passed for this call argument if you do not wish to receive the pointer. 

address_len

The length in bytes of the selected address, not including any NULL terminator. NULL may be passed for this call argument if you do not wish to receive the length. 

elements

A bitmask indicating which RFC 822 mailbox elements of the address to return, such as phrase, route, local-part, or domain. Any combination of these elements may be returned. 

Description

This routine retrieves the Nth address from a list of parsed addresses. The list of addresses must first be parsed with mtaAddressParse().

Either the entire address or just a portion of it may be retrieved.

Elements Argument

Using the nomenclature of RFC 822, an address has the following four-element format:

phrase <@route:local-part@domain>

Note –

The @route: element is referred to as a source route and is rarely seen.


An example address with all four elements is:

Judy Smith <@siroe.com:judy.smith@email.siroe.com>

The elements argument is a bitmask indicating which of these elements to return. The bitmask is formed by a logical OR of the following symbolic constants defined in the mtasdk.h header file:

For example, to select just the local and domain parts, use the following value for the elements argument:

MTA_ADDR_LOCAL | MTA_ADDR_DOMAIN

When a value of zero is supplied for elements the following default bitmask is assumed:

MTA_ADDR_ROUTE | MTA_ADDR_LOCAL | MTA_ADDR_DOMAIN

Address Argument

This routine returns a pointer to the retrieved address and not the address itself. This pointer is to a buffer within the address context. Each time the routine is called with the same address context, that buffer is overwritten. Therefore, care must be taken when specifying the address argument. The following code example correctly specifies how the argument should be used when multiple calls are involved:


mtaAddressGetN(adr_ctx, 0, &ptr, NULL, MTA_ADDR_LOCAL);
strcpy(buf, ptr);
strcat(buf, "@");
mtaAddressGetN(adr_ctx, 0, &ptr, NULL, MTA_ADDR_DOMAIN);
strcat(buf, ptr);

Alternately, it could also be coded as shown in the following code fragment:


mtaAddressGetN(adr_ctx, 0, &ptr, NULL,
               MTA_ADDR_LOCAL | MTA_ADDR_DOMAIN);
strcpy(buf, ptr);

However, since the pointer points to the same buffer for each call, and is overwritten at each call, it would be incorrect to code it as shown in the following code example:


mtaAddressGetN(adr_ctx, 0, &local, NULL, MTA_ADDR_LOCAL);
mtaAddressGetN(adr_ctx, 0, &domain, NULL, MTA_ADDR_DOMAIN);
strcpy(buf, local);
strcat(buf, "@");
strcat(buf, domain);

Return Values

Return Value  

Description  

0

Normal, successful completion 

MTA_BADARGS

One of the following conditions occurred: 

  1. A NULL value for the adr_content argument

  2. An invalid address context

  3. An invalid bitmask for elements

MTA_EOF

The value supplied for the address_index is equal to or greater than the number of addresses in the address list.

Example

The following is a code fragment that parses and displays the individual addresses from a list of two addresses, using mtaAddressGetN():


ires = mtaAddressParse(&adr_ctx, &adr_count,
        "Judy Public <judy.public@siroe.com\>, sue@siroe.com",
        0, 0);
for (i = 0; i < adr_count; i++)
{
    mtaAddressGetN(adr_ctx, i, &ptr, NULL,
                    MTA_ADDR_LOCAL | MTA_ADDR_DOMAIN);
    printf("Address %d: %s\n", i, ptr);
}

mtaAddressParse()

Parse a list of comma separated RFC 822 addresses.

Syntax


int mtaAddressParse(mta_adr_t **adr_ctx,
                    size_t     *address_count,
                    const char *address_list,
                    size_t      address_list_len,
                    int         item_code, ...);

Arguments

Argument  

Description  

adr_ctx

The address context created for the parsed list of addresses. 

address_count

The number of addresses parsed. 

address_list

A character string containing the list of comma separated RFC 822 addresses to be parsed. The string must be NULL terminated if a value of zero is passed for address_list_len.

address_list_len

The length in bytes of the string of addresses to parse, not including any NULL terminator. If a value of zero is passed for this argument, then the length of address_list will automatically be determined.

item_code

An optional list of item codes. The list must be terminated with an integer argument with value 0.

Description

This routine parses a list of one or more comma separated RFC 822 addresses. The input list can be of any arbitrary length. The result of the parse is represented by an address context and a count of the parsed addresses. Each parsed address can then be individually extracted from the parsed list with a call to mtaAddresGetN(). The address context should be disposed of with a call to mtaAddressFinish(). When there are no valid addresses in the input line, the returned context will be NULL and the count zero.


Note –

There are two item codes that can be used in the item_code argument. A NULL value can be passed for either or both of the adr_ctx and address_count arguments. When NULL is passed for both, all that is learned by calling the routine is whether or not the address list is syntactically valid.


The following table lists the item codes for this routine, their additional required arguments, and gives a description of each.

Item Codes  

Additional Arguments  

Description  

MTA_DOMAIN

const char *domain

size_t domain_len

Specify a domain name to append to short-form addresses, such as sue, in order to create a fully qualified address, for example, sue@siroe.com.

It must be followed by two additional call arguments: the domain name to use and the length in bytes of that domain name. If a value of 0 is passed for the length, then the domain name must be NULL terminated.

MTA_ITEM_LIST

mta_item_list_t *item_list

Specify a pointer to an item list array. The array must be terminated with a final array entry with an item code value of 0. For further information on item lists, see Item Codes and Item Lists.

Return Values

Return Value  

Description  

0

Normal, successful completion. 

MTA_BADARGS

A NULL value was supplied for the address_list argument or an optional item code argument.

MTA_NO

Unable to parse the address list. The likely cause is that one or more addresses in the list is syntactically invalid. 

MTA_NOMEM

Insufficient virtual memory. 

MTA_NOSUCHITEM

An invalid item code was supplied. 

MTA_STRTRUERR

Item code string argument is too long. 

Example

See the code example for mtaAddressGetN() for a sample code fragment that uses mtaAddressParse().

mtaAddressToChannel()

Determine which channel an address rewrites to.

Syntax


const char *mtaAddressToChannel(char       *channel,
                                size_t     *channel_len,
                                size_t      channel_len_max,
                                const char *address,
                                size_t      address_len,
                                int         address_type,
                                int         item_code, ...);

Arguments

Arguments  

Description  

channel

A pointer to a buffer to receive the NULL terminated channel name. To avoid possible truncation of the channel name, this buffer must be at least CHANLENGTH+1 bytes long.

channel_len

An optional pointer to a size_t to receive the length in bytes of the returned channel name. This length does not include the NULL terminator that terminates the channel name.

channel_len_max

The maximum size in bytes of the buffer pointed at by the channel argument.

address

The address to rewrite. The length of this address, not including any NULL terminator, should not exceed ALFA_SIZE bytes. If a value of 0 is passed for the address_len argument, then this string must be NULL terminated.

address_len

The length in bytes of the address string, address. This length does not include any NULL terminator. If a value of 0 is passed for this argument, the address string must be NULL terminated.

address_type

Indicates what type of address is being rewritten. There are two types: envelope or header. In addition it can be either forward or reverse pointing. See the description for a list of the possible values. 

item_code

Reserved for future use. Presently, a value of 0 must be supplied for this argument.

Description

Use this routine to determine which channel an address rewrites to. The address to be rewritten can be an envelope or header address, and can be forward or reverse pointing. The nature of the address is specified with the address_type argument. The following table lists the possible values for each combination: forward pointing envelope, reversing pointing envelope, forward pointing header, reverse pointing header:

Types of Address  

Value  

Forward pointing envelope address 

0, MTA_BCC, MTA_CC, MTA_ENV_TO, MTA_TO

Reverse pointing envelope address 

MTA_ENV_FROM

Forward pointing header address 

MTA_HDR_BCC, MTA_HDR_CC, MTA_HDR_TO

Reverse pointing header address 

MTA_HDR_FROM

In most cases, a value of MTA_ENV_TO is appropriate. Other values will typically give the same result, unless the MTA configuration has rewrite rules that are sensitive to the distinctions between the four types of addresses.

Return Values

On successful operation, the routine returns the value of the channel argument. In the event of an error, the value returned is NULL and the mta_errno variable is set with an error status code. The following table lists the error status codes and gives a description of each.

Error Status Codes  

Description  

MTA_BADARGS

There are two reasons to get this return value: 

  1. A NULL value was supplied for the address argument.

  2. An invalid value was supplied for the address_type.

MTA_FOPEN

Unable to initialize the MTA SDK; can’t read one or more configuration files. Issue the following command for further information: 

imsimta test -rewrite

MTA_NO

There are two reasons to get this return value: 

  1. Unable to rewrite the supplied address. Either the address is syntactically invalid, or it does not match any channel.

  2. Unable to initialize the MTA_SDK. Issue the following command for further information:

    imsimta test -rewrite

MTA_NOSUCHITEM

An invalid item code was specified. 

MTA_STRTRUERR

There are two reasons to get this return value: 

  1. Supplied address string is too long; length can not exceed ALFA_SIZE bytes.

  2. The supplied buffer to receive the channel name is too small.

Example

None

mtaBlockSize()

Obtain the size in bytes of an MTA block size unit.

Syntax

size_t mtaBlockSize(void);

Arguments

None

Description

The MTA measures message sizes in units of blocks. Units of blocks are used, for instance, when logging message sizes, and for the MTA_FRAGMENT_BLOCKS item code in the mtaEnqueueStart() routine. By default, a block is 1024 bytes. However, sites can change this setting with the BLOCK_SIZE option in the option.dat file.

Programs using the SDK can translate units of bytes to blocks by dividing the number of bytes by the value returned by mtaBlockSize(), that is:

bytes_per_block = mtaBlockSize();
block_limit = byte_limit / bytes_per_block;

Return Values

In the event of a failure, the routine returns the value zero and sets mta_errno with an error status code. This routine only fails when initialization of the MTA SDK fails. The following table lists the error status codes set in mta_errno when there is an error returned by mtaBlockSize().

Error Status Codes  

Description  

MTA_FOPEN

Unable to initialize the MTA SDK. Unable to read one or more configuration files. Issue the following command for further information: 

imsimta test -rewrite

MTA_NO

Unable to initialize the MTA SDK. Issue the following command for further information: 

imsimta test -rewrite

Example

The following code fragment displays the MTA block size setting:


printf ("BLOCK_SIZE = %u\n", mtaBlockSize());

mtaChannelGetName()

Determine the channel name for the currently running program.

Syntax


const char *mtaChannelGetName(char   *channel,
                              size_t *channel_len,
                              size_t  channel_len_max);

Arguments

Arguments  

Description  

channel

A pointer to a buffer to receive the NULL terminated channel name. To avoid possible truncation of the channel name, this buffer must be at least CHANLENGTH+1 bytes long.

channel_len

An optional pointer to a size_t to receive the length in bytes of the returned channel name. This length does not include the NULL terminator that terminates the channel name.

channel_len_max

The maximum size in bytes of the buffer pointed at by the channel argument.

Description

A running program can discover its channel name with this routine. The channel name is typically set using the PMDF_CHANNEL environment variable.

Return Values

In the event of an error, the routine returns NULL. The error status code is set in mta_errno.

Error Status Codes  

Description  

MTA_BADARGS

A NULL value passed for the channel argument.

MTA_NO

Unable to determine the channel name from the runtime environment. 

MTA_STRTRUERR

Channel buffer too small to receive the channel name. The buffer must be at least CHANLENGTH+1 bytes long.

Example

The following code fragment uses this routine to print the channel name.


char buf[CHANLENGTH+1];

printf("Channel name: %s\n",
       mtaChannelGetName(buf, NULL, sizeof(buf)));

mtaChannelToHost()

Determine the host name associated with a channel.

Syntax


const char *mtaChannelToHost(char  **host,
                             size_t *host_len,
                             int     item_code, ...);

Arguments

Arguments  

Description  

host

A pointer to receive the host name. The host name will be NULL terminated. NULL can be passed for this call argument. 

host_len

An optional pointer to a size_t to receive the length in bytes of the returned host name. This length does not include the NULL terminator that terminates the host name. A value of NULL can be passed for this call argument.

item_code

An optional list of item codes. The list must be terminated with an integer argument with value 0.

Description

This routine is used to determine the host name associated with a particular channel.

The channel name can be specified in one of three ways:

In all cases, the official host name of the selected channel is the host name that is returned. The official host name for a channel is the one that appears on the second line of the channel definition in the MTA configuration file, imta.conf.

The following table lists the item codes and any associated arguments:

Item Codes  

Additional Arguments  

Description  

MTA_CHANNEL

const char *channel

size_t channel_len

Explicitly specify a channel name for the official host name. This item code must be followed by the two additional call arguments, specifying: 

  1. The channel name.

  2. The length in bytes of that channel name.

    If a value of 0 is passed for the length, the channel name must be NULL terminated.

MTA_DQ_CONTEXT

mta_dq_t *dq_ctx

Use the channel associated with the specified dequeue context. This item code must be followed by one additional call argument: a pointer to a dequeue context generated by mtaDequeueStart().

MTA_ITEM_LIST

mta_item_list_t *item_list

Specify a pointer to an item list array that is terminated with a final array entry that has an item code value of 0. For further information on item lists, see Item Codes and Item Lists.

When none of the above item codes are specified, the channel name is taken from the runtime environment, using PMDF_CHANNEL environment variable.

On successful completion, the host name is stored in the buffer pointed at by the host argument, and the value of the host argument is returned.

Return Values

In the event of an error, mtaChannelToHost() will return NULL, but will set mta_errno. The following table lists the error status codes for this routine.

Error Status Codes  

Description  

MTA_BADARGS

A NULL value was supplied for either of these two argument: 

  1. The host argument in the routine call.

  2. An argument to an item code.

MTA_FOPEN

Unable to initialize the MTA SDK. Unable to read one or more configuration files. Issue the following command for further information: 

imsimta test -rewrite

MTA_NO

One of the following errors occurred: 

  1. Unable to determine the channel name from the runtime environment.

  2. Unable to initialize the MTA SDK. For further information, issue the following command:

    imsimta test -rewrite

MTA_NOSUCHCHAN

The selected channel name does not appear in the MTA configuration file, imta.cnf.

MTA_NOSUCHITEM

An invalid item code was specified. 

Example


printf("Host name: %s\n",
       mtaChannelToHost(NULL, NULL, MTA_CHANNEL,
                        "tcp_local", 0, 0));

mtaDateTime()

Obtain the current date and time in an RFC 822 and RFC 1123 complaint format.

Syntax


const char *mtaDateTime(char   *date,
                        size_t *date_len,
                        size_t  date_len_max,
                        time_t  time);

Arguments

Arguments  

Description  

date

A pointer to a buffer to receive the NULL terminated date and time string. To avoid possible truncation of the string, this buffer should be at least 81 bytes long. 

date_len

An optional pointer to a size_t to receive the length in bytes of the returned date and time string. This length does not include the NULL terminator that terminates the host name. A value of NULL can be passed for this call argument.

date_len_max

The maximum size in bytes of the buffer pointed at by the date argument.

time

The date and time for which to generate the string representation. To use the current local time, pass a value of zero for this argument. 

Description

This routine generates an RFC 2822 compliant date and time string suitable for use in an RFC 822 Date: header line. To generate a date and time string for a specific time, supply the time as the time argument. Otherwise, supply a value of 0 for the time argument and a date and time string will be generated for the current local time.

On successful completion, the date and time string is stored in the buffer pointed at by the date argument, and the value of the date argument is returned.

Return Values

In the event of an error, mtaDateTime() will return NULL. It will set the error status code in mta_errno.

Error Status Codes  

Description  

MTA_BADARGS

A value of NULL was supplied for the date argument.

MTA_STRTRU

The date buffer is too small; the returned value has been truncated to fit.

Example


char buf[80+1];

printf("The current date and time is %s\n",
       mtaDateTime(buf, NULL, sizeof(buf), (time_t)0);

mtaDebug()

Enable generation of MTA SDK diagnostic output.

Syntax

int mtaDebug(int item_code, ...);

Arguments

Arguments  

Description  

item_code

An optional list of item codes. The list must be terminated with an integer argument with value 0.

Description

Many of the low-level MTA subroutine libraries can produce diagnostic output as can the MTA SDK itself. This output, when enabled, is directed to stdout. When a channel program is run by the Job Controller, stdout is directed to the channel’s debug log file. Use this diagnostic output when developing programs.


Note –

mtaDebug() may also be used in production programs; however, caution should be used, as it can be quite verbose and voluminous, thereby degrading performance and consuming disk space.


As described in the following table, item codes are used to select specific types of diagnostic output.

Item Codes  

Additional Arguments  

Description  

MTA_DEBUG_DECODE

None 

Enable diagnostic output from the low-level MIME decoding routines. This might be helpful when trying to understand MIME conversions that occur either when enqueuing messages (and the destination channel is configured to invoke MIME conversions, for example, marked with channel keywords such a thurman or inner), or when using mtaDecodeMessage.()

MTA_DEBUG_DEQUEUE

None 

Enable diagnostic output from low-level queue processing routines. Use this when trying to understand issues around reading and processing of queued message files. This will not help diagnose the selection of queued messages, which is handled by the Job Controller. 

Enabling this diagnostic output is the equivalent of setting DEQUEUE_DEBUG=1 in the option file, option.dat.

MTA_DEBUG_ENQUEUE

None 

Enables output from low-level message enqueue routines. Can be used to diagnose the address rewriting process, destination channel selection, header processing, and other types of processing that occurs when a message is enqueued. 

Enabling this diagnostic output is the equivalent of setting MM_DEBUG=5 in the option.dat file.

MTA_DEBUG_MM

size_t level

Enable diagnostic output from the low-level message enqueue routines. The item code must be followed by one additional call argument: the debug level to use. The value of level ranges from 0 to 20. Enqueue diagnostics can be used to diagnose the address rewriting process, destination channel selection, header processing and other types of processing that occurs when a message is enqueued.

Enabling this diagnostic output is equivalent to setting DEQUEUE_DEBUG=level in the option.dat file.

MTA_DEBUG_OS

None 

Enable diagnostic output from the low-level operating system dependent routines. This output is helpful when diagnosing problems associated with creating, opening, writing, or reading files. This typically happens when attempting to enqueue messages, which requires permissions to create and write messages in the MTA queues. 

Enabling this output is equivalent to setting OS_DEBUG=1 in the option.dat file.

MTA_DEBUG_SDK

None 

Enable diagnostic output for the MTA SDK. When this is enabled, diagnostic information will be output whenever the SDK returns an error result. 

MTA_ITEM_LIST

mta_item_list_t *item_list

Specify a pointer to an item list array. The item list array must be terminated with a final array entry with an item code value of 0. For further information on item lists, see Item Codes and Item Lists.

Return Values

Return Values  

Description  

0

Successful, normal completion. 

MTA_BADARGS

A NULL value was supplied for a pointer to an item list array. 

MTA_FOPEN

Unable to initialize the MTA SDK. Unable to read one or more configuration files. For further information, issue the following command: 

imsimta test -rewrite

MTA_NO

Unable to initialize the MTA SDK. For further information issue the following command: 

imsimta test -rewrite

MTA_NOSUCHITEM

An invalid item code was specified. 

Example

mtaDebug(MTA_DEBUG_SDK, MTA_MM_DEBUG, 8, 0);

mtaDecodeMessage()

Decode a MIME formatted message; optionally convert non-MIME formats to MIME.

Syntax


int mtaDecodeMessage(void                 *ctx,
                     int                   input_type,
                     void                 *input,
                     int                   output_type,
                     void                 *output,
                     mta_decode_inspect_t *inspect,
                     int                   item_code, ...);

Arguments

Arguments  

Description  

ctx

Optional pointer to a caller-supplied context or other data type. This pointer will be passed as the ctx argument to any caller-supplied routines, such as the one supplied as the inspect argument. A value of NULL can be passed for this argument.

input_type

Input type indicator describing the input source to use, either a dequeue context or a caller-supplied routine. There are only two valid values: MTA_DECODE_DQ, MTA_DECODE_PROC.

input

For input_type=MTA_DECODE_DQ, input must be a pointer to a dequeue context created by mtaDequeueStart().

For input_type=MTA_DECODE_PROC, input must be the address of a routine of type mta_decode_read_t.

output_type

Optional output type indicator describing the output destination to use, either an enqueue context or a caller-supplied routine. Valid values are: 0, MTA_DECODE_NQ, MTA_DECODE_PROC. When a value of 0 is supplied, the output argument is ignored.

output

For output_type=MTA_DECODE_NQ, output must be a pointer to an enqueue context created with mtaEnqueueStart().

For output_type=MTA_DECODE_PROC, output must be the address of a routine to type mta_decode_write_t. This argument is ignored when a value of 0 is supplied for output_type.

inspect

The address of an inspection routine of type mta_decode_inspect_t.

item_code

An optional list of item codes. The list must be terminated with an integer argument with value 0.

Description

The MTA has powerful facilities for parsing and decoding single and multipart messages formatted using the MIME Internet messaging format. Additionally, these facilities can convert messages with other formats to MIME, for example, text parts with BINHEX or UUENCODE data, the RFC 1154 format, and many other proprietary formats. The mtaDecodeMessage() routine provides access to these facilities, parsing either a queued message or a message from an arbitrary source such as a disk file or a data stream.

There are two usage modes for mtaDecodeMessage(). In the first mode, messages are simply parsed, any encoded content decoded, and each resulting, atomic message part presented to an inspection routine. This mode of usage is primarily of use to channels that interface the MTA to non-Internet mail systems such as SMS and X.400. The second mode of operation allows the message to be rewritten after inspection by an output routine. The output destination for this rewriting may be either the MTA channel queues, or an arbitrary destination via a caller-supplied output routine.

During the inspection process in this second usage mode, individual, atomic message parts may be discarded or replaced with text. This operational mode is primarily of use to intermediate processing channels that need to scan message content or perform content conversions, for example, virus scanners and encryption software.

Example 5–1 illustrates the first usage mode, while Example 5–2 illustrates the second.

Inspection Routine

Key to either usage mode for mtaDecodeMessage() is the inspection routine, pointed to with the inspect argument. The mtaDecodeMessage() routine presents each atomic message part to the inspection routine one line at a time. The presentation begins with the part’s header lines. Once all of the header lines have been presented, the lines of content are presented next. The following points should also be noted:

The following code fragment shows the required syntax of an inspection routine:


int inspection_routine(void         *ctx,
                       mta_decode_t *dctx,
                       int           data_type,
                       const char   *data,
                       size_t        data_len);

The following table lists each of the inspection routine’s arguments, and gives a description of each.

Arguments  

Description  

ctx

The caller-supplied private context. 

dctx

A decode context created by mtaDecodeMessage(). This decode context represents the current part being processed. This context is to be used with calls to the other decode routines requiring a decode context. This context is automatically disposed of by mtaDecodeMessage().

data_type

The nature of the data being presented: 

  • For a header line: MTA_DATA_HEADER

  • For a line of text-based content: MTA_DATA_TEXT

  • For a line of binary content: MTA_DATA_BINARY

  • No data at all: MTA_DATA_NONE.

    Atomic part content with a MIME content type of text/* or message/* is considered to be text-based. Such content is given the data type MTA_DATA_TEXT. All other atomic part content (audio/*, image/*, and application/*) is considered to be binary and denoted by the data type MTA_DATA_BINARY. The data type MTA_DATA_NONE is only presented when using an optional output routine (supplied with the output argument in mtaDecodeMessage()).

data

A pointer to the data being presented. Message lines will not have carriage-return or line-feed terminators, nor is the data itself NULL terminated. (However, in the case of binary data, there may be carriage returns, line feeds, or even NULLs embedded within the data itself.) 

data_len

The length in bytes of the data being presented. This length may be 0, which indicates a blank line and not the absence of any data (MTA_DATA_NONE).

Output Routine

When an output routine is not used, the inspection routine can detect the transition from one message part to another by observing the part number on each call. The part number is obtained by calling mtaDecodeMessageInfoString() with an item value of MTA_DECODE_PART_NUMBER.

When the optional output routine (pointed to by the output argument) is used, an additional data type, MTA_DATA_NONE, is presented to the inspection routine. It is presented to the inspection routine after the part’s header and entire content have been presented. However, no data is actually presented for the MTA_DATA_NONE type. As such, this data type merely serves to (1) let the inspection routine know that the entire part has now been presented, and (2) allows the inspection routine a final chance to delete the part from the data being output to the output routine. For example, it allows a virus scanner to be activated and a judgment passed. Based upon the result of the virus scan, the part can then either be copied to the output or not.

If it is not copying the part to the output, the inspection routine must call mtaDecodeMessagePartDelete(). That call will either delete the part entirely, or optionally replace it with caller-supplied content. Calling mtaDecodeMessagePartCopy() makes the copy operation explicit; if neither routine is called, then the part will be implicitly copied to the message being output.

When using an output routine, the inspection routine may call mtaDecodeMessagePartDelete() or mtaDecodeMessagePartCopy() at any time. It is not necessary to wait until the inspection routine is called with a data type of MTA_DATA_NONE. For instance, a virus scanner may want to discard a part when it sees that the part’s content type indicates an executable program. However, once either of these routines is called, the inspection routine will not be called any further for that message part.

Dequeue Context

The message to be decoded is supplied by either a dequeue context or a caller-supplied input routine. When using a dequeue context, observe the following points:

Caller-Supplied Input Routine

When using a caller-supplied input routine to supply the message to be decoded, specify MTA_DECODE_PROC for the input_type argument, and pass the address of the input routine as the input argument.

The following code fragment shows the syntax of a caller-supplied input routine:


int input_routine(void       * ctx,
                  const char **line,
                  size_t     * line_len);

The following table lists the arguments for a caller-supplied input routine, and gives a description of each.

Arguments  

Description  

ctx

The caller-supplied private context. 

line

A pointer to the start of the next line or section of data to return. The line or data does not need to be NULL terminated. 

line_len

The length in bytes of the line or block of data being returned. A zero length signifies zero bytes of data. That is, a zero length does not cause mtaMessageDecode() to automatically determine the length by searching for a NULL terminator.

On each successful call, the input routine should return a status code of 0 (MTA_OK). When there is no more message data to provide, then the input routine should return MTA_EOF. The call that returns the last byte of data should return 0; it is the subsequent call that must return MTA_EOF. In the event of an error, the input routine should return a non-zero status code other than MTA_EOF, such as MTA_NO. This will terminate the message parsing process and mtaDecodeMessage() will return an error.


Note –

By default, each block of data must be a single line of the message. This corresponds to the MTA_TERM_NONE item code. If the MTA_TERM_CR, MTA_TERM_CRLF, MTA_TERM_LF, or MTA_TERM_LFCR item code is specified, then the block of data need not correspond to a single, complete line of message data It may be a portion of a line, multiple lines, or even the entire message. See Item Codes for information about mtaDecodeMessage() item codes.


Enqueue Context

The parsed message may be output either as a message enqueue or written to an arbitrary destination via a caller-supplied output routine. When using a message enqueue context, observe the following points:

Caller-Supplied Output Routine

To use a caller-supplied output routine, specify the MTA_DECODE_PROC for the output_type call argument, and pass the address of the output routine as the output argument.

This code fragment shows the syntax of a caller-supplied output routine.


int output_routine(void         *ctx,
                   mta_decode_t *dctx,
                   const char  **line,
                   size_t       *line_len);

The following table lists the arguments for a caller-supplied output routine, and gives a description of each.

Arguments  

Description  

ctx

The caller-supplied private context passed as ctx to mtaDecodeMessage().

dctx

A decode context created by mtaDecodeMessage(). This decode context should be used with calls to the other decode routines requiring a decode context. This context is automatically disposed of by mtaDecodeMessage().

line

Pointer to a line of the message to output. This line is not NULL terminated. The line will also lack any carriage return or line feed record terminators. 

line_len

The length in bytes of the message line to output. A length of 0 indicates a blank line. The maximum line length presented will be BIGALFA_SIZE bytes (1024 bytes).

Each line passed to the output routine represents a complete line of the message to be output. The output routine must add to the line any line terminators required by the output destination (for example, carriage return, line feed pairs if transmitting over the SMTP protocol, or line feed terminators if writing to a UNIX® text file). Supplying a value of zero for the output_type call argument, causes the output argument to be ignored. In this case no output routine will be used.

Decode Context Queries

When mtaDecodeMessage() calls either a caller-supplied inspection or output routine, it passes to those routines a decode context. Through various SDK routine calls, this decode context may be queried to obtain information about the message part currently being processed.

The following table lists the informational message codes that can be obtained about a message part being processed, and gives a description of each, including the SDK routine used to obtain it.

Message Code  

Description  

MTA_DECODE_CCHARSET

The character set specified with the CHARSET parameter of the part’s Content-type: header line. If the part lacks a CHARSET specification, then the value us-ascii will be returned. Obtain with mtaDecodeMessageInfoString().

MTA_DECODE_CDISP

Value of the Content-disposition: header line, less any optional parameters. Will be a zero length string if the part lacks a Content-disposition: header line. Obtain with mtaDecodeMessageInfoString().

MTA_DECODE_CDISP_PARAMS

Parameter list to the Content-disposition: header line, if any. The parsed list is returned as a pointer to an option context. For further information, see mtaDecodeMessageInfoParams().

MTA_DECODE_CSUBTYPE

The content subtype specified with the part’s Content-type: header line (for example, plain for text/plain, gif for image/gif). Defaults to plain when the part lacks a Content-type: header line.

Obtain with mtaDecodeMessageInfoString().

MTA_DECODE_CTYPE

The major content type specified with the part’s Content-type: header line (for example, text for text/plain, image for image/gif). Defaults to text when the part lacks a Content-type: header line.

Obtain with mtaDecodeMessageInfoString().

MTA_DECODE_CTYPE_PARAMS

Parameter list to the Content-type: header line, if any. The parsed list is returned as a pointer to an option context. For further information, see mtaDecodeMessageInfoParams().

MTA_DECODE_DTYPE

Data type associated with this part. Obtain with mtaDecodeMessageInfoInt().

MTA_DECODE_PART_NUMBER

Sequential part number for the current part. The first message part is part 0, the second part is 1, the third part is 2, and so on. Obtain with mtaDecodeMessageInfoInt().

Item Codes

The table that follows lists the item codes for the item_code argument passed to mtaDecodeMessage(). The list of item codes must be terminated with an item code with a value of 0.

Item Codes  

Additional Arguments  

Description  

MTA_DECODE_LEVELS_MAX

max_levels

Place an upper limit on the depth of nested MIME multiparts that will be parsed. When this limit is reached no further parsing of deeper, nested multiparts is performed and the parts handed over for inspection include as text content these deeper, nested multiparts. By default, no limit is imposed. When dealing with looping notification messages, it is possible for the looping message to become deeply nested. 

This item code must be followed by one additional call argument whose value is the integer-valued upper limit to impose: max_levels.

MTA_DECODE_PARTS_MAX

max_parts

Place an upper limit on the total number of message parts that will be parsed. When this limit is reached, no further parsing of parts is performed. By default, no limit is imposed. 

This item code must be followed by one additional call argument whose value is the integer-valued part limit to impose: max_parts.

MTA_DECODE_THRURMAN

None 

When specified, the MIME parser will first translate non-MIME formatted data to MIME. By default this translation is not performed. 

MTA_ITEM_LIST

mta_item_list_t *item_list

Specify a pointer to an item list array. The item list array must be terminated with a final array entry with an item code value of 0. For further information on item lists, see Item Codes and Item Lists.

MTA_TERM_CR

None 

Data supplied by the input routine, pointed to by the input argument, uses a single byte carriage return terminator to terminate each line of message data. This option is ignored when input_type has the value MTA_DECODE_DQ.

MTA_TERM_CRLF

None 

Data supplied by the input routine, pointed to by the input argument, uses a two byte carriage-return line-feed terminator to terminate each line of message data. This option is ignored when input_type has the value MTA_DECODE_DQ.

MTA_TERM_LF

None 

Data supplied by the input routine, pointed to by the input argument, uses a single byte line-feed terminator to terminate each line of message data. This option is ignored when input_type has the value MTA_DECODE_DQ.

MTA_TERM_LFCR

None 

Data supplied by the input routine, pointed to by the input argument, uses a two byte line-feed carriage-return terminator to terminate each line of message data. This option is ignored when input_type has the value MTA_DECODE_DQ.

MTA_TERM_NONE

None 

Data supplied by the input routine, pointed to by the input argument, uses no line terminators. Each call to the input routine returns a single, complete line of message data. This option is ignored when input_type has the value MTA_DECODE_DQ.

Return Values

Return Values  

Description  

0

Successful, normal completion. 

MTA_BADARGS

Two conditions cause this error: 

  1. A NULL value was supplied for input, output (when output_type is non-zero), or a required argument to an item code.

  2. An invalid value supplied for either input_type or output_type.

MTA_FOPEN

Unable to initialize the MTA SDK. Unable to read one or more configuration files. For further information issue the following command:imsimta text -rewrite

MTA_NO

Can be sent for one of three reasons: 

  1. Error parsing the supplied message.

  2. An error reading from the queued message file when MTA_DECODE_DQ is supplied for input_type.

  3. Unable to initialize the MTA SDK. In this case, issue the command: imsimta test -rewrite

MTA_NOMEM

Insufficient virtual memory. 

MTA_NOSUCHITEM

An invalid item code was specified. 

Example

For examples of using mtaDecodeMessage, see Example 5–1 and Example 5–2.

mtaDecodeMessageInfoInt()

Obtain integer-valued information relating to the current message part.

Syntax


int mtaDecodeMessageInfoInt(mta_decode_t *dctx,
                            int           item);

Arguments

Arguments  

Description  

dctx

A decode context created by mtaMessageDecode().

item

Item identifier specifying which value to return. See the description that follows for the list of permitted values for this argument. 

Description

This routine is used to obtain integer-valued information about the current message part. (When mtaDecodeMessage() calls either a user-supplied inspection or output routine, it provides a decode context describing the current message part being processed.)

The following table lists the values for the item argument, and gives a description of each.

Values  

Description  

MTA_DECODE_DTYPE

Data type associated with this part. The returned values will be MTA_DATA_NONE, MTA_DATA_HEADER, MTA_DATA_TEXT, or MTA_DATA_BINARY.

MTA_DECODE_PART_NUMBER

Sequential part number for the current part. The first message part is part 0, the second part is 1, the third part is 2, and so on.

Return Values

Upon normal, successful completion the value of the requested item is returned. In the event of an error, a value of -1 is returned and mta_errno is set to indicate the error status code. The following table lists the error status codes for this routine, and gives an example of each.

Error Status Codes  

Description  

MTA_BADARGS

A NULL value was supplied for the dctx call argument.

MTA_NOSUCHITEM

An invalid value was supplied for the item call argument.

Example

part_number = mtaDecodeMessageInfoInt(dctx, MTA_PART_NUMBER);

mtaDecodeMessageInfoParams()

Obtain an option context describing the current message part’s content parameters.

Syntax


mta_opt_t *mtaDecodeMessageInfoParams(mta_decode_t *dctx,
                                      int           item,
                                      mta_opt_t   **params);

Arguments

Arguments  

Description  

dctx

A decode context created by mtaMessageDecode().

item

Item identifier specifying which content parameter list to return. See the description that follows for the list of permitted values for this argument. 

params

An optional pointer to receive the address of the option context describing the requested parameter list. 

Description

This routine returns the parameter lists for either the Content-type: or Content-disposition: header lines. (When mtaDecodeMessage() calls either a user-supplied inspection or output routine, it provides a decode context describing the current part being processed.)

The following table lists the values for the item argument, and gives a description of each.

Values  

Description  

MTA_DECODE_CDISP_PARAMS

Parameters associated with the Content-disposition: header line, if any.

MTA_DECODE_CTYPE_PARAMS

Parameters associated with the Content-type: header line, if any.

The option context returned upon normal completion does not need to be disposed of with mtaOptionFinish(). It will automatically be disposed of by mtaDecodeMessage(). The values of individual parameters can be queried using mtaOptionString(), mtaOptionInt(), and mtaOptionFloat(). Program code need not worry about whether the underlying header line exists in the parts header. If it does not, then calls to obtain individual parameter values will succeed, but return no value.


Note –

If the Content-type: header line is not present, mtaOptionString() returns an empty string. This is in contrast to what happens when mtaDecodeMessageInfoString() is used. It always returns a value for the CHARSET parameter of the Content-type: header line. If the Content-type: header line is not present, it returns the MIME default value us-ascii.


It is important to note that the option contexts returned by this routine are only valid during the lifetime of the associated decode context. They are not valid after inspection or output of a new message part begins, nor are they valid after mtaDecodeMessage() returns.

Return Values

Upon normal, successful completion, a pointer to an option context is returned. In the event of an error, a NULL value is returned, and mta_errno is set to indicate the error status code. The following table lists the error status codes, and gives a description of each:

Error Status Codes  

Description  

MTA_BADARGS

A NULL value was supplied for the dctx call argument, or an invalid decode context was supplied for dctx.

MTA_NOSUCHITEM

An invalid value was supplied for the item call argument.

Example


char buf[64];

strcpy(buf, "us-ascii");
mtaOptionString(
    mtaDecodeMessageInfoParams(dctx, MTA_DECODE_CTYPE_PARAMS,
    NULL), "charset", 0, buf, NULL, sizeof(buf));
printf("Message part’s character set is %s\n", buf);

mtaDecodeMessageInfoString()

Obtain string-valued information relating to the current message part.

Syntax


const char *mtaDecodeMessageInfoString(mta_decode_t *dctx,
                                       int           item,
                                       const char  **str,
                                       size_t       *len);

Arguments

Arguments  

Description  

dctx

A decode context created by mtaMessageDecode().

item

Item identifier specifying which string-value item to return. See the description that follows for the list of permitted values for this argument. 

str

An optional pointer to receive the address of the requested string. The string will be NULL terminated. A value of NULL may be passed for this argument. 

len

An optional pointer to receive the length of the requested string. This length is measured in bytes and does not include the NULL terminator at the end of the string. A value of NULL may be passed for this argument. 

Description

This routine is used to obtain string-valued information about the current message part. (When mtaDecodeMessage() calls either a user-supplied inspection or output routine, it provides a decode context describing the current message part being processed.)

The following table lists the values for the item call argument, and gives a description of each.

Values  

Description  

MTA_DECODE_CCHARSET

The character set specified with the CHARSET parameter of the part’s Content-type: header line. If the part lacks a CHARSET specification, then the value us-ascii will be returned.

MTA_DECODE_CDISP

Value of the Content-disposition: header line, less any optional parameters. If the part lacks a Content-disposition: header line, the returned value will be a zero length string.

MTA_DECODE_CSUBTYPE

The content subtype specified with the part’s Content-type: header line (for example, plain for text/plain, gif for image/gif). Defaults to plain when the part lacks a Content-type: header line.

MTA_DECODE_CTYPE

The major content type specified with the part’s Content-type: header line (for example, text for text/plain, image for image/gif). Defaults to text when the part lacks a Content-type: header line.

Return Values

mtaDecodeMessageInfoString() always returns a value for the CHARSET parameter of the Content-type: header line. When the Content-type: header line is not present, it returns the MIME default value, us-ascii.

Upon normal, successful completion a pointer to the requested string is returned. In addition, if pointers were provided in the str and len call arguments, the address of the string and its length are returned.

In the event of an error, a NULL value is returned and mta_errno is set to indicate the error status code. The following table lists the error status codes, and gives a description of each.

Error Status Codes  

Description  

MTA_BADARGS

A NULL value was supplied for the dctx call argument, or an invalid decode context was supplied for dctx.

MTA_NOSUCHITEM

An invalid value was supplied for the item call argument.

Example


printf("The message part’s character set is %s\n",
       mtaDecodeMessageInfoString(dctx, MTA_DECODE_CCHARSET,
                                  NULL, NULL));

mtaDecodeMessagePartCopy()

Explicitly copy a message part to the message being written.

Syntax


int mtaDecodeMessagePartCopy(mta_decode_t *dctx,
                             int           item_code, ...);

Arguments

Arguments  

Description  

dctx

A decode context created by mtaMessageDecode().

item_code

Reserved for future use. A value of zero must be supplied for this argument. 

Description

When an output routine is used in conjunction with mtaDecodeMessage(), the inspection routine can explicitly request that the current message part be copied to the output destination. After the inspection routine calls mtaDecodeMessagePartCopy(), it will no longer be called for that message part.

If the inspection routine is called with a data type of MTA_DATA_NONE, the message part copy is implicitly done, even if the inspection routine does not call either mtaDecodeMessagePartCopy() or mtaDecodeMessagePartDelete(). Therefore, the only advantage to making an explicit call to mtaDecodeMessagePartCopy() is that once that call is made, the inspection routine will no longer be called for that particular message part.

Return Values

Values  

Description  

Normal, successful completion. 

MTA_BADARGS

A NULL value was supplied for the dctx call argument, or an invalid decode context was supplied for dctx.

MTA_NO

Invalid call to this routine. Either no output routine is being used, or the call was made from the output routine itself. 

Output errors encountered while attempting to write the output may also result in this error. 

Example

This routine is used in Example 5–2.

mtaDecodeMessagePartDelete()

Prevent a message part from being written or replace it with a text part.

Syntax


int mtaDecodeMessagePartDelete(mta_decode_t *dctx,
                               int           item_code, ...);

Arguments

Arguments  

Description  

dctx

A decode context created by mtaMessageDecode().

item_code

An optional list of item codes. See the description section that follows for a list of item codes. The list must be terminated with an integer argument with value 0.

Description

When an output routine is used in conjunction with mtaDecodeMessage(), the inspection routine may discard the current message part by calling this routine. As an alternative to discarding the part, it may be replaced with a part containing caller-supplied data such as a warning message. This replacement is achieved through the use of item codes.

Once mtaDecodeMessagePartDelete() has been called, the inspection routine will no longer be called for that message part. As such, calling the routine is final and cannot be undone short of cancelling the entire message decode operation itself (for example, by having the caller-supplied read routine return an error, or after mtaDecodeMessage() completes, cancelling the dequeue and enqueue operations with mtaDequeueMessageFinish() and mtaEnqueueFinish()).

The following table lists the item codes for this routine, any additional item code arguments each item code requires, and gives a description of each.

Item Codes  

Additional Arguments  

Description  

MTA_DECODE_CCHARSET

const char *charset

size_t charset_len

Specify the character set used for the message part (for example, us-ascii, iso-8859-1). This item code must be followed by two additional call arguments:

  1. The name of the character set

  2. The length in bytes of that name

    If a value of zero is passed for the length, then the name must be NULL terminated.

MTA_DECODE_CDISP

const char *disposition

size_t disposition_len

Specify the content disposition for the message part (for example, inline, attachment; filename=a.doc). This disposition information will be placed in a Content-disposition: header line. The item code must be followed by two additional call arguments:

  1. The disposition string

  2. The length in bytes of that string

    If a value of zero is passed for the length, then the disposition string must be NULL terminated.

MTA_DECODE_CLANG,

const char *language

size_t language_len

Specify the language used for the message part (for example, en, fr). This language information will be placed in a Content-language: header line. The item code must be followed by two additional call arguments:

  1. The language string

  2. The length in bytes of that string.

    If a value of zero is passed for the length, then the string must be NULL terminated.

MTA_DECODE_CSUBTYPE

const char *subtype

size_t subtype_len

Specify the content subtype for the message part (for example, plain or html for text/plain or text/html). This subtype information will be combined with the type and charset information and placed in a Content-type: header line. The item code must be followed by two additional call arguments:

  1. The language string

  2. The length in bytes of that string.

    If a value of zero is passed for the length, then the string must be NULL terminated.

MTA_DECODE_CTYPE

const char *type

size_t type_len

Specify the major content type for the message part (for example, text for text/plain or text/html). This major type information will be combined with the subtype and charset information and placed in a Content-type: header line. The item code must be followed by two additional call arguments:

  1. The language string

  2. The length in bytes of that string.

    If a value of zero is passed for the length, then the string must be NULL terminated.

MTA_ITEM_LIST

mta_item_list_t *item_list

Specify a pointer to an item list array. The item list array must be terminated with a final array entry with an item code value of 0. For further information on item lists, see Item Codes and Item Lists.

MTA_REASON

const char *text

size_t text_len

Specifies the content and length of caller-supplied text or data used to replace the deleted message part. 

The item code must be followed by two additional call arguments: 

  1. The language string

  2. The length in bytes of that string.

    If a value of zero is passed for the length, then the string must be NULL terminated.

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_BADARGS

Returned for one of two reasons: 

  1. A NULL value was supplied for the dctx call argument, an invalid decode context was supplied for dctx.

  2. A required argument to an item code was NULL.

MTA_NO

Returned for one of two reasons: 

  1. Invalid call. Either no output routine is being used, or the call was made from the output routine itself.

  2. Output errors encountered while attempting to write the output.

MTA_NOSUCHITEM

An invalid item code was specified. 

Example

The following code fragment shows how the routine is used to discard the message part:

mtaDecodeMessagePartDelete(dctx, 0);

The following code fragment shows how to replace the message part with a text warning:


mtaDecodeMessagePartDelete(dctx,
    MTA_REASON, "Warning: virus infected message part was
                 discarded.", 0,”
    MTA_DECODE_CLANG, "en", 2,
    MTA_DECODE_CCHARSET, "us-ascii", 8, 0);

The following code fragment shows the output generated by the preceding code example.


Content-type: text/plain; charset=us-ascii
Content-language: en

Warning: virus infected message part was discarded.

See also Example 5–2.

mtaDequeueInfo()

Obtain information associated with an ongoing message dequeue.

Syntax


int mtaDequeueInfo(mta_dq_t *dq_ctx,
                   int       item_code, ...);

Arguments

Arguments  

Description  

dq_ctx

A dequeue context created by mtaDequeueStart().

item_code

An optional list of item codes. See the description section that follows for a list of item codes. The list must be terminated with an integer argument with value 0. 

Description

Information associated with an ongoing message dequeue may be obtained with mtaDequeueInfo(). The information to obtain is specified through the use of item codes.


Note –

The pointers returned by mtaDequeueInfo() are only valid during the life of the dequeue context. Once the dequeue has been completed for that particular message, the pointers are no longer valid.


Item Codes  

Additional Arguments  

Description  

MTA_CHANNEL

const char **channel

size_t *channel_len

Obtain the name of the channel for which messages are being dequeued. The channel name will be NULL terminated. 

This item code must be followed by two additional call arguments: 

  1. the address of a pointer to receive the address of the NULL terminated channel name.

  2. The address of a size_t to receive the length of the channel name.

    A NULL value may be passed for the channel_len argument.

MTA_DELIVERY_FLAGS

size_t *dflags

Return the envelope delivery flags for either the entire message or for a particular recipient. If called before the first call to mtaDequeueRecipientNext(), then the delivery flags for the entire message are returned. If called after the first call to mtaDequeueRecipientNext(), then the delivery flags are returned for the most recently reported envelope recipient address. The value of the delivery flags is a logical OR of the deliveryflags channel keyword values on each channel the message has been enqueued to as it flows through the MTA.

This item code must be followed by one additional call argument, the address of a size_t to receive the delivery flag setting.

MTA_DOMAIN

const char **domain

size_t *domain_len

Retrieve the destination domain name, if any, the Job Controller has associated with this dequeue thread. When the channel is marked with the single_sys channel keyword, then the Job Controller tries to give each dequeue thread for that channel all messages destined for the same host as determined by the domain name in the recipient envelope addresses.

This item code must be followed by two additional call arguments: 

  1. The address of a pointer to receive the address of the NULL terminated destination domain name.

  2. The address of a size_t to receive the length of that domain name.

    A NULL value may be passed for the domain_len argument.

MTA_ENV_ID

const char **env_id

size_t *env_id_len

Obtain the envelope ID associated with this message. If the message was submitted to the MTA using the SMTP NOTARY extension (RFC 1891), then this will be the value of the ENVID parameter supplied with the SMTP MAIL FROM command. In all other cases, it will be an envelope ID assigned by the MTA.

This item code must be followed by two additional call arguments: 

  1. The address of a pointer to receive the address of the NULL terminated envelope ID.

  2. The address of a size_t to receive the length of that envelope id.

    A NULL value may be passed for the env_id_len argument.

MTA_ENV_TO

const char **env_to

size_t *env_to_len

Return the envelope recipient address last returned by mtaDequeueRecipientNext(). If that routine has not yet been called for the dequeue context, then an MTA_NO error code will be returned.

This item code must be followed by two additional call arguments: 

  1. The address of a pointer to receive the address of the NULL terminated recipient address.

  2. The address of a size_t to receive the length of that address.

    A NULL value can be passed for the env_to_len argument.

MTA_ENV_FROM

const char **env_from

size_t *env_from_len

Obtain the envelope From: address for the message. It is possible for this to be an empty string (that is, a string of zero length). This is not uncommon and is mandated by Internet standards for automatically generated notification addresses. Notifications must never be sent for messages with an empty envelope From: address. The MTA SDK adheres to this rule when generating any requested notification messages.

This item code must be followed by two additional call arguments: 

  1. The address of a pointer to receive the address of the NULL terminated envelope From: address.

  2. The address of a size_t to receive the length of that address.

    A NULL value can be passed for the env_from_len argument.

MTA_IRCPT_TO

const char **ircpt_to

size_t *ircpt_to_len

Return the intermediate form of the last envelope recipient address returned by mtaDequeueRecipientNext(). If that routine has not yet been called for the dequeue context, then an MTA_NO error code will be returned.

This item code must be followed by two additional call arguments: 

  1. The address of a pointer to receive the address of the NULL terminated intermediate recipient address

  2. The address of a size_t to receive the length of that address.

    A NULL value can be passed for the ircpt_to_len argument.

MTA_ITEM_LIST

mta_item_list_t*item_list

Specify a pointer to an item list array. The item list array must be terminated with a final array entry with an item code value of zero. For further information on item list usage, see Item Codes and Item Lists.

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_BADARGS

Received for one of three reasons: 

  1. A NULL value was supplied for the dq_ctx call argument

  2. An invalid dequeue context was supplied for dq_ctx

  3. A required argument to an item code was NULL.

MTA_NO

An attempt was made to retrieve recipient information before calling mtaDequeueRecipientNext().

MTA_NOSUCHITEM

An invalid item code was specified. 

MTA_THREAD

The MTA SDK detected simultaneous use of the dequeue context by two different threads. 

Example

The following code fragment illustrates how this routine is used to retrieve the delivery flags and intermediate recipient address for each recipient address.


int dflags, istat;
const char *to, *ito;

while (!(istat = mtaDequeueRecipientNext(dq, &to, NULL, 0)))
{
    mtaDequeueInfo(dq, MTA_DELIVERY_FLAGS, &dflags,
                   MTA_IRCPT_TO, &ito, NULL, 0);
    printf("Delivery flags: %d\n"
           "Intermediate recipient address: %s\n", dflags, ito);
}
if (istat != MTA_EOF)
    printf("An error occured; %s\n", mtaStrError(istat));

mtaDequeueLineNext()

Read the next line of the message from the queued message file.

Syntax


int mtaDequeueLineNext(mta_dq_t    *dq_ctx,
                       const char **line,
                       size_t      *len);

Arguments

Arguments  

Description  

dq_ctx

A dequeue context created by mtaDequeueStart().

line

Optional address of a pointer to receive the address of the next line of the message. The line will not be NULL terminated. A value of NULL may be passed for this argument. 

len

Optional address of a size_t to receive the length of the returned line. A value of NULL may be passed for this argument.

Description

After exhausting a message’s list of envelope recipients by repeated calls to mtaDequeueRecipientNext(), begin reading the message’s header and content with mtaDequeueLineNext(). Each call will return one line of the message, with the first call returning the first line of the message, the second call the second line, and so on. Once the message has been completely read, the status code MTA_EOF will be returned.

The returned lines of the message will not be NULL terminated. This is because the underlying message file is often mapped into memory. When that is the case, then the returned pointer is a pointer into that memory map. Since the message files themselves do not contain NULL terminators and the file is mapped read-only, it is not possible for the SDK to add a NULL terminator to the end of the line without copying it first to a writable portion of memory.

The returned lines of the message will not have any line terminators such as a line feed or a carriage return. It is up to the calling routine to supply whatever line terminators might be appropriate (for example, adding a carriage-return line-feed pair when transmitting the line over SMTP.)

It is possible to call mtaDequeueLineNext() with NULL values for both the line and len call arguments. But this is of limited use; one example is when writing a channel that deletes all queued messages after first counting the number of lines in each message for accounting purposes. More typical of such a channel would be to supply NULL for the line argument but pass a non-zero address for the len argument. That would then allow the channel to count up the number of bytes in the deleted message.

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_BADARGS

A NULL value was supplied for the dq_ctx call argument, or an invalid dequeue context was supplied for dq_ctx.

MTA_EOF

Message file has been completely read; no further lines to return. 

Example


int istat;
const char *line;
size_t len;

while (!(istat = mtaDequeueLineNext(dq_ctx, &line, &len)))
     printf("%.*s\n", len, line);
if (istat != MTA_EOF)
     printf("An error occured; %s\n", mtaStrError(istat));

mtaDequeueMessageFinish()

Complete a message dequeue or defer a message for later processing.

Syntax


int mtaDequeueMessageFinish(mta_dq_t *dq_ctx,
                            int       item_code, ...);

Arguments

Arguments  

Description  

dq_ctx

A dequeue context created by mtaDequeueStart().

item_code

An optional list of item codes. See the description section the follows for a list of item codes. The list must be terminated with an integer argument with value 0.

Description

Before completing processing of a queued message, the disposition of each envelope recipient must be set either by repeated calls to mtaDequeueRecipientDisposition(), or by means of the MTA_DISP item code for mtaDequeueMessageFinish(). For the former, a call should be made for each envelope recipient address. For the latter, the disposition set with MTA_DISP applies to all envelope recipients, overriding any previous settings made with mtaDequeueRecipientDisposition(). It is important that the dispositions be set correctly because they influence whether or not the message is deleted from the channel’s queue by mtaDequeueMessageFinish(). Incorrectly setting the dispositions can lead to duplicate message delivery, or, worse yet, lost mail.

To complete processing of a queued message, call mtaDequeueMessageFinish(). Upon being called, the routine performs one of three possible actions:

After mtaDequeueMessageFinish() is called, the dequeue context passed to it is no longer valid, regardless of the status it returns. When it returns an error status, it also defers the message and all of its recipients for later processing. This is done regardless of the disposition of the recipients. Doing otherwise could potentially lead to lost mail.

Internet standards require that notifications concerning a message be directed to the message’s envelope From: address. In addition, the following two rules apply:

These two rules combine to prevent certain broad classes of message loops. The MTA SDK strictly adheres to these Internet requirements.

Whenever a temporary processing error occurs and the channel can no longer process a queued message, processing of the message should be deferred until a later time. Processing for all recipients is deferred regardless of any prior disposition settings. Temporary processing errors include such errors as: insufficient virtual memory, network problems, disk errors, and other unexpected processing errors.

The following table lists the item codes for this routine, the additional arguments they take, and gives a description of each one.

Item Codes  

Additional Arguments  

Description  

MTA_ABORT

None 

When this item code is specified, processing of the message is deferred for all recipients of the message. The message is left in the channel’s queue and a later processing attempt is scheduled. 

MTA_DISP

size_t disposition

Use the MTA_DISP item code to set the disposition for all recipients of the message. This disposition will override any prior disposition settings.

This item code must be followed by one additional call argument: the disposition value to set. See the description of mtaDequeueRecipientDisposition() for a discussion of the disposition settings.

MTA_ITEM_LIST

mta_item_list_t *item_list

Specify a pointer to an item list array. The item list array must be terminated with a final array entry with an item code value of zero. For further information on item list usage, see Item Codes and Item Lists.

MTA_REASON

const char *reason

size_t reason_len

When deferring processing of a message, the reason for the deferral may be saved as part of the messages delivery history. This delivery history may be viewed by system managers with the MTA qm utility. It may also be reported in delay notifications.

This item code must be followed by two additional call arguments: 

  1. The address of the string containing the reason text.

  2. The length in bytes of the reason text. If a value of zero is passed for the length, then the reason text must be NULL terminated.

Return Values

Return Values  

Description  

Normal, successful completion. 

MTA_BADARGS

Received for one of two reasons: 

  1. A NULL value was supplied for the dq_ctx call argument, an invalid dequeue context was supplied for dq_ctx.

  2. A required argument to an item code was NULL.

MTA_NO

Unable to dequeue the message. This error can result from an attempt to enqueue a new message to a subset of recipients. 

MTA_NOSUCHITEM

An invalid item code was specified. 

MTA_ORDER

Call made out of sequence. The call was made either before the recipient list has been exhausted with mtaDequeueRecipientNext(), or after the message had been dequeued or deferred with mtaDequeueMessageFinish().

MTA_THREAD

The MTA SDK detected simultaneous use of the dequeue context by two different threads. 

Example

There are three code examples, each showing variations on deferring a message.

The following code fragment shows how to use this routine to defer processing of a message until a later time by calling the routine with the MTA_ABORT item code:

mtaDequeueMessageFinish(dq_ctx, MTA_ABORT, 0);

The following code fragment shows how to use this routine to defer processing of a message and setting the disposition:

mtaDequeueMessageFinish(dq_ctx, MTA_DISP, MTA_DISP_DEFERRED, 0);

The following code fragment shows how to use this routine to defer processing of a message with a text string explaining the reason for the deferral:


mtaDequeueMessageFinish(dq_ctx, MTA_ABORT, MTA_REASON,
                        "Temporary network error", 0, 0);

mtaDequeueRecipientDisposition()

Specify the delivery status (disposition) of an envelope recipient address.

Syntax


int mtaDequeueRecipientDisposition(mta_dq_t   *dq_ctx,
                                   const char *env_to,
                                   size_t      env_to_len,
                                   size_t      disposition,
                                   int         item_code, ...);

Arguments

Arguments  

Description  

dq_ctx

A dequeue context created by mtaDequeueStart().

env_to

The recipient address to effect the setting for. This must be the recipient’s envelope To: address as returned by mtaDequeueRecipientNext() and not some transformation of that address. If a value of zero is passed for the env_to_len argument, then this string must be NULL terminated.

env_to_len

The length in bytes of the recipient address, env_to. This length does not include any NULL terminator. If a value of zero is passed for this argument, then the recipient address string must be NULL terminated.

disposition

The delivery status disposition to set for this recipient address. See the description section that follows for further details. 

item_code

An optional list of item codes. See the description section that follows for a list of item codes. The list must be terminated with an integer argument with value 0.

Description

Before completing processing of a queued message, the disposition of each envelope recipient must be set either by repeated calls to mtaDequeueRecipientDisposition(), or by means of the MTA_DISP item code for mtaDequeueMessageFinish(). For the former, a call should be made for each envelope recipient address. For the latter, the disposition set with MTA_DISP applies to all envelope recipients, overriding any previous settings made with mtaDequeueRecipientDisposition(). The delivery status dispositions, and their descriptions are listed in the table that follows. Pass one of these values for the disposition argument.

Delivery Status Dispositions  

Description  

MTA_DISP_DEFERRED

Processing for this recipient has experienced a temporary failure (for example, the network is temporarily down, the disk is currently full, the recipient is presently over quota). Schedule a later processing attempt for this recipient. 

MTA_DISP_DELIVERED

Final delivery has been effected for this recipient address. Any required delivery notifications should be generated. Intermediate processing channels should use MTA_DISP_RELAYED rather than MTA_DISP_DELIVERED. Use of MTA_DISP_DELIVERED by an intermediate processing channel might incorrectly generate a delivery status notification when final delivery has not yet been effected.

MTA_DISP_FAILED

Processing for this recipient has experienced a permanent failure. The message is and will remain undeliverable for this recipient. No further delivery attempts are to be made for this recipient. Any required non-delivery notifications should be generated. 

MTA_DISP_RELAYED

The message has been successfully processed for this recipient. No further processing by this channel is needed for this recipient address. No delivery status notification is generated as final delivery will be effected by another entity capable of generating any needed notification messages. This disposition should be used by intermediate processing channels. It should also be used by gateways that transfer the message to other mail systems capable of generating the necessary notification messages. 

MTA_DISP_RELAYED_FOREIGN

The message has been successfully processed for this recipient. No further processing by this channel is needed for this recipient address; however, a relayed delivery status notification should be generated if delivery notification was requested for this recipient. This disposition should be used by gateways that transfer the message to other mail systems incapable of generating the necessary notification messages. 

MTA_DISP_RETURN

Generate a postmaster non-delivery notification for this recipient and, for this recipient, remove the message from the channel’s queue. This disposition is not intended for use by channels. Instead, it should be used by postmaster utilities that allow the postmaster to manually return mail messages. 

MTA_DISP_TIMEDOUT

Generate a timed-out non-delivery notification indicating that the message has been undeliverable for too long and no further delivery attempts will be made. This disposition is not intended for use by channels. Instead, it is meant for use by the MTA return job that scans the MTA queues, returning old, undeliverable messages to their originators. 

This table lists the item codes for this routine, and the additional required arguments, and gives a description of each.

Item Codes  

Additional Arguments  

Description  

MTA_DISP

size_t disposition

Use the MTA_DISP item code to set the disposition for all recipients of the message. This disposition will override any prior disposition settings. This item code must be followed by one additional call argument: the disposition value to set. See the description of mtaDequeueRecipientDisposition() for a discussion of the disposition settings.

MTA_ITEM_LIST

mta_item_list_t *item_list

Specify a pointer to an item list array. The item list array must be terminated with a final array entry with an item code value of zero. For further information on item list usage, see Item Codes and Item Lists.

MTA_REASON

const char *reason

size_t reason_len

The reason for ascribing the disposition to this recipient address. This reason might then appear in any delivery or non-delivery status notification for that recipient. 

This item code must be followed by two additional call arguments: 

  1. the address of the string containing the reason text.

  2. The length in bytes of the reason text. If a value of zero is passed for the length, then the reason text must be NULL terminated.

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_BADARGS

This value was returned for one of the following reasons: 

  1. A NULL value was supplied for the dq_ctx call argument.

  2. An invalid dequeue context was supplied for dq_ctx.

  3. A required argument to an item code was NULL.

MTA_NOSUCHITEM

An invalid item code was specified. 

MTA_THREAD

The MTA SDK detected simultaneous use of the dequeue context by two different threads. 

Example

This code fragment assumes a condition in which the recipient address is invalid. It returns a disposition of MTA_DISP_FAILED with an explanation.


mtaDequeueRecipientDisposition(
   dq_ctx, "sue@siroe.com", 0, MTA_DISP_FAILED,
   MTA_REASON, "Invalid recipient address: no such user", 0, 0);

mtaDequeueRecipientNext()

Obtain the next envelope recipient address for the queued message file.

Syntax


int mtaDequeueRecipientNext(mta_dq_t    *dq_ctx,
                            const char **env_to,
                            size_t      *env_to_len,
                            int          item code, ...);

Arguments

Argument  

Description  

dq_ctx

A dequeue context created by mtaDequeueStart().

env_to

Optional address of a pointer to receive the memory address of the next envelope recipient address. The recipient address will not be NULL terminated. 

env_to_len

Optional address of a size_t to receive the length of the returned recipient address. A value of NULL may be passed for this argument.

item_code

An optional list of item codes. See the description section that follows for a list of item codes. The list must be terminated with an integer argument with value 0.

Description

The first step in processing a queued message is to retrieve its list of envelope recipient addresses. This is done by repeatedly calling mtaDequeueRecipientNext() until a status code of MTA_EOF is returned. Note that each call that returns a recipient address will return a status code of 0 (MTA_OK). The final call, which returns MTA_EOF, will not return a recipient address.

The processing of the list of envelope recipient addresses will, in general, be unique to each channel. Intermediate processing channels should simply re-enqueue a new message and copy the envelope recipient list verbatim over to the new message being enqueued, being sure to specify the MTA_ENV_TO and MTA_DQ_CONTEXT item codes to mtaEnqueueTo(). The envelope recipient list must be read in its entirety before attempting to read the message itself with mtaDequeueLineNext(). Failure to do so will result in an MTA_ORDER error being returned by mtaDequeueLineNext().

This routine accepts the same item codes as mtaDequeueInfo(). The code fragments are equivalent also, (compare the examples). Consequently, the mtaDequeueInfo() routine might appear superfluous. However, it also serves as a means of obtaining, in a single, non-repeated call, information about the overall message itself, such as the message’s envelope ID.

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_BADARGS

This value was returned for one of the following reasons: 

  1. A NULL value was supplied for the dq_ctx call argument.

  2. An invalid dequeue context was supplied for dq_ctx.

  3. A NULL value was supplied for a required item code argument.

MTA_NOMEM

Insufficient virtual memory. 

MTA_EOF

The recipient list has been completely read; there are no further recipient addresses to return. 

MTA_THREAD

Concurrent use of the dequeue context by two different threads has been detected. 

Example

This code fragment illustrates an intermediate processing channel using this routine to fetch recipient addresses.


int dflags, istat;
const char *to, *ito;
while (!(istat = mtaDequeueRecipientNext(dq, &to, NULL,
                                MTA_DELIVERY_FLAGS, &dflags,
                                MTA_IRCPT_TO, &ito, NULL, 0)))
    printf("Delivery flags: %d\n"
           "Intermediate recipient address: %s\n", dflags, ito);
if (istat != MTA_EOF)
    printf("An error occured; %s\n", mtaStrError(istat));

mtaDequeueRewind()

Reset the read point to the start of the message.

Syntax

int mtaDequeueLineNext(mta_dq_t *dq_ctx);

Arguments

Arguments  

Description  

dq_ctx

A dequeue context created by mtaDequeueStart().

Description

Repositions the read point back to the start of the message.

After obtaining a message’s recipient list by repeated calls to mtaDequeueRecipientNext(), the read point into the underlying message file is positioned at the start of the actual message. Specifically, at the start of the message’s outermost header. Calling mtaDequeueLineNext() advances this read point, with each call moving it towards the end of the message. To reposition the read point back to the start of the message (that is, to the start of the message’s outermost header), call mtaDequeueRewind(). Use this call if a program needs to make a second pass through a message. For example, a program might scan a message’s content before actually processing it.

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_BADARGS

A NULL value was supplied for the dq_ctx call argument, or an invalid dequeue context was supplied for dq_ctx.

MTA_ORDER

Call made out of sequence. The call was made either before the recipient list has been exhausted with mtaDequeueRecipientNext(), or after the message had been dequeued or deferred with mtaDequeueMessageFinish().

MTA_THREAD

The MTA SDK detected simultaneous use of the dequeue context by two different threads. 

Example

None

mtaDequeueStart()

Initiate message dequeue processing.

Syntax


int mtaDequeueStart(void                     *ctx1,
                    mta_dq_process_message_t *process_message,
                    mta_dq_process_done_t    *process_done,
                    int                       item_code, ...);

Arguments

Arguments  

Description  

ctx1

Optional pointer to a caller-supplied context or other data type. This pointer will be passed as the ctx1 argument to the caller-supplied routines process_message and process_done. A value of NULL may be passed for this argument.

process_message

The address of a caller-supplied routine to process each message. 

process_done

Optional address of a caller-supplied clean up routine. A NULL value may be passed for this argument. 

item_code

An optional list of item codes. See the description section that follow for a list of item codes. The list must be terminated with an integer argument with value 0.

Description

The mtaDequeueStart() routine initiates processing of messages queued to a specific channel. By default, the channel serviced will be determined from the PMDF_CHANNEL environment variable. However, a channel name can be explicitly specified with the MTA_CHANNEL item code.

All of the item codes, their additional arguments, and a description of each are included in the table that follows.

Item Codes  

Additional Arguments  

Description  

MTA_CHANNEL

const char *channel

size_t channel_len

Explicitly specify the name of the channel name to perform dequeue processing for. This item code must be followed by two additional call arguments: the name of the channel and the length in bytes of that channel name. If a value of zero is passed for the length, then the channel name must be NULL terminated. 

When this item code is not specified, the name of the channel to process queued messages for is taken from the PMDF_CHANNEL environment variable.

MTA_ITEM_LIST

mta_item_list_t *item_list

Specify a pointer to an item list array. The item list array must be terminated with a final array entry with an item code value of zero. For further information on item list usage, see Item Codes and Item Lists.

MTA_JBC_MAX_ATTEMPTS

size_t attempts

Specify the maximum number of contiguous attempts that will be made to sleep and then re-query the Job Controller for work after being told by the Job Controller that there are no more messages to process. The default value for this setting is 5 attempts. If an attempt succeeds in providing additional work, the count of attempts is reset to zero. (The duration of each sleep may be specified with the MTA_JBC_RETRY_INTERVAL item code.)

This item code must be followed by an additional argument: the maximum number of contiguous attempts to make. 

MTA_JBC_RETRY_INTERVAL

size_t seconds

Set the number of seconds mtaDequeueMessage() sleeps before again querying the Job Controller for additional work. When not specified, a value of 10 seconds is used. This item code must be followed by one additional argument: the number of seconds to sleep for.

MTA_THREAD_MAX_THREADS

size_t threads

Specify the maximum number of processing threads to run concurrently. If not specified, then a limit of 20 threads is assumed.

This item code must be followed by one additional argument: the maximum number of concurrent threads to permit. 

MTA_THREAD_STACK_SIZE

size_t bytes

By default, the processing threads will have a stack whose size is sufficient for MTA SDK operations. This is the size returned by the mtaStackSize() routine. To request a larger size, use this item code to specify the desired size. Note that specification of a smaller size is ignored: mtaDequeueMessage() will never use a stack size smaller than that returned by mtaStackSize().

This item code must be followed by one additional argument: the minimum size in bytes for each thread’s stack. 

MTA_THREAD_MAX_MESSAGES

size_t messages

The number of messages to allocate per processing thread. The channel program will aim to run N processing threads where N is computed as follows: N = (count of pending queued messages) / MTA_THREAD_MAX_MESSAGES. For example, if there are 100 queued messages and MTA_THREAD_MAX_MESSAGES has its default value of 20 messages, then 5 processing threads are started.

This value does not control the total number of messages presented to a single processing thread. 

This item code must be followed by one additional argument: the number of messages for each processing thread. 

MTA_THREAD_WAIT_TIMEOUT

size_t seconds

Once mtaDequeueMessage() determines that there are no more messages to process, it waits for all processing threads to complete their work and exit. By default, mtaDequeueMessage() will wait no longer than 1800 seconds (30 minutes).

This item code must be followed by one additional argument: the maximum number of seconds to wait. 

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_BADARGS

This value is returned for one of following reasons: 

  1. A NULL value was supplied for the dq_ctx call argument.

  2. An invalid dequeue context was supplied for dq_ctx.

  3. A NULL value was specified for the process_message routine.

  4. A NULL value was supplied for a required item code argument.

MTA_FOPEN

Unable to initialize the MTA SDK. Unable to read one or more configuration files. 

For further information, issue the following command: 

imsimta test -rewrite

MTA_NETWORK

Error communicating with the Job Controller. 

MTA_NO

Unable to initialize the MTA SDK. 

For further information, issue the following command: 

imsimta test -rewrite

MTA_NOMEM

Insufficient virtual memory. 

MTA_NOSUCHCHAN

Specified channel is not defined in the MTA configuration file. If no channel was explicitly specified, then the channel name specified with the PMDF_CHANNEL environment variable is not defined in the MTA configuration file. This error may also be returned when the Job Controller’s configuration file lacks a CHANNEL section matching the specified channel.

MTA_NOSUCHITEM

An invalid item code was specified. 

Example

For an example of mtaDequeueStart(), see Example 5–2

Other Considerations for mtaDequeueStart()

This section contains supplementary information concerning mtaDequeueStart(). It covers the following topics:

Multiple Calls to mtaDequeueStart()

A channel program can call mtaDequeueStart() multiple times: either sequentially or in parallel. In the latter case, the program would need to create threads so as to effect multiple, simultaneous calls to mtaDequeueStart(). However, just because this can be done does not mean that it is appropriate to do so. In the former case of multiple sequential calls, there’s no need to be making repeated calls. When mtaDequeueStart() returns, the channel no longer needs immediate processing and has been in that state for

MTA_JBC_ATTEMPTS_MAX * MTA_JBC_RETRY_INTERVAL

seconds. Instead, the channel program should exit thereby freeing up system resources. The Job Controller will start a new channel program running when there are more messages to process. In the latter case of multiple parallel calls, there is again no need to do so. If there is an advantage to running more threads than a single call generates, then the channel’s threaddepth channel keyword setting should be increased so that a single call does generate more threads. The only exception to either of these cases might be if the multiple calls are each for a different channel. Even then, however, the advantage of so doing is dubious as the same effect can be achieved through the use of multiple processes, one for each channel.

Message Processing

When mtaDequeueStart() is called, a communication path with the MTA Job Controller is established. The Job Controller is then asked if there are messages to be processed for the channel. Typically there will be messages to process since it is the Job Controller that normally starts channel programs, and it does so when there are queued messages in need of processing. Based upon information obtained from the Job Controller, mtaDequeueStart() will then begin to create non-joinable processing threads. Each processing thread immediately begins processing the queued messages.

Message Processing Procedure

To process queued messages, a processing thread takes the following steps:

  1. The thread sets ctx2 to have the value NULL:

    ctx2 = NULL;

    For information on the process_message arguments, see process_message() Routine

  2. The thread communicates with the Job Controller to obtain a message file to process. If there are no more message files to process, then go to Message Processing Procedure.

  3. For the message file, the thread creates a dequeue context that maintains the dequeue processing state for that message file.

  4. The thread then invokes the caller-supplied process_message routine, passing to it the dequeue context created in Message Processing Procedure, for example:

    istat = process_message(&ctx2, ctx1, &dq_ctx, env_from, env_from_len);

    For a description of the process_message routine, see process_message() Routine

  5. The process_message routine then attempts to process the message, ultimately removing it from the channel’s queues or leaving the message file for a later processing attempt.

  6. If mtaDequeueMessageFinish() was not called before the process_message routine returned, then the queued message is deferred. That is, its underlying message file is left in the channel’s queue and a later processing attempt is scheduled.

  7. The dequeue context is destroyed.

  8. If the process_message routine did not return the MTA_ABORT status code, then repeat this cycle starting at Message Processing Procedure.

  9. The caller-supplied process_done routine is called, for example:

    process_done(&ctx2, ctx1);

    For a description of the process_done routine, see process_done() Routine

  10. The thread exits.

process_message() Routine

This caller-supplied routine is invoked by the processing threads to do the actual processing of the messages.

The following code fragment shows the required syntax for a process_message routine.


int process_message(void      **ctx2,
                    void       *ctx1,
                    mta_dq_t   *dq_ctx,
                    const char *env_from,
                    int         env_from_len);

The following table lists the required arguments for a process_message routine, and gives a description of each.

Arguments  

Description  

ctx2

A writable pointer that the process_message routine can use to store a pointer to a per-thread context. See the description that follows for further details.

ctx1

The caller-supplied private context passed as ctx1 to mtaDequeueStart().

dq_ctx

A dequeue context created by mtaDequeueStart() and representing the message to be processed by this invocation of the process_message routine.

env_from

A pointer to the envelope From: address for the message to be processed. Since Internet messages are allowed to have zero length envelope From: addresses, this address can have zero length. The address will be NULL terminated.

env_from_len

The length in bytes of the envelope From: string. This length does not include any NULL terminator.

When a processing thread first begins running, it sets the value referenced by ctx2 to NULL. This assignment is made only once per thread and is done before the first call to the process_message routine. Consequently, on the first call to the process_message routine, the following test is true:

*ctx2 == NULL

That test will remain true until such time that the process_message routine itself changes the value by making an assignment to *ctx2. As demonstrated in the following code fragment, if the process_message routine needs to maintain state across calls to itself by the same processing thread, it can allocate memory for a structure to store that state in, and then save a pointer to that memory with ctx2.


int process_message(void **ctx2, void *ctx1,
                    const char *env_from, size_t env_from_len)
{
    struct our_state_t *state;

    state = (our_state_t *)(*ctx2);
    if (!state)
    {
        /*
         * First call for this thread.
         * Allocate a structure in which to store the state
         * information
         */
        state = (our_state_t *)calloc(1, sizeof(our_state_t));
        if (!state) return(MTA_ABORT);
        *ctx2 = (void *)state;

        /*
         * Set any appropriate initial values for the state
         * structure
         */
       ...
    }
...

For a sample process_message routine, see Example 5–2.

process_done() Routine

To assist in cleaning up state information for a thread, callers can provide a routine pointed to by the process_done argument.

The following code fragment shows the required syntax for a process_done() routine.


void process_done(void *ctx2,
                  void *ctx1);

The following table lists the arguments required for a process_done routine, and gives a description of each.

Required Arguments  

Description  

ctx2

The value of the last pointer stored by process_message in the ctx2 call argument for this thread.

ctx1

The caller-supplied private context passed as ctx1 to mtaDequeueStart().

The following code fragment demonstrates the type of actions taken by a process_done routine.


void process_done(ctx2, ctx1)
{
    struct our_state_t *state = (our_state_t *)ctx2;
    if (!state)
         return;
    /*
     * Take steps to undo the state
     * (for example, close any sockets or files)
     */
    ...

    /*
     * Free the memory allocated by process_message()
     * to store the state
     */
    free(state)
}

Thread Creation Loop

While the processing threads are running, the thread that invoked mtaDequeueStart() executes a loop containing a brief pause (that is, a sleep request). Each time the mtaDequeueStart() thread awakens, it communicates with the Job Controller to see if it should create more processing threads. In addition, the Job Controller itself has logic to determine if more threads are needed in the currently running channel program, or if it should create additional processes to run the same channel program.

To demonstrate, the following code fragment shows pseudo code of the mtaDequeueStart() loop.


threads_running = 0
threads_max = MTA_THREAD_MAX_THREADS
attemtps    = MTA_JBC_MAX_ATTEMPTS

LOOP:
    while (threads_running < threads_max)
    {

      Go to DONE if a shut down has been requested

      pending_messages = Ask the Job Controller how many
                         messsages there are to be processed

      // If there are no pending messages
      // then consider what to do next
      if (pending_messages = 0)
      {
          // Continue to wait?
          if (attempts <= 0)
              go to DONE

          // Decrement attempts and wait
          attempts = attempts - 1;
          go to SLEEP
      }
      // Reset the attempts counter
      attempts = MTA_JBC_MAX_ATTEMPTS

      threads_needed = Ask the Job Controller how many
                       processing threads are needed

      // Cannot run more then threads_max threads per process
      if (threads_needed \> threads_max)
          threads_needed = threads_max

      // Create additional threads if needed
      if (threads_needed \> threads_running)
      {
         Create (threads_needed - threads_running) more threads
         threads_running = threads_needed
      }
    }

SLEEP:
    Sleep for MTA_JBC_RETRY_INTERVAL seconds
     -- a shut down request will cancel the sleep
    go to LOOP

DONE:
    Wait up to MTA_THREAD_WAIT_TIMEOUT seconds
    for all processing threads to exit

    Return to the caller of mtaDequeueStart()

mtaDequeueThreadId()

Return the thread ID associated with the specified dequeue context.

Syntax

int mtaDequeueThreadId(mta_dq_t *dq_ctx);

Arguments

Arguments  

Description  

dq_ctx

A dequeue context created by mtaDequeueStart().

Description

Each processing thread is assigned a unique integer identifier referred to as a thread ID. This thread ID is intended as a diagnostic aid when debugging channel programs. Showing it with diagnostic messages helps to differentiate the work of one thread from another in the channel’s debug log file.

The thread ID can also be obtained with mtaDequeueInfo().

Return Values

In the event of an error, the value -1 is returned and mta_errno is set to indicate the error status code.

Error Status Code  

Description  

MTA_BADARGS

A NULL value was supplied for the dq_ctx call argument, or an invalid dequeue context was supplied for dq_ctx.

Example


mtaLog("%08d: process_message() called with dq_ctx=%p",
       mtaDequeueThreadId(dq_ctx), dq_ctx);

mtaDone()

Release resources used by the MTA SDK.

Syntax

void mtaDone(void);

Arguments

None

Description

Once use of the MTA SDK has been finished, mtaDone() should be called to release any resources used by the MTA SDK. The routine should be called while the calling process is single threaded.

Return Values

None

Example

mtaDone();

mtaEnqueueCopyMessage()

Copy a queued message to a new message being enqueued.

Syntax


int mtaEnqueueCopyMessage(mta_nq_t *nq_ctx,
                          mta_dq_t *dq_ctx,
                          int       rewind);

Arguments

Arguments  

Description  

nq_ctx

Message submission to copy the message data to. nq_ctx must be an enqueue context created by mtaEnqueueStart().

dq_ctx

Queued message to copy the message data from. Must be a a dequeue context created by mtaDequeueStart().

rewind

Supply a value of 1 to move the read point in the queued message file to the start of the message before commencing the copy operation. Supply a value of zero to leave the message read point unchanged before copying.

Description

Intermediate processing channels often need to copy verbatim a message from a channel queue to a new message being enqueued. That is, intermediate processing channels often re-enqueue an existing, queued message. This verbatim copy can be accomplished with mtaEnqueueCopyMessage(). Using this routine is significantly faster than using mtaDequeueLineNext() and mtaEnqueueWriteLine() in a read and write loop.

When mtaEnqueueCopyMessage() is called, the copy begins at the current read point of the queued message file associated with the supplied dequeue context, dq_ctx. The message file from that point to its end is copied to the new message being enqueued. To start at the beginning of the queued message (that is, to start at the beginning of its outermost header), specify a value of 1 for the rewind call argument. So doing is equivalent to first calling mtaDequeueRewind() before mtaEnqueueCopyMessage().

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_BADARGS

This value is returned for one of the following reasons: 

  1. A NULL value was supplied for either the nq_ctx or dq_ctx call arguments.

  2. Invalid contexts were passed for either or both of those call arguments.

MTA_FCREATE

Unable to create a temporary file to hold data for the new message being enqueued. 

MTA_FIO

An I/O error occurred while attempting to write data to a message file. 

MTA_ORDER

Call made out of order. Either no recipients have yet been specified for the new message with mtaEnqueueTo(), or the recipient list of the queued message has not been completely read with mtaDequeueRecipientNext().

MTA_THREAD

Simultaneous use of either the enqueue or dequeue context by two different threads was detected. 

Example

The following code fragment specifies starting at the beginning of the queued message by using the rewind call argument.

mtaEnqueueMessageCopy(nq_ctx, dq_ctx, 1);

The code fragment that follows illustrates a second, less efficient way of copying the message.


mtaDequeueRewind(dq_ctx)
while (!mtaDequeueLineNext(dq_ctx, &line, &len))
   mtaEnqueueWriteLine(nq_ctx, line, len, NULL);

mtaEnqueueError()

Retrieve an extended error message.

Syntax


const char *mtaEnqueueError(mta_nq_t    *nq_ctx, const char **message,
                            size_t      *message_len,
                            int          item_code);

Arguments

Arguments  

Description  

nq_ctx

An enqueue context created by mtaEnqueueStart().

message

Optional address of a pointer to receive the address of the NULL terminated error message text. A NULL value may be supplied for this argument. 

message_len

Optional address of a size_t to receive the length in bytes of the error message text. A NULL value may be supplied for this argument.

item_code

Reserved for future use. A value of zero must be supplied for this call argument. 

Description

When mtaEnqueueTo() returns an MTA_NO error message, there is often extended error information available, which takes the form of a text string suitable for writing as diagnostic output. To retrieve this information, issue mtaEnqueueError() immediately after receiving an MTA_NO error return from mtaEnqueueTo().

Return Values

In the event of an error from mtaEnqueueError(), a NULL value will be returned and mta_errno is set to indicate the error status code. The following table lists the error status codes, and gives a description of them.

Error Status Codes  

Description  

0

Normal, successful completion. 

MTA_BADARGS

This value is returned for one of the following reasons: 

  1. A NULL value was supplied for the nq_ctx call argument.

  2. An invalid context was passed for nq_ctx.

MTA_THREAD

Simultaneous use of the enqueue context by two different threads was detected. 

Example

None

mtaEnqueueFinish()

Complete or cancel a message enqueue operation.

Syntax


int mtaEnqueueFinish(mta_nq_t *nq_ctx,
                     int       item_code, ...);

Arguments

Arguments  

Description  

nq_ctx

An enqueue context created by mtaEnqueueStart().

item_code

An optional list of item codes. See the description section that follows for a list of item codes. The list must be terminated with an integer argument with value 0.

Description

Call mtaEnqueueFinish() to complete an enqueue operation, submitting a new message to the MTA for transport and delivery. Alternatively, call mtaEnqueueFinish() with the MTA_ABORT item code to cancel an enqueue operation without submitting a new message. In either case, when mtaEnqueueFinish() is called the enqueue context passed to it, nq_ctx, is disposed of and may no longer be used regardless of whether a success or error status code is returned.

When completing an enqueue operation, the MTA does much of the actual enqueue work, such as, performing any configured header rewriting, content transformation, and actually writing the message copy or copies to the MTA channel queues. Consequently, errors returned by this routine are typically caused by either site imposed limits (that is, the message size exceeds a site configured limit), or file system related problems (for example, the disk is full, write errors to the disk).

When mtaEnqueueFinish() returns an MTA_NO error message, there is often extended error information available. This information may be retrieved with the MTA_REASON item code. This extended error information takes the form of a text string suitable for writing as diagnostic output.

Before calling mtaEnqueueFinish() to complete an enqueue operation, be sure that the envelope recipient list has been specified with mtaEnqueueTo() and any header lines and content have been written with mtaEnqueueWrite() or mtaEnqueueWriteLine().

When cancelling an enqueue operation, no message is submitted to the MTA, and any temporary files that may have been created are disposed of. To cancel an enqueue operation, specify the MTA_ABORT item code.

The following table lists the item codes for this routine, their additional arguments, and gives a description of each.

Item Codes  

Additional Arguments  

Description  

MTA_ABORT

None 

Cancel the current enqueue operation. The message represented by the enqueue context will not be enqueued to the MTA. 

MTA_ITEM_LIST

mta_item_list_t *item_list

Specify a pointer to an item list array. The item list array must be terminated with a final array entry with an item code value of zero. For further information on item list usage, see Item Codes and Item Lists.

MTA_REASON

const char **errmsg

size_t *errmsg_len

Provide the address of a string pointer to receive any extended error message information. In the event of an error associated with submitting the message to the MTA, then the MTA may return additional information. By providing this pointer, that additional information may be obtained for diagnostic purposes. 

This item code should be followed by two additional item codes: 

  1. The address of a pointer to receive the address of the NULL terminated error text.

  2. The address of a size_t to receive the length of that error text.

    A value of NULL may be passed for the errmsg_len argument.

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_BADARGS

This value is returned for one of the following reasons: 

  1. A NULL value was supplied for the nq_ctx call argument.

  2. An invalid enqueue context was supplied for nq_ctx.

  3. A required argument to an item code was NULL.

MTA_FCREATE

Insufficient disk space or other I/O error encountered while attempting to create or close a message file or a temporary file. 

MTA_FIO

An I/O error occurred while writing message files to the MTA channel queues or while reading from a temporary file. 

MTA_NO

Error terminating the message temporary file, there appears to be insufficient disk space to write the message copies, or there is a problem with a configured content scanner (for example, a virus or spam filter). 

MTA_NOSUCHITEM

An invalid item code was supplied. 

MTA_ORDER

The call was made out of order. Either no envelope recipient addresses have been specified or no message content has been provided. 

MTA_THREAD

Simultaneous use of the enqueue context by two different threads was detected. 


Note –

In case of an error, the MTA_REASON item code can be used to receive extended error message information


As shown in the preceding table, in the case of an error, the MTA_REASON item code can be used to receive extended error message information

Example

See A Simple Example of Enqueuing a Message.

mtaEnqueueInfo()

Obtain information associated with an ongoing message enqueue.

Syntax


int mtaEnqueueInfo(mta_nq_t *nq_ctx,
                   int       item_code, ...);

            int mtaEnqueueInfo(mta_nq_t *nq_ctx,

Arguments

Arguments  

Description  

nq_ctx

An enqueue context created by mtaEnqueueStart().

item_code

An optional list of item codes. See the description section that follows for a list of item codes. The list must be terminated with an integer argument with value 0.

Description

Information associated with an ongoing message enqueue operation may be obtained with mtaEnqueueInfo(). The information to obtain is specified through the use of item codes. Arguments to the item codes provide memory addresses through which to return the requested data.

String pointers returned by mtaEnqueueInfo() are only valid during the life of the enqueue context. Once the enqueue has been completed, the associated pointers are no longer valid.

The following table lists the item codes for this routine, their additional arguments, and gives a description of each.

Item Codes  

Additional Arguments  

Description  

MTA_ALIAS_EXPAND

size_t *value

Return the setting of the alias expansion flag. Normally, this flag has a nonzero value that indicates that alias expansion should be done for all envelope recipient addresses. When the flag has a value of zero, alias expansion will not be performed. The value of the flag is set with the mtaEnqueueStart() routine.

This item code must be followed by one additional argument: the address of size_t to store the setting’s value in.

MTA_ADR_SORT

size_t *value

Obtain the setting of the address sorting flag. Normally, this flag has a non-zero value that indicates that the list of envelope recipients written to each message copy in the MTA channel queues are to be sorted in ascending order based upon US-ASCII ordinal values. When this flag has a value of zero, the list of envelope recipient addresses will not be sorted. This item code must be followed by one additional argument: the address of size_t to store the setting’s value in.

MTA_CHANNEL

char **channel

size_t *channel_len

Obtain the name of the channel that this message is being enqueued by. 

This item code must be followed by two additional call arguments: 

  1. The address of a pointer to receive the address of the NULL terminated channel name.

  2. The address of a size_t to receive the length of the channel name. A NULL value may be passed for the channel_len argument.

MTA_DELIVERY_FLAGS

size_t *dflags

Return the envelope delivery flags set for the entire message by mtaEnqueueStart().

This item code must be followed by one additional call argument: the address of a size_t to receive the delivery flag setting.

MTA_ENV_FROM

const char **env_from

size_t *env_from_len

Retrieve the envelope From: address specified when the enqueue was started with mtaEnqueueStart().

This item code must be followed by two additional call arguments: 

  1. The address of a pointer to receive the address of the NULL terminated envelope From: address.

  2. The address of a size_t to receive the length of that address. A NULL value may be passed for the env_from_len argument.

MTA_ENV_ID

const char **env_id

size_t *env_id_len

Obtain the envelope ID specified with mtaEnqueueStart().

This item code must be followed by two additional call arguments: 

  1. The address of a pointer to receive the address of the NULL terminated envelope ID.

  2. The address of a size_t to receive the length of that envelope ID. A NULL value may be passed for the env_id_len argument.

MTA_EXPAND_LIMIT

size_t *value

Retrieve the expand limit setting specified with mtaEnqueueStart(). The returned value will be a positive integer value. When no expand limit has been set, the returned value will be a large integer value (for example, 2,147,483,647 on 32-bit processors).

This item code must be followed by one additional argument: the address of a size_t to store the setting’s value in.

MTA_FRAGMENT_BLOCKS

size_t *value

Obtain the value, if any, specified for the MTA_FRAGMENT_BLOCKS setting when the message enqueue was initiated. The returned value will be a positive integer value. When no value was set, the returned value will be a large integer value (for example, 2,147,483,647 on 32-bit processors).

This item code must be followed by one additional argument: the address of a size_t to store the setting’s value in.

MTA_FRAGMENT_LINES

size_t *value

Obtain the value specified for the MTA_FRAGMENT_LINES setting when the message enqueue was initiated. The returned value will be a positive integer value. When no value was set, the returned value will be a large integer value (for example, 2,147,483,647 on 32-bit processors).

This item code must be followed by one additional argument: the address of a size_t to store the setting’s value in.

MTA_NOTIFY_FLAGS

size_t *nflags

Return the delivery status notification flags set for the entire message when the enqueue was started. The returned value is a bit map constructed using the MTA_NOTIFY_ constants defined in mtasdk.h. If no setting was effected with mtaEnqueueStart(), then the returned value will be the MTA default of: MTA_NOTIFY_DELAY | MTA_NOTIFY_FAILURE | MTA_NOTIFY_CONTENT_FULL

This item code must be followed by one additional call argument: the address of a size_t to receive the setting of the delivery status notification flags.

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_BADARGS

This value is returned for one of the following reasons: 

  1. A NULL value was supplied for the nq_ctx call argument.

  2. An invalid enqueue context was supplied for nq_ctx.

  3. A required argument to an item code was NULL.

MTA_NOSUCHITEM

An invalid item code was specified. 

MTA_THREAD

Simultaneous use of the enqueue context by two different threads was detected. 

Example

The following code fragment obtains the name of the channel used as the source channel for the enqueue.


mta_nq_t *nq;
const char *channel;

mtaEnqueueStart(&nq, "sue@siroe.com", 0, 0);
mtaEnqueueInfo(nq, MTA_CHANNEL, &channel, NULL, 0);
printf("Source channel = %s\n", channel);

mtaEnqueueStart()

Initiate a message submission.

Syntax


int mtaEnqueueStart(mta_nq_t   **nq,
                    const char *env_from,
                    size_t      env_from_len,
                    int         item_code, ...);

Arguments

Arguments  

Description  

nq_ctx

On a successful return, a pointer to an enqueue context created by mtaEnqueueStart(). This enqueue context represents the message enqueue operation initiated by the call.

env_from

Optional pointer to the address to use as the envelope From: address for the message being submitted. The address must be compliant with RFC 2822. When used as an envelope address, the MTA will reduce it to an RFC 2821 compliant transport address. The string must be NULL terminated if a value of zero is passed for env_from_len. The length of this string, not including any NULL terminator, may not exceed ALFA_SIZE bytes.

A value of NULL may be supplied for this argument. When that is done, the env_from_len argument is ignored and an empty envelope From: address is used for the message submission.

env_from_len

The length in bytes, not including any NULL terminator, of the envelope From: address supplied with env_from. If a value of zero is passed for this argument, then the envelope From: address string must be NULL terminated.

item_code

An optional list of item codes. See the description section that follows for a list of item codes. The list must be terminated with an integer argument with value 0.

Description

To submit a message to the MTA for delivery, an enqueue operation must be initiated. This is achieved by calling mtaEnqueueStart(). When the call is successful, an enqueue context representing the enqueue operation will be created and a pointer to the context returned via the nq_ctx call argument. This context must then be used to specify the message’s envelope recipient list and content, both header and body. Once the recipient list and content have been specified, the submission may be completed with mtaEnqueueFinish(). That same routine is also used to cancel an enqueue operation. For further information on message enqueue processing, see Basic Steps to Enqueue Messages.

Enqueue contexts are disposed of with mtaEnqueueFinish(), either as part of completing or cancelling a message enqueue operation.

When initiating an enqueue operation, the envelope From: address for the message should be specified with the env_from and env_from_len call arguments, or through use of a dequeue context with the MTA_DQ_CONTEXT item code. In either case, it is important to keep in mind the usage of the envelope From: address. MTAs transporting the message use it as a return path, that is, the address to which notifications about the message should be returned. Specifically, it is the address to which the message will be returned in the form of a non-delivery notification (NDN) should the message prove undeliverable. It is also the address to which any delivery status notifications (DSNs) will be sent. As such, the envelope From: address specified should be an address suitable for receiving such notifications.


Note –

Automatically generated messages such as NDNs and DSNs are required to have an empty envelope From: address, that is, a zero length address. These rules are mandated by Internet standards so as to prevent broad classes of looping messages. It is imperative that they be observed; failure to do so may result in exponentially growing mail loops that affect not only your own mail system but possibly mail systems of other sites with which you exchange mail.


When explicitly specifying the envelope From: address via the env_from and env_from_len call arguments, note the following points:

When using a dequeue context to supply the envelope From: address, simply supply a value of NULL and zero for, respectively, the env_from and env_from_len call arguments. Be sure to also supply the dequeue context with the MTA_DQ_CONTEXT item code. For example:

ires = mtaEnqueueStart(&nq, NULL, 0, MTA_DQ_CONTEXT, dq, 0);

If the submitted message lacks a From: header line, then the address supplied as the envelope From: address will also be used to generate a From: header line. This is the reason why mtaEnqueueStart() allows an RFC 2822 compliant address to be supplied for the envelope From: address. When placing the supplied address into the envelope, the MTA reduces it to an RFC 2821 compliant address (for example, removes any RFC 2822 phrases or comment fields).

When submitting a message, the MTA requires a source channel to associate with the enqueue operation. By default, the name of the source channel will be derived from the PMDF_CHANNEL environment variable. However, this may be overridden one of two ways: by supplying a dequeue context with the MTA_DQ_CONTEXT item code, or by explicitly specifying the channel name with the MTA_CHANNEL item code. Use of a dequeue context implicitly specifies the source channel name to be the name of the channel associated with the dequeue context.


Note –

An explicitly specified channel name will take precedence over a channel name specified with a dequeue context.


As part of initiating a message submission, item codes may be used to specify additional envelope information for the message as well as select non-default values for MTA parameters that influence message enqueue processing.

The following table lists the items codes for this routine, their additional arguments, and gives a description of each.

Item Codes  

Additional Arguments  

Description  

MTA_ALIAS_EXPAND

None 

When this item code is specified, each envelope recipient address is allowed to undergo alias expansion (for example, mailing list expansion). This is the default behavior. 

MTA_ALIAS_NOEXPAND

None 

Use of this item code inhibits alias expansion for the envelope recipient addresses. The default behavior is to permit alias expansion. 

MTA_ADR_NOSORT

None 

Inhibit sorting of the envelope recipient list in the message copies written to the MTA channel queues. By default, the envelope recipient address list is sorted. Use this option if it is imperative that the envelope recipients be processed in some specific order. Maintaining the order requires control of all MTA channels that the message will pass through. 

MTA_ADR_SORT

None 

Allow the envelope recipient list to be sorted in the message copies written to the MTA channel queues. This is the default behavior. 

MTA_CHANNEL

char *channel

size_t channel_len

Explicitly specify the name of the channel under which to enqueue this message. That is, explicitly specify the name of the source channel to use for this message submission. The name specified will override any name implicitly specified with the MTA_DQ_CONTEXT item code.

This item code must be followed by two additional call arguments: 

  1. The address of the string containing the channel name.

  2. The length in bytes of that channel name. If a value of zero is specified for the length, then the channel name string must be NULL terminated.

MTA_DELIVERY_FLAGS

size_t dflags

Specify additional envelope delivery flags to set for this message. The logical OR of any existing setting and the value here supplied will be used for the message’s delivery flag setting. In general, the delivery flag setting associated with a message will be the logical OR of the values set by each channel a message has travelled through. Note that channels also can set this value with the deliveryflags channel keyword. When this item code is not used, the delivery flags inherited from a supplied dequeue context will be used. If no dequeue context is supplied, then the value of the delivery flags will be set to zero.

This item code should be followed by an additional call argument: the value to combine with any existing setting. 

MTA_DELIVERY_FLAGS_ABS

size_t dflags

Ignore any previous envelope delivery flag setting for the message and replace the setting with the value specified with this item code. 

This item code should be followed by an additional call argument: the delivery flag setting to effect. 

MTA_DQ_CONTEXT

mta_dq_t *dq_ctx

When a dequeue context is supplied with this item code, the message submission will take all of its envelope fields, except for the recipient list, from the envelope of the queued message represented by the dequeue context, including the envelope From: field. These assumed settings can then be overridden on an individual basis through the use of other item codes, and the env_from and env_from_len call arguments.

Use of this item code changes the defaults for the envelope fields from the MTA defaults to the values used in the dequeue context. 

Intermediate processing channels are strongly encouraged to use this item code. Use of this feature allows envelope information to be automatically copied from the queued message being processed to the new message that will be enqueued as a result. 

This item code must be followed by one additional argument: the pointer to the dequeue context to use. 

MTA_ENV_ID

const char *env_id

size_t env_id_len

Explicitly specify an envelope ID string for the message. The supplied value must conform to the syntax of an xtext object in RFC 1891 and may not have a length exceeding 100 bytes. The value specified with this item code will override any value implicitly specified with the MTA_DQ_CONTEXT item code. If no value is supplied either explicitly or implicitly, then the MTA will generate a unique envelope ID for the message.

This item code must be followed by two additional call arguments: 

  1. The address of the envelope ID string.

  2. The length in bytes of that string. If a value of zero is supplied for the length, then the string must be NULL terminated.

MTA_EXPAND_LIMIT

size_t limit

If the message has more envelope recipients than the specified limit, then processing of the recipient list (that is, alias expansion) will be deferred. This deferral is performed by enqueuing the message to the reprocess channel. At a later time, and running in a separate process, the reprocess channel will complete the processing of the envelope recipient list. 

This item code must be followed by one additional argument: the limit to impose. By default, no limit is imposed. 

MTA_FRAGMENT_BLOCKS

size_t blocks

A large enqueued message may automatically be fragmented into several, smaller messages using MIME’s message/partial content type. At the destination MTA system, these smaller messages may automatically be re-assembled back into one single message. The MTA_FRAGMENT_BLOCKS item code allows specification of a size threshold for which messages larger than the threshold will automatically be fragmented. The limit specified is measured in units of blocks. (By default, a block is 1024 bytes.) However, sites may change that size with the MTA BLOCK_SIZE option. Consequently, code using this option should use the mtaBlockSize() option should they need to convert some other unit to blocks.

This item code must be followed by one additional argument: the block size threshold to impose. By default, no threshold is imposed. 

MTA_FRAGMENT_LINES

size_t lines

A large enqueued message can be automatically fragmented into several, smaller messages using the MIME content type message/partial. At the destination MTA system, these smaller messages can be automatically re-assembled back into one single message. The MTA_FRAGMENT_LINES item code allows specification of a line count threshold for which messages exceeding the threshold will automatically be fragmented.

This item code must be followed by one additional argument: the line count threshold to impose. By default, no threshold is imposed. 

MTA_NOTIFY_FLAGS

size_t nflags

Specify the delivery status notification flags to be set for the entire message. The specified value is a bit map constructed using the MTA_NOTIFY_ constants defined in mtasdk.h. If no setting is made, then the value from a supplied dequeue context will be used. If no dequeue context is supplied, then the MTA default value is used. The default value is:

MTA_NOTIFY_DELAY | MTA_NOTIFY_FAILURE | MTA_NOTIFY_CONTENT_FULL

Flags for individual recipient address may be specified when mtaEnqueueTo() is called.

This item code must be followed by one additional call argument: the address of an integer to receive the setting of the delivery status notification flags. 

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_BADARGS

This value is returned for one of the following reasons: 

  1. A NULL value was supplied for the nq_ctx call argument.

  2. An invalid enqueue context was supplied for nq_ctx.

  3. A required argument to an item code was NULL.

MTA_NO

Unable to determine the channel name from the PMDF_CHANNEL environment variable,

MTA_NOMEM

Insufficient virtual memory. 

MTA_NOSUCHCHAN

Specified channel name does not exist in the MTA configuration. 

MTA_NOSUCHITEM

An invalid item code was specified. 

MTA_STRTRUERR

The supplied envelope From: address is too long; it may not exceed a length of ALFA_SIZE bytes. Or the supplied channel name has a length exceeding CHANLENGTH bytes.

Example

This routine is used as part of Example 5–2.

mtaEnqueueTo()

Add an envelope recipient to a message being submitted.

Syntax


int mtaEnqueueTo(mta_nq_t   *nq_ctx,
                 const char *to_adr,
                 size_t      to_adr_len,
                 int         item_code, ...);

Arguments

Arguments  

Description  

nq_ctx

Pointer to an enqueue context created with mtaEnqueueStart().

to_adr

An address to add to the message being enqueued. The address must be compliant with RFC 2822. When used as an envelope address, the MTA will reduce it to an RFC 2821 compliant transport address. If a value of zero is passed for to_adr_len the address string must be NULL terminated. The length of this string, not including any NULL terminator, may not exceed ALFA_SIZE bytes.

to_adr_len

The length in bytes, not including any NULL terminator, of the address supplied with to_adr. If a value of zero is passed for this argument, then the address string must be NULL terminated.

item_code

An optional list of item codes. See the description section below for a list of item codes. The list must be terminated with an integer argument with value 0.

Description

After initiating a message enqueue operation with mtaEnqueueStart(), the envelope recipient list for the message must to be constructed. This list is the actual list of recipients to which the message is to be delivered. A message must have at least one envelope recipient address; otherwise, there is no one to deliver the message to. In the envelope there is no distinction between To:, Cc:, or Bcc: addressees. Additionally, the list of addressees appearing in the message’s header need not be the same as those appearing in the envelope. This is the case with list-oriented mail. The address in the message’s header is often the list’s mail address; whereas, the addresses in the envelope are the those of the list’s individual members.

By default, when an address is added to a message with mtaEnqueueTo(), it is added as both an envelope recipient address as well as a To: addressee in the message’s To: header line. The address is therefore considered to be an active transport address as well as a header address. This case corresponds to the MTA_TO item code. To instead mark an active transport address for addition to either a Cc: or Bcc: header line, use the MTA_CC or MTA_BCC item code.

Addresses that only appear in the message’s header are sometimes referred to as inactive addresses. Such addresses added with mtaEnqueueTo() may be noted as such with the MTA_HDR_TO, MTA_HDR_CC, and MTA_HDR_BCC item codes. They can also be manually added by constructing the To:, Cc:, or Bcc: header lines with mtaEnqueueWrite() or mtaEnqueueWriteLine().


Note –

The MTA SDK will automatically generate multiple message copies when Bcc: recipients exist for the message. Specifically, when a message has N envelope recipient addresses which are Bcc: recipients, the MTA SDK will automatically generate N+1 message copies: one copy for each of the Bcc: recipients and an additional copy for the remaining, non-Bcc: recipients. Each copy for a Bcc: recipient will only disclose that Bcc: recipient in the message’s header. The message copy for all of the non-Bcc: recipients will disclose none of the Bcc: recipients in its header


An address may be added as only an active transport address without addition to any header line. This is done with the MTA_ENV_TO item code. This item code should be used by intermediate processing channels that copy verbatim the outer message header from the old message to the new, which prevents duplication of addresses in the new message’s header.

When an active transport address is added to a message, it is possible that the MTA will reject the address. For example, the address can be rejected when there is a mapping table, such as the SEND_ACCESS mapping table. When an address is rejected by the MTA, extended error text is made available by the MTA. This extended information can be captured through use of the MTA_REASON item code.

The following table lists the item codes for this routine, their additional arguments, and gives a description of each.

Item Codes  

Additional Arguments  

Description  

MTA_BCC

None 

The address is an active transport address that should also appear in a Bcc: header line. The address will be added to both the envelope recipient list as well as the message’s header. For further information about Bcc:, see the note under Description.

MTA_CC

None 

The address is an active transport address that should also appear in a Cc: header line. As such, the address will be added to both the envelope recipient list as well as the message’s header.

MTA_DELIVERY_FLAGS

size_t dflags

Specify additional envelope delivery flags to set for this recipient. The logical OR of any existing setting for the recipient and the value here supplied will be used for the recipient’s delivery flag setting. The existing setting for the recipient will be either the message’s setting, which was set with mtaEnqueueStart(), or any setting copied over from the dequeue context for this recipient with the MTA_DQ_CONTEXT item code.

This item code should be followed by one additional call argument: the value to combine with any existing setting. 

MTA_DELIVERY_FLAGS_ABS

size_t dflags

Ignore any previous envelope delivery flag setting for the recipient and replace the setting with the value specified with this item code. 

This item code should be followed by one additional call argument: the delivery flag setting to effect. 

MTA_DQ_CONTEXT

mta_dq_t *dq_ctx

When a dequeue context is supplied using this item code, the specified envelope recipient address is compared to the envelope recipient list for the queued message represented by the dequeue context. If a match is found, envelope fields for the recipient are copied from the queued message to the new message being enqueued. If no match is found, an MTA_NO error status is returned.

This item code must be followed by one additional argument: the pointer to the dequeue context to use. 

MTA_ENV_TO

None 

The address is an active transport address; add it to the envelope recipient list. Do not add it to any header lines. This designation is often used by intermediate processing channels. 

MTA_HDR_BCC

None 

The address is not an active transport address; do not add it to the envelope recipient list. The address should, however, be added to a Bcc: header line. Note that since a Bcc: header line is usually only placed in the message copy destined to the Bcc: recipient, use of this item code only arises when the Bcc: recipient’s header address differs from their transport address and, consequently, the two need to be added with separate calls to mtaEnqueueTo().

MTA_HDR_CC

None 

The address is not an active transport address; do not add it to the envelope recipient list. The address should, however, be added to a Cc: header line.

MTA_HDR_TO

None 

The address is not an active transport address; do not add it to the envelope recipient list. The address should, however, be added to a To: header line.

MTA_NOTIFY_FLAGS

size_t nflags

Delivery status notification flags specific to this envelope recipient address. A value specified with this item code overrides any setting made for the message itself when the enqueue context was created. It also overrides any value inherited from a dequeue context. Note that this item code has no effect when MTA_HDR_BCC, MTA_HDR_CC, or MTA_HDR_TO is specified; notification flags only apply to active transport addresses. For further details, see the description of this item code for mtaEnqueueStart().

This item code must be followed by one additional call argument: the address of an integer to receive the setting of the delivery status notification flags. 

MTA_ORCPT_TO

const char *orcpt

size_t orcpt_len

Specify the original envelope recipient address in RFC 1891 original-recipient address format (for example, rfc822;sue@siroe.com for sue@siroe.com).

This item code must be followed by two additional arguments: 

  1. The pointer to the original recipient address.

  2. The length in bytes of that address. If a value of zero is supplied for the length, then the address string must be NULL terminated.

MTA_REASON

const char **errmsg

size_t *errmsg_len

Provide the address of a string pointer to receive any extended error message information. In the event of an error associated with submitting the recipient to the MTA, then the MTA may return additional information. By providing this pointer, that additional information may be obtained for diagnostic purposes. 

This item code should be followed by two additional item codes: 

  1. The address of a pointer to receive the address of the NULL terminated error text.

  2. The address of a size_t to receive the length of that error text. A value of NULL can be passed for the errmsg_len argument.

MTA_TO

None 

The address is an active transport address that should also appear in a To: header line. This is the default interpretation of addresses added with mtaEnqueueTo().

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_BADARGS

This value is returned for one of the following reasons: 

  1. A NULL value was supplied for the nq_ctx call argument.

  2. An invalid enqueue context was supplied for nq_ctx.

  3. A required argument to an item code was NULL.

MTA_NO

If MTA_DQ_CONTEXT was specified, then the supplied envelope To: address does not match any envelope recipient address in the queued message represented by the supplied dequeue context. Otherwise, the MTA rejected the envelope recipient address. It could be syntactically invalid, refused by a mapping table, such as SEND_ACCESS. Consider using the MTA_REASON item code.

MTA_NOSUCHITEM

An invalid item code was specified. 

MTA_ORDER

The call was made out of order: the message’s envelope recipient list has already been terminated by a call to mtaEnqueueWrite() or mtaEnqueueWriteLine().

MTA_STRTRUERR

The supplied envelope To: address or original envelope To: address is too long. Neither may exceed a length of ALFA_SIZE bytes.

Example

This routine is used in Example 5–2.

mtaEnqueueWrite()

Write message data to the message being submitted.

Syntax


int mtaEnqueueWrite(mta_nq_t    *nq_ctx,
                    const char  *str1,
                    size_t       len1,
                    const char  *str2, ...);

Zero or more string pointer-length pairs can be supplied to this routine. The list of pairs must be terminated by a NULL call argument.

Arguments

Arguments  

Description  

nq_ctx

Pointer to an enqueue context created with mtaEnqueueStart().

str1

Pointer to a string of text to write to the message. The string must be NULL terminated if a value of zero is passed for len1.

len1

The length in bytes, not including any NULL terminator, of the string str1. If a value of zero is passed for this argument, then the string str1 must be NULL terminated.

str2

Pointer to a second string of text to write to the message. The string must be NULL terminated if a value of zero is passed for len2. If only supplying a single string, then pass a NULL value for this argument.

Description

After a message’s list of envelope recipient addresses has been supplied with mtaEnqueueTo(), the message itself must be supplied. This is done by repeatedly calling mtaEnqueueWrite(). First the message’s header should be supplied, followed by a blank line, followed by any message content. Each line of message data must be terminated by a US-ASCII line-feed character (0x0A). Each call to mtaEnqueueWrite() can supply one or more bytes of the message’s data. Unlike mtaEnqueueWriteLine(), a single call to mtaEnqueueWrite() does not necessarily correspond to a single, complete line of message data; it could correspond to a partial line, a complete line, multiple lines, or even one or more complete lines plus a partial line. This flexibility with mtaEnqueueWrite() exists because it is up to the caller to supply the message line terminators. Calling either mtaEnqueueWrite() or mtaEnqueueWriteLine() terminates the message’s envelope recipient list. Once either of these routines have been called, mtaEnqueueTo() can no longer be called for the same enqueue context.

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_BADARGS

This value is returned for one of the following reasons: 

  1. A NULL value was supplied for the nq_ctx call argument.

  2. An invalid enqueue context was supplied for nq_ctx, or a required argument to an item code was NULL.

MTA_FCREATE

Unable to create a disk file. 

MTA_FIO

Error writing to a disk. 

MTA_ORDER

Call made out of order. No envelope recipient addresses have been supplied. 

MTA_THREAD

Simultaneous use of the enqueue context by two different threads was detected. 

Example

The code fragment that follows shows two ways to produce the same results. They both write two header lines to the message:


mtaEnqueueWrite(nq, "From: sue@siroe.com\n", 0, NULL);
mtaEnqueueWrite(nq, "Subject: test\n", 0, NULL);


mtaEnqueueWrite(nq, "From: sue@siroe.com\nSubject: test\n", 0,
                NULL);

The following code fragment shows the two header lines output by each code fragment in the preceding code example.


 From: sue@siroe.com
Subject: test

This code fragment demonstrates how to terminate the message header by writing a blank line.

mtaEnqueueWrite(nq, "\n", 0, NULL);

The following code fragment shows a single call to mtaEnqueueWrite()that writes out an entire header, including the terminating blank line.


mtaEnqueueWrite(nq, "Date: today\nFrom: sue@siroe.com\n"
                    "To: bob@siroe.com\nSubject: test\n\n", 0,
                    NULL);

The following code example shows an alternate way of writing the routine call, but with one pair per line.


mtaEnqueueWrite(nq, "Date: today\n", 0,
                    "From: sue@siroe.com\n", 0,
                    "To: bob@siroe.com\n", 0,
                    "Subject: test\n", 0,
                    "\n", 0,
                    NULL);

mtaEnqueueWriteLine()

Write a complete, single line of message data to the message being submitted.

Syntax


int mtaEnqueueWrite(mta_nq_t    *nq_ctx,
                    const char  *str1,
                    size_t       len1,
                    const char  *str2, ...);

Zero or more string pointer-length pairs can be supplied to this routine. The list of pairs must be terminated by a NULL call argument.

Arguments

Arguments  

Description  

nq_ctx

Pointer to an enqueue context created with mtaEnqueueStart().

str1

Pointer to a string of text to write to the message. The string must be NULL terminated if a value of zero is passed for len1.

len1

The length in bytes, not including any NULL terminator, of the string str1. If a value of zero is passed for this argument, then the string str1 must be NULL terminated.

str2

Pointer to a second string of text to write to the message. The string must be NULL terminated if a value of zero is passed for len2. If only supplying a single string, then pass a NULL value for this argument.

Description

After a message’s list of envelope recipient addresses has been supplied with mtaEnqueueTo(), the message itself must be supplied. This can be done by repeatedly calling mtaEnqueueWriteLine(). First the message’s header should be supplied, followed by a blank line, followed by any message content. Each call to this routine must supply a single, complete line of the message. The line should not include a line-feed terminator as mtaEnqueueWriteLine() will supply the terminator automatically.

Calling mtaEnqueueWriteLine() terminates the message’s envelope recipient list. Once the routine is called, mtaEnqueueTo() can no longer be called for the same enqueue context.

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_BADARGS

This value is returned for one of the following reasons: 

  1. A NULL value was supplied for the nq_ctx call argument.

  2. An invalid enqueue context was supplied for nq_ctx, or a required argument to an item code was NULL.

MTA_FCREATE

Unable to create a disk file. 

MTA_FIO

Error writing to a disk. 

MTA_ORDER

Call made out of order. No envelope recipient addresses have been supplied. 

MTA_THREAD

Simultaneous use of the enqueue context by two different threads was detected. 

Example

This code fragment writes out two header lines.


mtaEnqueueWriteLine(nq, "From: sue@siroe.com", 0, NULL);
mtaEnqueueWriteLine(nq, "Subject: test", 0, NULL);

This code fragment shows the header output as a result of the preceding code example.


From: sue@siroe.com
Subject: test

The following code fragment shows how to terminate the header by writing a blank line.

mtaEnqueueWriteLine(nq, "", 0, NULL);

The following code fragment that produces a Date: header line.


char buf[64];

mtaEnqueueWriteLine(nq,
                     "Date: ", 0,
                      mtaDateTime(buf, NULL, sizeof(buf), 0), 0,
                      NULL);

mtaErrno()

Obtain the last returned error status for the calling thread.

Syntax

int mtaErrno(void);

Arguments

None

Description

When an MTA SDK routine is called by a processing thread and returns an error status code, the SDK saves that status code in thread-specific data. The same processing thread can obtain the most recently saved status code for its own thread of execution by calling mtaErrno().

For convenience purposes, the mtasdk.h header file also defines mta_errno as a macro that calls mtaErrno(). Specifically:

#define mta_errno mtaErrno()

Return Values

The last error return status code returned by an MTA SDK routine called by this processing thread.

For a description of the MTA SDK error status codes, see Chapter 9, Error Status Codes Summary

Example

The following code fragment demonstrates how to obtain the most recent error status code for its own thread.


if (!mtaEnqueueStart(&nq, from_adr, 0, 0))
    printf("Error returned: %d\n", mtaErrno());

mtaInit()

Initialize the MTA SDK.

Syntax

int mtaInit(int item_code, ...);

Arguments

Arguments  

Description  

item_code

An optional list of item codes. See the description section that follows for a list of item codes. The list must be terminated with an integer argument with value 0.

Description

Call the mtaInit() routine to initialize the MTA SDK. As part of the initialization process, the SDK will load the MTA configuration. This loading process will be the typical cause of initialization failures; either there’s an error in a configuration file, a missing but required configuration file, or a configuration file can’t be accessed for reading. To prevent that last error case, ensure that your programs run under a UID that has read access to the MTA configuration files, especially the compiled configuration file produced by the imsimta cnbuild utility.

While there is no benefit to doing so, it is safe to call mtaInit() multiple times, either before or after calling mtaDone(). (To de-initialize the SDK, use mtaDone().)

Although the MTA SDK is self-initializing, the initialization must occur while the process is single-threaded. As such, multi-threaded programs must call mtaInit() and must do so while still single threaded.

When the SDK is initialized, the SDK can be told using an item code whether or not the calling program will be functioning as an interactive utility or not. When being used by an interactive utility, such as a management utility or a user agent, the SDK ensures that accounting files are closed after every operation that records accounting information. This prevents the accounting file from being left open by a single process for long periods of time. To specify that the SDK will be used by an interactive utility, specify the MTA_INTERACTIVE item code. By default, the SDK assumes that it will be run by a channel program or other program that wishes to achieve maximum performance while using the SDK. This corresponds to the MTA_CHANNEL item code. Also, when the SDK self-initializes itself, it assumes MTA_CHANNEL and not MTA_INTERACTIVE. As part of initializing the SDK, a number of diagnostic facilities can be enabled. These are enabled using the MTA_DEBUG_ item codes described in the following table. These diagnostic facilities may also be enabled at any time using the mtaDebug() routine.

Item Code  

Additional Arguments  

Description  

MTA_CHANNEL

None 

Indicate that the SDK is being used by a channel program or other non-interactive program. By default this is the assumed usage. Interactive programs should use the MTA_INTERACTIVE item code.

MTA_DEBUG_DECODE

None 

Enable diagnostic output from the low-level MIME decoding routines used by the MTA SDK. This diagnostic output may prove helpful when attempting to understand any MIME conversions that occur either when enqueuing messages to the MTA and the destination channel is configured to invoke MIME conversions (for example, marked with channel keywords such as thurman or inner), or when using the SDK message decoding routine, mtaDecodeMessage.()

MTA_DEBUG_DEQUEUE

None 

Enable diagnostic output from the low-level queue processing routines used by the MTA SDK. Use this diagnostic output when attempting to understand issues surrounding reading and processing of queued message files. This diagnostic output will not help diagnose the selection of queued messages as that is handled by a separate process: the MTA Job Controller. 

Enabling this diagnostic output is equivalent to setting DEQUEUE_DEBUG=1 in the MTA option file, option.dat.

MTA_DEBUG_ENQUEUE

None 

Enable diagnostic output from the low-level message enqueue routines used by the MTA SDK. Enqueue diagnostics can be used to diagnose the address rewriting process, destination channel selection, header processing, and other types of processing that occurs when a message is enqueued to the MTA. 

Enabling this diagnostic output is equivalent to setting MM_DEBUG=5 in the MTA option file.

MTA_DEBUG_MM

size_t level

Enable diagnostic output from the low-level message enqueue routines used by the MTA SDK. 

This item code must be followed by one additional call argument: the debug level to use. 

The debug level is an integer value in the range 0-20. Enqueue diagnostics may be used to diagnose the address rewriting process, destination channel selection, header processing, and other types of processing that occurs when a message is enqueued to the MTA.

Enabling this diagnostic output is equivalent to setting DEQUEUE_DEBUG=level in the MTA option file.

MTA_DEBUG_OS

None 

Enable diagnostic output from the low-level operating system dependent routines used by the MTA SDK. Use of this diagnostic output is helpful when diagnosing problems associated with creating, opening, writing, or reading files. Such problems typically arise when attempting to enqueue messages to the MTA, a process that requires permissions to create and write messages in the MTA queues. 

Enabling this diagnostic output is equivalent to setting OS_DEBUG=1 in the MTA option file.

MTA_DEBUG_SDK

None 

Enable diagnostic output for the MTA SDK. When this output is enabled, diagnostic information will be output whenever the SDK returns an error result. 

MTA_ITEM_LIST

mta_item_list_t *item_list

Specify a pointer to an item list array. The item list array must be terminated with a final array entry with an item code value of zero. For further information on item list usage, see Item Codes and Item Lists.

MTA_INTERACTIVE

None 

Indicate that the SDK will be used by an interactive program. In an interactive scenario, the SDK manages some of the MTA resources differently than when running as a channel program. For instance, closing the MTA log file after every completed message submission or dequeue operation. 

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_BADARGS

A required argument to an item code was NULL. 

MTA_FOPEN

Unable to initialize the MTA SDK. Unable to read one or more configuration files. Issue the following command for further information: 

imsimta test -rewrite

MTA_NO

Unable to initialize the MTA SDK. Issue the following command for further information: 

imsimta test -rewrite

MTA_NOSUCHITEM

An invalid item code was specified. 

Example

For normal use:

mtaInit(0);

To select SDK diagnostics:

mtaInit(MTA_DEBUG_SDK, 0);

mtaLog()

Write diagnostic output to the channel’s log file.

Syntax

void mtaLog(const char *fmt, ...);

Arguments

Arguments  

Description  

fmt

Pointer to a printf() formatting string. The string must be NULL terminated. See your platform’s C run-time library documentation for information on the formatting substitutions accepted by printf().

Description

Programs that wish to write diagnostic output should use mtaLog() and mtaLogv(). These two routines ensure that diagnostic output is directed to the same output stream as other diagnostic information generated by the MTA SDK. With one exception, consider a call to mtaLog() as being identical to calling the C run-time library routine printf(). The call arguments for the two routines are identical, including the formatting argument, fmt. The single exception is that, unlike printf(), a call to mtaLog() always produces a single line of output to the channel’s log file. Consequently, do not attempt to write either partial or multiple lines with a single call to mtaLog().

Do not include a terminating line feed or other record terminator in the output. That is, do not put a \n at the end of the formatting string.

A time stamp with a resolution of hundredths of a second prefaces each line of diagnostic output generated with mtaLog(). The time stamp uses the system clock and is reported in the local time zone.

Return Values

None

Example


char buf[64];

mtaLog("Version: %d.%d-%d",
       mtaVersionMajor(), mtaVersionMinor(),
       mtaVersionRevision());
mtaLog("Date/time: %s",
       mtaDateTime(buf, NULL, sizeof(buf), 0));
mtaLog("Postmaster address: %s",
       mtaPostmasterAddress(NULL, NULL));

The following output is generated by the preceding code example.


12:43:24.62: Version: 6.0-0
12:43:24.62: Date/time: Thu, 01 May 2003 12:43:24 -0700
12:43:24.63: Postmaster address: postman@mailhub.siroe.com

mtaLogv()

Write diagnostic output to the channel’s log file.

Syntax


void mtaLogv(const char *fmt
             va_list     ap);

Arguments

Arguments  

Description  

fmt

Pointer to a printf() formatting string. The string must be NULL terminated. See your platform’s C run-time library documentation for information on the formatting substitutions accepted by printf().

ap

A va_list structure as defined by the system stdarg.h header file.

Description

The mtaLogv() routine is provided for programs that either need to provide a diagnostic interface accepting a va_list() argument, or want to provide some generalization of mtaLog(). Use of mtaLogv() ensures that diagnostic output is directed to the same output stream as other diagnostic information generated by the MTA SDK.

With one exception, consider a call to mtaLogv() as being identical to calling the C run-time library routine vprintf(). The call arguments for the two routines are identical including the formatting argument, fmt. The single exception is that, unlike vprintf(), a call to mtaLogv() always produces a single line of output to the channel’s log file. Consequently, do not attempt to write either partial or multiple lines with a single call to mtaLogv().

Do not include a terminating line feed or other record terminator in the output. That is, do not put a \n at the end of the formatting string.

Return Values

None

Example

The following code fragment demonstrates a way to provide a generalization of mtaLog() using mtaLogv().


#include <stdarg.h>

void ourLog(our_context_t *ctx, const char *fmt, ...)
{
   char new_fmt[10240];
   va_list ap;

   /*
    * Genrate a new formatting string that includes as a prefix
    * the value of ctx-\>id then followed by the contents of the
    * supplied formatting string.
    */
   snprintf(new_fmt, sizeof(new_fmt),
            "id=%d; %s", ctx-\>id, fmt);
   va_start(ap, fmt);
   mtaLogv(new_fmt, ap);
   va_end(ap);
}

mtaOptionFinish()

Dispose of an option context.

Syntax

void mtaOptionFinish(mta_opt_t *opt_ctx);

Arguments

Arguments  

Description  

opt_ctx

An option context created by mtaOptionStart().

Description

Option contexts should be disposed of with a call to mtaOptionFinish(). The one exception to this rule are option contexts returned by mtaDecodeMessageInfoParams(). While those contexts may be passed to mtaOptionFinish(), they do not need to be because mtaDecodeMessage() will automatically dispose of them.

Return Values

None

Example

mtaOptionFinish(opt);

mtaOptionFloat()

Interpret and return an option’s value as a floating point number.

Syntax


int mtaOptionFloat(mta_opt_t  *opt_ctx,
                   const char *name,
                   size_t      len,
                   double     *val);

Arguments

Arguments  

Description  

opt_ctx

An option context created by mtaOptionStart(). A NULL value is permitted for this argument. When a NULL is passed, then no option value is returned.

name

Name of the option to obtain the value for. The length of this string should not exceed ALFA_SIZE bytes. This string must be NULL terminated if a value of zero is passed for len.

len

Length in bytes, not including any NULL terminator, of the option name supplied with name. If a value of zero is supplied, then the option name string must be NULL terminated. 

val

Pointer to a floating point of type double to receive the option’s value. If the option was not specified in the option file, then the value referenced by this pointer will be left unchanged. 

Description

Use mtaOptionFloat() to retrieve the value of an option, interpreting its value as a floating point number. If the option is specified in the option file and its value is a valid floating point number, then its value will be returned using the val call argument. If the option is not specified or its value does not correctly specify a floating point number, then no value is returned and the memory pointed at by val is left unchanged.

The mtaOptionFloat()routine can be called with a NULL value for the opt_ctx argument. When this is done, mtaOptionFloat() immediately returns with a status code of zero and no value is returned.

This routine does not provide an indication of whether or not the option was specified in the option file. If it is important to know whether or not the option was specified, then use mtaOptionString() to test to see if the option was specified.

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_STRTRUERR

The supplied option name is too long. Its length must not exceed ALFA_SIZE bytes.

Example

The following code example retrieves the value of an option named aspect_ratio. Before calling mtaOptionFloat(), a default value is set for the variable to receive the value of the option. If the option was not specified in the option file, then the variable will retain that default setting. If the option was specified, then the variable will assume the value set in the file.


ratio = 1.0;
mtaOptionFloat(opt, "aspect_ratio", 0, &ratio);

If it is important to know whether or not the option was specified, then use mtaOptionString() to test to see if the option was specified as shown in the following code example. In this example, when the routine returns, the code determines that the option was specified by whether or not the value of the buflen variable has changed.


char buf[1];
size_t buflen;

buflen = 0xffffffff;
mtaOptionString(opt, "aspect_ratio", 0, buf, &buflen,
                sizeof(buf));
ratio_specified = (buflen != 0xffffffff) ? 1 : 0;

mtaOptionInt()

Interpret and return an option’s value as an integer number.

Syntax


int mtaOptionInt(mta_opt_t  *opt_ctx,
                 const char *name,
                 size_t      len,
                 int        *val);

Arguments

Arguments  

Description  

opt_ctx

An option context created by mtaOptionStart(). A NULL value is permitted for this argument. When a NULL is passed, then no option value is returned.

name

Name of the option to obtain the value for. The length of this string should not exceed ALFA_SIZE bytes. This string must be NULL terminated if a value of zero is passed for len.

len

Length in bytes, not including any NULL terminator, of the option name supplied with name. If a value of zero is supplied, then the option name string must be NULL terminated. 

val

Pointer to an integer of type int to receive the option’s value. If the option was not specified in the option file, then the value referenced by this pointer will be left unchanged.

Description

Use mtaOptionInt() to retrieve the value of an option, interpreting its value as an integer-valued number. If the option is specified in the option file and its value is a valid integer, then its value will be returned using the val call argument. If the option is not specified or its value does not correctly specify an integer, then no value is returned and the memory pointed at by val is left unchanged.

The routine can be called with a NULL value for the opt_ctx argument. When this is done, mtaOptionInt() immediately returns with a status code of zero and no value is returned.

This routine does not provide an indication of whether or not the option was specified in the option file. If it is important to know whether or not the option was specified, then use mtaOptionString() to test to see if the option was specified as shown in the code example.

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_STRTRUERR

The supplied option name is too long. Its length must not exceed ALFA_SIZE bytes.

Example

In the following code example, the value of an option named max_blocks is retrieved. Before calling mtaOptionInt(), a default value is set for the variable to receive the value of the option. If the option was not specified in the option file, then the variable will retain that default setting. If the option was specified, then the variable will assume the value set in the file.


blocks = 1024;
mtaOptionInt(opt, "max_blocks", 0, &blocks);

The following code example illustrates how upon return from mtaOptionString(), the code determines that the option was specified by whether or not the value of the buflen variable has changed.


char buf[1];
size_t buflen;

buflen = 0xffffffff;
mtaOptionString(opt, "max_blocks", 0, buf, &buflen, sizeof(buf));
blocks_specified = (buflen != 0xffffffff) ? 1 : 0;

mtaOptionStart()

Open, parse, and load into memory an MTA option file.

Syntax


int mtaOptionStart(mta_opt_t **opt_ctx,
                   const char *path,
                   size_t      len,
                   int         item_code);

Arguments

Arguments  

Description  

opt_ctx

On successful return, a pointer to an option context created by mtaOptionStart(). This option context represents the options read from the option file.

path

Optional file path to the option file to read. If not specified, then the path specified by the PMDF_CHANNEL_OPTION environment variable will be used. If a value of zero is supplied for len, and there is a non-NULL value for path, the value must be NULL terminated. The length of the file path, not including any NULL terminator, may not exceed ALFA_SIZE bytes.

len

Length in bytes, not including any NULL terminator, of the file path. This argument is ignored when a NULL is passed for path. When path is non-NULL and a value of zero is supplied for len, then the file path string must be NULL terminated.

item_code

Reserved for future use. A value of zero must be supplied for this call argument. 

Description

MTA option files such as channel option files may be read, parsed, and loaded into memory with mtaOptionStart(). Once loaded into memory, the values of individual options may be retrieved with the routines shown in the table that follows:

Routine Names  

Description  

mtaOptionFloat()

Retrieve the value of a floating point valued option. 

mtaOptionInt()

Retrieve the value of an integer valued option. 

mtaOptionString()

Retrieve the string representation of an options value. 

These routines are designed such that if the requested option does not exist, then no value is returned. This allows code to assign to a variable an option’s default value, then attempt to retrieve an explicitly set value from the option file. During the retrieval, the address of the variable can be passed. If the option is specified in the option file, then the value of the variable will be replaced with the value from the option file. If the option is not specified, then the default value stored in the variable is left unchanged. Code examples of such usage are provided in the individual routine descriptions.

Once finished obtaining the values of any options, unload the options from memory and dispose of the option context with mtaOptionFinish().

When the underlying option file does not exist, mtaOptionStart() still returns a success status code. However, a NULL value is returned for the pointer to the option context. The other option routines accept a NULL value for an option context pointer and will behave as though the requested option is not specified in the option file. This behavior reflects the fact that MTA option files are considered optional. If a channel’s option file does not exist, then the channel is supposed to use its default settings for its options. This also simplifies coding, allowing programs not to have to worry about whether or not the option file exists and whether or not the option context pointer is NULL. If, however, the existence of an option file is mandatory, then a program can detect that the file does not exist by seeing if the returned value for the option context pointer is NULL as shown in the code example section that follows.

If an explicit option file path is specified with the path call argument, then the path can be a relative file path or an absolute file path. File paths can be prefixed with any of the symbolic MTA directory names specified in the imta_tailor file. For example, the entry shown in the following code fragment specifies a file named mmsc_gateway.cnf located in the nmsc subdirectory of the MTA configuration directory. Note that a colon separates the symbolic name from the remainder of the path.

IMTA_TABLE:/mmsc/mmsc_gateway.cnf

If no file path is specified, then the file specified with the PMDF_CHANNEL_OPTION environment variable will be opened and read. That environment variable is established by the Job Controller for the channel programs that it runs. It will always have the following format:

IMTA_TABLE:channel-name_option

where channel-name is the name of the channel being run. The following example demonstrates how the environment variable settings are effected for tcp_local channel:


PMDF_CHANNEL=tcp_local
PMDF_CHANNEL_OPTION=IMTA_TABLE:tcp_local_option

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_BADARGS

A NULL value was supplied for the opt_ctx call argument.

MTA_FOPEN

Unable to open the option file. File access permissions are the likely cause for this error. 

MTA_NO

An error occurred while reading or parsing the option file. 

MTA_NOMEM

Insufficient virtual memory. 

MTA_STRTRUERR

The supplied file path is too long. Its length must not exceed ALFA_SIZE bytes.

Example


opt_ctx = NULL;
if (mtaOptionStart(&opt_ctx, NULL, 0, 0))
    /*
     * Error loading the option file
     */
else if (!opt_ctx)
    /*
     * Option file did not exist
     */

mtaOptionString()

Return an option’s value as a string.

Syntax


int mtaOptionString(mta_opt_t  *opt_ctx,
                    const char *name,
                    size_t      len,
                    const char *str,
                    size_t     *str_len,
                    size_t      str_len_max);

Arguments

Arguments  

Description  

opt_ctx

An option context created by mtaOptionStart(). A NULL value is permitted for this argument. When a NULL is passed, then no option value is returned.

name

Name of the option to obtain the value for. The length of this string should not exceed ALFA_SIZE bytes. This string must be NULL terminated if a value of zero is passed for len.

len

Length in bytes, not including any NULL terminator, of the option name supplied with name. If a value of zero is supplied, then the option name string must be NULL terminated. 

str

A pointer to a buffer to receive the NULL terminated value of the specified option. The MTA allows channel options to have a maximum length of BIGALFA_SIZE bytes. As a result, this buffer should in general have a length of at least BIGALFA_SIZE+1 bytes. If the option was not specified in the option file, then the contents of the buffer is left untouched.

str_len

An optional pointer to a size_t to receive the length in bytes of the returned option value string, str. A value of NULL may be passed for this call argument.

str_len_max

The maximum size in bytes of the buffer pointed at by str.

Description

Use mtaOptionString() to retrieve the string representation of an option’s value. If the option is specified in the option file, then its value and length will be returned via the str and str_len call arguments. If the option is not specified then no value is returned and the memory pointed at by str and str_len are left unchanged. This routine can be called with a NULL value for the opt_ctx argument. When this is done, mtaOptionString() immediately returns with a status code of zero and no option value is returned.

Return Values

Return Values  

Description  

0

Normal, successful completion. 

MTA_STRTRU

Supplied buffer pointed at by buf is too small. The returned value has been truncated to fit. Truncated value is NULL terminated. The buffer should have a length of at least BIGALFA_SIZE+1 bytes.

MTA_STRTRUERR

The supplied option name is too long. Its length must not exceed ALFA_SIZE bytes.

Example

In the code example that follows, the value of an option named mail_url is retrieved. Before calling mtaOptionString(), a default value is set for the variable to receive the value of the option. If the option was not specified, then the variable will retain that default setting. If the option was specified, then the variable will assume the value set by that specification.


char url[1024];

strcpy(url, "mail_to:webmaster@siroe.com");
mtaOptionString(opt, "mail_url", 0, url, NULL, sizeof(url));

mtaPostmasterAddress()

Obtain the MTA local postmaster address.

Syntax


const char *mtaPostmasterAddress(const char **address,
                                 size_t      *len,
                                 int          item code, ...)

Arguments

Arguments  

Description  

address

Optional pointer to receive the memory address of the string buffer containing the MTA local postmaster address. The string will be NULL terminated. A value of NULL may be passed for this argument. 

len

Optional address of a size_t to receive the length in bytes of the postmaster address. A value of NULL may be passed for this argument.

item code

Reserved for future use. A value of zero (0) must be passed for this argument.

Description

This routine returns a pointer to a NULL terminated string containing the MTA local postmaster address. This address is suitable, for instance, for inclusion in the From: header line of notification messages as shown in the code example for this routine.

It is usually not a good idea for programs to send mail to the postmaster’s address. In many situations, sending mail to the postmaster when failures occur can lead to mail loops if the mail sent to the postmaster itself fails, and generates a message to the postmaster, which then fails, and generates yet another message to the postmaster, and so on.

On a successful completion, the address of the string buffer containing the postmaster’s address is returned using the address call argument. That same address is also returned as the return status.

Return Values

In the event of an error, a value of NULL is returned as the status and mta_errno is set with a status code indicating the underlying error.

Error Status Codes  

Description  

MTA_FOPEN

Unable to initialize the MTA SDK. Unable to read one or more configuration files. For further information, issue the following command: 

imsimta test -rewrite

MTA_NO

Unable to initialize the MTA SDK. For further information, issue the following command: 

imsimta test -rewrite

Example

The following example shows how to use this routine to include the postmaster address in the From: header line of a notification message:


mtaEnqueueWriteLine(nq, "From: Postmaster <", 0,
                    mtaPostmasterAddress(NULL, NULL, 0), 0,
                    "\>", 0, NULL);

mtaStackSize()

Obtain the minimum thread stack size required when using the MTA SDK.

Syntax

size_t mtaStackSize(void);

Arguments

None

Description

A number of the run-time libraries used by the MTA SDK make intensive use of stack variables. As a result, some MTA SDK operations can require a larger than usual thread stack size. The minimum thread stack size required for typical MTA SDK operations, such as message dequeue and enqueue operations, can be obtained with mtaStackSize(). When writing multi-threaded code, ensure that any threads that will be calling SDK routines have a stack size at least as large as the value returned by mtaStackSize(). Failure to do may result in abnormal process terminations when a thread overruns its stack.

Return Values

The minimum thread stack size required for MTA SDK operations.

Example

None

mtaStrError()

Obtain a text description of an error status code.

Syntax


const char *mtaStrError(int code,
                        int item_code);

Arguments

Arguments  

Description  

code

The MTA SDK error status to obtain a text description for. 

item_code

Reserved for future use. A value of zero must be supplied for this call argument. 

Description

Use mtaStrError() to obtain English language descriptions of MTA SDK error codes. These descriptions are intended solely for use in fine-grained diagnostic output. They are not intended for reading by end users of programs written using the MTA SDK.

Return Values

A pointer to a NULL terminated string containing the error code description.

Example


ires = mtaEnqueueStart(&nq, from, 0, 0);
if (ires)
    printf("mtaEnqueueStart() returned %d; %s\n",
           ires, mtaStrError(ires, 0));

mtaUniqueString()

Generate a system-wide unique string.

Syntax


const char *mtaUniqueString(char   *buf,
                            size_t *len,
                            size_t  max_len);

Arguments

Arguments  

Description  

buf

A pointer to a buffer to receive the NULL terminated unique string. The buffer should be at least 20 bytes long. 

len

An optional pointer to a size_t to receive the length in bytes of the returned unique string. This length does not include the NULL terminator that terminates the returned unique string. A value of NULL can be passed for this call argument.

len_max

The maximum size in bytes of the buffer pointed at by buf.

Description

The mtaUniqueString() routine may be used to generate a system-wide unique string. The strings generated are suitable for use as MIME boundary markers and file names. On a successful completion, the unique string is stored in the buffer pointed at by the buf argument. Additionally, the value of the buf argument is returned as the routines return status.

Return Values

In the event of an error, mtaUniqueString() will return NULL. The error status code may be obtained by examining the value of mta_errno.

Error Status Codes  

Description  

MTA_BADARGS

A value of NULL was supplied for the buf argument.

MTA_STRTRUERR

The buf buffer is too small.

Example

This routine is used in Example 5–2.

mtaVersionMajor()

Obtain the major version number associated with the MTA SDK library.

Syntax

int mtaVersionMajor(void);

Arguments

None

Description

Return the major version number associated with the MTA SDK library.

Return Values

The SDK major version number.

Example


printf("MTA SDK Version %d.%d-%d\n"
       mtaVersionMajor(), mtaVersionMinor(),
       mtaVersionRevision())

mtaVersionMinor()

Obtain the minor version number associated with the MTA SDK library.

Syntax

int mtaVersionMinor(void);

Arguments

None

Description

Return the minor version number associated with the MTA SDK library.

Return Values

The SDK minor version number.

Example


printf("MTA SDK Version %d.%d-%d\n"
       mtaVersionMajor(), mtaVersionMinor(),
       mtaVersionRevision());

mtaVersionRevision()

Obtain the revision level associated with the MTA SDK library.

Syntax

int mtaVersionRevision(void);

Arguments

None

Description

Return the revision level associated with the MTA SDK library.

Return Values

The SDK revision level.

Example


printf("MTA SDK Version %d.%d-%d\n"
mtaVersionMajor(), mtaVersionMinor(), mtaVersionRevision());