pInitFunc function prototype. Called once at MTA startup, the function initializes local server data, loads configuration information off the disk, declares global variables, and returns an integer that indicates whether the initialization succeeded. The plug-in function is relieved of this task, so a boost to performance results.
typedef int (*pInitFunc)(pblock *Config);The
Config parameter represents configuration data that is relevant to plug-in operation. It points to the name:value pairs that contain all the optional parameters on the configuration command line. For example, the no-xlate-domains parameter in the example in "How Messaging Server Plug-ins Work" is passed in the parameter block Config.
In your server plug-in function, you can access and modify data in the config pblock structure.
If you need to construct global variables in the plug-in, you can do that in this function. Keep in mind that if you do, and if these variables are changed when the plug-in is called with incoming or outgoing messages, you must synchronize access to them.
For example, this simple version of the initialization function only returns whether or not the function completed.
SAMPLE_EXPORT int SamplePluginInit(pblock *Config){
return 1;
}
To see how the initialization function is used in a sample plug-in DLL, see Chapter 4, "Messaging Server Sample Plug-in." For information about stages in message processing, see "How Messaging Server Plug-ins Work."
[Top] [Writing the Initialization and Plug-in Functions]
pFunc function prototype:
typedef int (*pFunc) (pblock *Config,The
struct Message **InMessage,
struct Message ***OutMessage);
Config parameter represents configuration data that is relevant to plug-in operation. It points to the name:value pairs that contain all the optional parameters on the configuration command line. For example, the no-xlate-domains parameter in the example in "How Messaging Server Plug-ins Work" is passed in the parameter block Config.
In your server plug-in function, you can access and modify data in the config pblock structure.
The input-only InMessage parameter represents a pointer to an array of pointers to structures of type Message, terminated by a null pointer. Every pointer to the Message structure represents a separate message. The simplest, and perhaps the most common, case is to place only one pointer in this array.
The OutMessage parameter represents the result of the execution of the site-specific plug-in code. This parameter is required only if the plug-in code generates more than one message from a single input message. The plug-in code should return null in the OutMessage parameter in these cases:
PostSmtpAccept stage. If the plug-in code does not split the input message (for example, if it encodes the message for all the recipients), the OutMessage output parameter is not necessary.
For return values for this function, see "Plug-in Return Codes."
To see how the plug-in function is used in a sample plug-in DLL, see Chapter 4, "Messaging Server Sample Plug-in." For information about stages in message processing, see "How Messaging Server Plug-ins Work." For information about the Message structure itself, see "The Message Structure."
[Top] [Writing the Initialization and Plug-in Functions]
MSG_CONTINUE. The plug-in succeeded. The resulting messages should go on to Messaging Server for further processing. This result is possible from any stage in Messaging Server operation.MSG_NOACTION. The plug-in did not do anything. Proceed with further message processing.pblock parameter block and the Message structure. Many of the functions reference a message Recipient and RecipientList, whose definitions are based on the Address and AddressList structures, respectively.
WARNING: The type definitions are described in this section for informational purposes only. Although your plug-in should be able to reference the members of these structures, it should make all changes through the API, to accommodate future API changes. §[Top]
pblock, or parameter block structure, containing server configuration information to the function.
The pblock structure is an array of name:value pairs in a linked list that you can use to set and retrieve control information for a message. Your server plug-in can access and modify data in this parameter block. If you are writing a function that is invoked before the message is handed off to another host immediately after the message is received, at the PostSmtpAccept entry point, you can also stop the message from being sent.
The parameter block is made of name:value pairs keyed on the name string, which maps each name to its value character string.
The pblock structure has this syntax:
typedef struct p_block {
char *name;
char *value;
struct p_block *next;
} pblock;
The name parameter points to the name portion of the name:value pair, while the value parameter points to the value portion. The next parameter points to the next entry in the linked list of parameter blocks.
To access this structure, use the pblock_findval function.
The functions in Table 2.1 operate on the pblock structure:
Table 2.1 Functions for manipulating the pblock structure
| To do this: |
Call this function:
|
| Pass the configuration when the plug-in function is called at MTA startup.
|
| |
WARNING: This type definition is for informational purposes only. Although your plug-in should be able to reference the members of these structures, it should make all changes through the API, to accommodate future API changes. §[Top] [Using Messaging Server Plug-in Data Structures]
Message structure stores all attributes that define a single message. This includes control or envelope information, such as envelope sender and recipients, sender and per-recipient extensions, and so on, as well as RFC 822 attributes such as pointers to RFC 822 headers and RFC 822 body.
The Message structure has this syntax:
typedef struct message {
long magic;
char *BaseMsgName;
char *MsgFileName;
RecipientList *recipList;
Sender *sender;
const char *stage;
int flags;
void *context;
void *control;
} Message; magic parameter represents a magic cookie for the message and must have a particular value, 0xdeadbeef. For information about using the magic value, see "Add and remove recipients."BaseMsgName parameter is a pointer to the base message file name, not including the file path. MsgFileName parameter is a pointer to the message file name, including the file path. recipList and AddressList parameter definitions are based on other structures and type definitions of the API. recipList parameter points to the list of addresses of message recipients. It is defined as a RecipientList structure, which is of type AddressList. See "The Message RecipientList and the AddressList Structure."Sender parameter points to the sender of the message and is of type Address. See "The Message Recipient and the Address Structure."stage parameter represents a pointer to the stage in message processing at which the plug-in should be called. It can be PostSmtpAccept (immediately after the message is received off the wire), or PreSmtpDelivery (just before the message is handed off to another host).flags parameter is a flag for the message.context parameter represents a pointer to the internal context for things like getNext routines.control parameter represents a pointer to the ControlFile, which is accessible through the Plug-in API. Message structure or on the Recipient in the Message structure, you can call the functions in Table 2.2:
Table 2.2 Functions for manipulating the Message structure
| To do this: |
Call this function:
|
|
|
|
| Get the filename and path to the message file that includes both the header and body.
| |
WARNING: This type definition is for informational purposes only. Although your plug-in should be able to reference the members of this structure, it should make all changes through the API, to accommodate future API changes. §[Top] [Using Messaging Server Plug-in Data Structures]
Recipient parameter, and the RecipientList, represented by the RecipientList parameter. These parameters are defined as types of the Address and AddressList structures, respectively.
Recipient parameter. The definition of the recipient is based on the Address structure.
The Address structure has this syntax:
typedef char *N821Address;
typedef char *SmtpExt;
typedef struct address {
long magic;
N821Address Addr821;
SmtpExt Ext;
int flags;
} Address;
The definitions of the Recipient and Sender parameters of the Message structure are based on the Address structure.
The functions in Table 2.3 allow access to the recipient list encapsulated in the Message structure:
Table 2.3 Functions for manipulating the Recipient
| To do this: |
Call this function:
|
|
|
| Remove a recipient from the recipient list of a message header.
| |
RecipientList parameter. The definition of the RecipientList is based on the AddressList structure.
The AddressList structure has this syntax:
typedef struct addr_list {
long magic;
void *context;
Address Addr;
struct addr_list *pNext;
} AddressList;
The RecipientList definition occurs in the API only as a parameter of the Message structure. You have access to RecipientList only through functions that access the Message structure.
typedef AddressList RecipientList;[Using Messaging Server Plug-in Data Structures] [The Message Structure]
pblock_findval function searches the parameter block for the name:value pair with the name given in the name parameter and returns its value or null.
char *pblock_findval(char *name, pblock *pb);The parameter block, a
pblock structure, contains the configuration information for the plug-in.
Message structure, use DupMessage.
Message *DupMessage (Message *pMessage);This function creates a new instance of the message in Messaging Server. Messaging Server automatically allocates a message file for the new message and copies the contents of the header and body of the original message. The function returns
null if memory failures occur or if the message is not valid.
FreeMessage function frees the resources associated with the message.
void FreeMessage (Message *pMessage);
GetFirstRecipient and GetNextRecipient functions.
GetFirstRecipient gets a pointer to the first recipient in the message.
Recipient *GetFirstRecipient (Message *pMessage);
GetNextRecipient gets the second, third, and all subsequent recipients.
Recipient *GetNextRecipient (Message *pMessage);
AddRecipient or RemoveRecipient function.
int AddRecipient (Message *pMessage,
Recipient *pRecipient);
int RemoveRecipient (Message *pMessage,
Recipient *pRecipient);
AddRecipient succeeds if both input parameters are valid and no memory errors occur. RemoveRecipient always succeeds.
This example shows how you can use AddRecipient. First, define the new recipient with any required flags or extension.
new_rcpt.Addr821 = (char*)malloc (strlen ("<testuser@test.com>") + 1);
strcpy(new_rcpt.Addr821, "<testuser@test.com>");
new_rcpt.Ext = NULL; /* Extension is null */
new_rcpt.flags = 0; /* No flags used in this example */
Set this required magic value:
new_rcpt.magic = 0xdeadbeef; /* Use only this magic value */Make the
AddRecipient call. Add the free command to free the recipient when it is finished.
AddRecipient(ppInMsg[0],&new_rcpt); /* Add the new recipient */To see this sequence as part of a sample plug-in DLL, see Chapter 4, "Messaging Server Sample Plug-in."
free (new_rcpt.Addr821);
foo@somewhere.org, use GetRecipientAddress.
char *GetRecipientAddress (Recipient *pRecipient);
GetMessageFile function.
char *GetMessageFile (Message *pMessage);This function returns the full path to the files that contain the RFC 822 header and body portions of the message. It always succeeds if the message is valid.
NOTE: This function is new in Messaging Server Plug-in API 4.0. It combines the functionality of two 3.0 functions. For more information, see Appendix A, "Converting Messaging Server Plug-in 3.0 Files." §[Top] [Using Messaging Server Plug-in Functions]
NOTE: These functions are new in Messaging Server Plug-in API 4.0. §[Top]
GetControlData function.
char *GetControlData (Message *pMessage);This function returns the control data in the form of a character string that contains the full path name to the control data for the message. The character string contains name:value pairs with the elements separated by LFs. If you change recipients using any if the API functions, this will change the values of the control data that this function retrieves. For this reason, the plug-in should not rely on this information to be up to date.
NOTE: This function is new in Messaging Server Plug-in API 4.0. §[Top] [Accessing Control Data]
GetControlData and reviewing the character string returned by it, you must free the control data with the FreeControlData function.
void FreeControlData(char *controldata);
NOTE: This function is new in Messaging Server Plug-in API 4.0. §[Top] [Accessing Control Data]
int AddControlInfo(Message *pMessage,Supply the name portion of the pair in the key parameter and the value portion of the pair in the data parameter. You can delete the original message after adding control data by entering 1 or 0 in the
const char *key,
const char *data,
int delete_original);
delete_original parameter. This function returns an integer that indicates whether the add operation succeeded. All changes are reflected in any future call to GetControlData.
NOTE: This function is new in Messaging Server Plug-in API 4.0. §[Top] [Accessing Control Data]
name portion in the key parameter.
int RemoveControlInfo(Message *pMessage, char *key);This function returns an integer that indicates whether the remove operation succeeded. All changes are reflected in any future call to
GetControlData.
NOTE: This function is new in Messaging Server Plug-in API 4.0. §[Top] [Accessing Control Data]
Last Updated: 11/19/98 10:35:16
[an error occurred while processing this directive]