Plugins¶
Plugins in Dovecot are really simple. They basically have two functions:
<plugin_name>_init(module)
is called whenmodule_dir_init()
is called.<plugin_name>_deinit() is called when
module_dir_deinit()
ormodule_dir_unload()
is called.
The <plugin_name>
is the short version of the plugin name, based on the
filename. For example if the filename is lib11_imap_quota_plugin.so
,
the <plugin_name>
is imap_quota
and the init function to be called is
imap_quota_plugin_init()
.
Versioning¶
Since different Dovecot versions can have different APIs, your plugin
should usually also define <plugin_name>_version
, like:
const char *imap_quota_plugin_version = DOVECOT_ABI_VERSION;
If the version string in plugin doesn’t match the version of the running
binary, the plugin loading fails. The DOVECOT_ABI_VERSION is defined in
Dovecot’s config.h
, which you’re typically including.
It’s possible to check the Dovecot version number with a macro. This allows either supporting different Dovecot APIs or giving a clear error message if the API is too old to support your plugin. For example:
#if ! DOVECOT_PREREQ(2, 3, 18)
# error Must have at least v2.3.18
#endif
Changed in version v2.3.18: added the 3rd micro-version parameter.
Dependencies¶
Some plugins depend on another one. In some systems (but not all) it’s possible to handle this by giving a nicer error message than “symbol xyz not found”. There are two steps for this:
First create <plugin_name>_dependencies
array listing plugin names that
the plugin depends on, like:
const char *imap_quota_plugin_dependencies[] = { "quota", NULL };
Then you’ll also have to make the plugin .so binary link to the other plugins:
if PLUGIN_DEPS
lib11_imap_quota_plugin_la_LIBADD = \
../quota/lib10_quota_plugin.la
endif
PLUGIN_DEPS
is set only if plugin dependencies are actually supported.
Otherwise the build might fail or plugin loading might fail.
Once all this is done, trying to load imap_quota plugin without quota plugin gives a nice error message:
Error: Can't load plugin imap_quota_plugin: Plugin quota must be loaded also
Hooks¶
Different kinds of plugins can also hook into various things:
imap:
imap_client_created_hook_set()
pop3:
pop3_client_created_hook_set()
submission:
submission_client_created_hook_set()
lmtp:
hook_client_created
lib-storage:
mail_storage_hooks_add()