e534a4eed1fd838764b807d04a214c2818313656
[exim.git] / src / src / miscmods / README
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 Copyright (c) The Exim Maintainers 2024
6
7 This directory contains source for modules that can be built as part
8 of Exim, either static-linked or as dynamic-load modules. Doing the
9 latter keeps the runtime binary smaller when a feature is not used
10 by the configuration, especially when a library is involved.
11
12 Which modules are built, and the choice of static vs. dynamic, is
13 under the control of the Local/Makefile at build time.
14 Any combination of static/dynamic is valid.
15
16 Moudules built for dynamic load must be installed in a directory
17 which is defined in Local/Makefile.
18
19 The API starts with a struct with a known name <foo>_module_info.
20 For dynamic builds this includes a magic number permitting versioning
21 of the highlevel interface.
22 The structure has elements for some commonly-needed call types
23 (init, version-report etc.).  Any my be left as null pointers;
24 those present will be called at appropriate times.
25
26 The current list is
27         init
28         lib_vers_report
29         smtp_reset
30         msg_init
31
32 Then there are three pair of elements, each being a table pointer
33 and table length, for options, functions, and variable that the
34 module provides.
35
36 The options table defines main-section configuration options, using
37 the same definition entry struct as the main table in readconf.c;
38 entries here should have their proper opt_<type> and
39 should be duplicated in the main table, but with opt_module and the
40 module name (this supports both getting the module loaded, if dynamic,
41 and writing the value from the config). Entries must be in order by
42 the option name.
43
44 The functions table defines service functions additional to the "common"
45 ones noted above.  Each offset in the table should have a #define in an
46 include-file brought in to the general set by exim.h.
47
48 The variables table defins $variables for expansion, using the same
49 definition entry struct as the main var_table in expand.c;
50 entries here should have their proper vtype_<type> and should be duplicated
51 in the main table but with vtype_module and the module name.
52
53 There are service functions to locate and to locate-or-load modules
54 by name; these hide the static/dynamic aspect of a module.  Most
55 new coding will only need these for calls to the "additiona" custom
56 functions a module provides. The example code is:
57
58       {
59       /* You need to know the function's prototype */
60       typedef int (*fn_t)(const uschar **, const uschar *, int);
61       fn_t fn;
62       misc_module_info * mi = misc_mod_find(US"spf", &log_message);
63
64       if (mi)
65         {
66         fn = ((fn_t *) mi->functions)[SPF_PROCESS];
67         rc = fn(args...);
68         }
69       }
70
71
72
73 Adding new modules
74 ------------------
75
76 Put the code in this directory.  Use filenames starting with the module name.
77 Write an include file with anything callers need to know, in particular
78 #defines for the function call numbers.  Include that file from exim.h
79 and add it to HDRS and PHDRS in OS/Makefile-Base.
80 Add a SUPPORT_<foo> line to Local/Makefile, and (if dynamic) any
81 SUPPORT_<foo>_INCLUDE or SUPPORT_<foo>_LIBS required.
82 Add the capitalised module name <foo> to the "miscmods" like in
83 scripts/Configure-Makefile.
84 Add all the filenames to the "miscmods" list in scripts/Makelinks