Next: Interface Module, Up: mfmod [Contents][Index]
External functions in the loadable library must be declared as
int funcname(long count, MFMOD_PARAM *param, MFMOD_PARAM *retval);
The MFMOD_PARAM
type is declared in the header file
mailfromd/mfmod.h, which must be included at the start of the
source code.
This type is defined as follows:
typedef struct mfmod_param { mfmod_data_type type; union { char *string; long number; mu_message_t message; }; } MFMOD_PARAM;
The type
fields defines the type of the data represented by the
object. Its possible values are:
String data.
Numeric data.
A mailutils
message object (mu_message_t
).
The actual data are accessed as string
, number
, or
message
, depending on the value of type
.
The first parameter in the external function declaration, count,
is the number of arguments passed to that function. Actual arguments are
passed in the MFMOD_PARAM
array param. The function should
never modify its elements. If the function returns a value to MFL, it
must pass it in the retval parameter. For example, the
following code returns the numeric value ‘1’:
retval->type = mfmod_number; retval->number = 1;
To return a string value, allocate it using malloc
,
calloc
or a similar function, like this:
retval->type = mfmod_string; retval->string = strdup("text");
If a message is returned, it should be created using mailutils message
creation primitives. Mailutils
will call
mu_message_destroy
on it, when it is no longer used.
The return value (in the C sense) of the function is used to determine
whether it succeeded or not. Zero means success. Returning -1 causes
a runtime exception e_failure
with a generic error text
indicating the names of the module and function that caused the
exception. Any other non-zero value is treated as a
mailfromd
exception code (see Exceptions). In this case
an additional textual explanation of the error can be supplied in the
retval
variable, whose type must then be set to mfmod_string
.
This explanation string must be allocated using malloc
.
To facilitate error handling, the following functions are provided (declared in the mailfromd/mfmod.h header file):
Raises exception ecode with the error message formatted from the
variadic arguments using printf
-style format string fmt.
Example use:
if (error_condition) return mfmod_error(retval, "error %s occurred", error_text);
Reports argument type mismatch error (e_inval
with
appropriately formatted error text). Arguments are:
The two arguments passed to the interface function.
0-based index of the erroneous argument in param.
Expected data type of param[n]
.
You will seldom need to use this function directly. Instead, use the
ASSERT_ARGTYPE
macro described below.
Returns the MFL name of the mfmod data type type.
The following convenience macros are provided for checking the number of argument and their types and returning error if necessary:
Assert that the number of arguments (count) equals the expected
number (expcount). If it does not, return the e_inval
exception with a descriptive error text.
retval and count are corresponding arguments from the calling function.
Check if the data type of the nth parameter
(i.e. param[n]
) is exptype and return the
e_inval
exception if it does not.
As an example, suppose you want to write an interface to the system
crypt
function. The loadable library source,
mfmod_crypt.c, will look as follows:
#include <stdlib.h> #include <unistd.h> #include <string.h> #include <mailfromd/mfmod.h> #include <mailfromd/exceptions.h> /* * Arguments: * param[0] - key string to hash. * param[1] - salt value. */ int cryptval(long count, MFMOD_PARAM *param, MFMOD_PARAM *retval) { char *hash; /* Check if input arguments are correct: */ ASSERT_ARGCOUNT(retval, count, 2); ASSERT_ARGTYPE(param, retval, 0, mfmod_string); ASSERT_ARGTYPE(param, retval, 1, mfmod_string); /* Hash the key string. */ hash = crypt(param[0].string, param[1].string); /* Return string to MFL */ retval->type = mfmod_string; retval->string = strdup(hash); /* Throw exception if out of memory */ if (retval->string == NULL) return -1; return 0; }
The exact way of building a loadable library from this source file depends on the operating system. For example, on GNU/Linux you would do:
cc -shared -fPIC -DPIC -omfmod_crypt.so -lcrypt mfmod_crypt.c
The preferred and portable way of doing so is via libtool
(see Shared library support for GNU in Libtool).
Mailfromd
provides a special command mfmodnew
that
creates infrastructure necessary for building loadable modules.
See mfmodnew.
Next: Interface Module, Up: mfmod [Contents][Index]