Using the Messaging Server Plug-in API
[Contents] [Previous] [Next] [Index]

Chapter 2
Using the Messaging Server Plug-in API


This chapter provides basic information about the elements and functions of the Messaging Server Plug-in API.

This chapter introduces the functions and result codes of the plug-in (external) code and discusses the functions provided by Messaging Server to manipulate its fundamental data structures. It concludes with platform-specific information for generating the shared object.

This chapter includes the following sections:


Plug-in Entry Points

With the Messaging Server Plug-in API, you can plug in additional functionality at the following stages in message processing:

Use this format to specify plug-in functionality in the plug-in configuration file:

Stage Shared Object funcs=comma-separated list of functions [name=value,...]

Stage
One of the stages in message processing, either:

Shared Object
Dynamically loadable code that implements the additional functionality.

funcs
Comma-separated list of functions that implement the additional functionality.

name=value
Arbitrary name-value pairs that are passed to the function to implement additional functionality.

This format has the following parameters:

For example, a plug-in configuration file could contain lines like these:

PostSmtpAccept /foo/bar/libxlate.so funcs=decode-euc 
PostSmtpDelivery /foo/bar/libxlate.so funcs=encode-iso no-xlate-domains="*.kr"
[Top]


Plug-in Function Format and Result Codes

Plug-in functions have this format:

int function (pblock *Config,
               Message **InMessage,
               Message ***OutMessage);
The Config parameter represents a hash table organization of name-value pairs. The hash table contains all the optional parameters on the configuration command line in name=value format. For example, the no-xlate-domains parameter in the example in "Plug-in Entry Points" is passed in the parameter block Config.

The InMessage parameter is an input-only parameter that 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 that of 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:

You can use Messaging Server functions to allocate and manipulate Message structures. If you split the message, do so immediately after it is received by the Messaging Server, at the PostSmtpAccept stage. If the plug-in code does not split the input message into multiple messages (for example, if it encodes the message for all the recipients) the OutMessage output parameter is not necessary.

For more information about stages in message processing, see "Messages and Message Processing Steps." For information about the Message structure, see "Data Structures."

The plug-in code should return one of these codes to the Messaging Server:

[Top]


Data Structures

Message Server Plug-in functions use two fundamental data structures, the pblock parameter block and the Message structure. To help you use these structures, this section provides a general description of their characteristics and contents.

WARNING: The type definitions in this section are for informational purposes only. They do not reproduce the actual definitions of the structures. All types mentioned in this guide are opaque, and members of the type defined structures are not exposed in the header files. The only access to the members is through the Messaging Server API. §
[Top]


Parameter Block

The first fundamental data structure in the server code is the parameter block, pblock. The parameter block is a hash table keyed on the name string, which maps the name strings to their value character strings. A parameter block could be constructed as in this example:

typedef struct { 
   char *name, *value; }
   pb_param;
struct { 
   pb_param *param;
   struct pb_entry *next; };
   pb_entry;
typedef struct { 
   int hsize;
   struct pb_entry **ht; }
   pblock;
In this example, the pb_param structure is used to manage name-value pairs, and pb_entry is a structure used to create linked lists of pb_param structures.

The parameter block in the example, pblock, is the hash table that holds pb_entry structures. Its contents are transparent to most code. The hash function is subject to change and is not made known to application functions.

To access this structure, use the pblock_findval function.

WARNING: This type definition is for informational purposes only. It does not reproduce the actual definition of the structure. §
[Top]


Message Structure

The Message structure stores all attributes that define a single message. This includes 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 could be constructed as in this example:

typedef char *N821Address; 
typedef char *SmtpExt;
typedef struct { long magic; /* definition of Address structure */
   N821Address Addr;
   SmtpExt Ext;
   int flags;
} Address;      
typedef struct addr_list { 
   long magic;
   void *context;
   Address Addr;
   struct addr_list *pNext;
} AddressList;
typedef AddressList RecipientList;
typedef Address Recipient; /* Definition of Recipient type */
typedef Address Sender;
typedef struct { 
   long magic;
   char *ControlFileName;
   char *BodyFileName;
   char *HeaderFileName;
   RecipientList *recipList; /* List of recipients */
   Sender *sender; /* Envelope sender */
   char *stage; /* Stage in processing */
   int flags;
   void *context; /* Internal context for */
                  /* operations, such as getNext routines */
} Message;
The Message structure represents the message itself. The other type used in the functions in this API is the Recipient structure, defined as a type of Address.

To set or access this structure, use the functions associated with the Message type.

WARNING: This type definition is for informational purposes only. It does not reproduce the actual definition of the structure. §
[Top]


Using Messaging Server Plug-in Functions

Messaging Server functions operate either on the pblock structure or the Message structure.

This list summarizes the operations the Messaging Server API can perform. Each item links to a further explanation that includes the function you need to perform it.

These examples demonstrate the operations above in more detail.

Find a Messaging Server entry
The pblock_findval function searches the hash table (pblock parameter) for the entry with the given name and returns its value or null. It is the only function that operates on the parameter block.

char *pblock_findval(char *name, pblock *pb);
Duplicate the message
To duplicate an existing Message structure, use DupMessage.

Message *DupMessage (Message *pMessage);
This function creates a new instance of the message in the Mail Server. Mail Server automatically allocates header and body files for the new message and copies the contents of the header and body files of the original message. The function returns null if memory failures occur or if the message is not valid.

Free the message
The FreeMessage function frees the resources associated with the message.

void FreeMessage (Message *pMessage);
Get message recipients
To access the recipient list of the input message, use the GetFirstRecipient and GetNextRecipient functions.

Recipient *GetFirstRecipient (Message *pMessage); 
Recipient *GetNextRecipient (Message *pMessage);
Add and remove recipients
To add or delete recipients on the recipient list, use the 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.
Get the recipient's address
To get the RFC-821 address of the recipient, for example, foo@somewhere.org, use GetRecipientAddress.

char *GetRecipientAddress (Recipient *pRecipient);
Get header and body files
To find, open, and rewrite or encode the header and body files of the message, use the GetHeaderFile and GetBodyFile functions.

char *GetHeaderFile (Message *pMessage); 
char *GetBodyFile (Message *pMessage);
These functions return the full path name to the files that contain the RFC-822 header and RFC-822 body portions of the message, respectively. GetHeaderFile and GetBodyFile are always successful if the message is valid.

[Top] [Data Structures]


Generating the Shared Object

The following ld lines are examples of generating the shared object. In these examples, the source code file implementing the plug-in functionality is plugin.c, and the object file is plugin.o.

Unix

Solaris
For gcc version 2.6.3:

gcc -Wal -fpic -o plugin.o -c plugin.c 
# ld -G -o plugin.so plugin.o
HP-UX 9.05
Ensure that libNSmail.sl is present in the default search path of ld.

For native compiler:

cc +z -Aa -o plugin.o -c plugin.c 
# ld -b -o plugin.sl -lNSmail plugin.o

Windows NT

cl -DWIN32 -D_WINDOWS plugin.c /link /dll /out:plugin.dll NetscapeMTAX30.lib
If NetscapeMTAX.lib is not in the current directory, the complete path must be specified.

[Top]


[Contents] [Previous] [Next] [Index]

Last Updated: 10/01/97 15:03:48


Copyright © 1997 Netscape Communications Corporation