dovecot-1.2-sieve: Further developed support for Sieve engine plugins.
pigeonhole at rename-it.nl
pigeonhole at rename-it.nl
Thu Dec 31 19:17:56 EET 2009
details: http://hg.rename-it.nl/dovecot-1.2-sieve/rev/42de2855105d
changeset: 1172:42de2855105d
user: Stephan Bosch <stephan at rename-it.nl>
date: Thu Dec 31 18:10:46 2009 +0100
description:
Further developed support for Sieve engine plugins.
diffstat:
src/lib-sieve/Makefile.am | 2 +
src/lib-sieve/sieve-common.h | 6 +
src/lib-sieve/sieve-plugins.c | 210 ++++++++++++++++++++++++++++++++++++++++++
src/lib-sieve/sieve-plugins.h | 12 ++
src/lib-sieve/sieve.c | 79 +---------------
5 files changed, 232 insertions(+), 77 deletions(-)
diffs (truncated from 379 to 300 lines):
diff -r 66404c1a046f -r 42de2855105d src/lib-sieve/Makefile.am
--- a/src/lib-sieve/Makefile.am Thu Dec 31 04:41:30 2009 +0100
+++ b/src/lib-sieve/Makefile.am Thu Dec 31 18:10:46 2009 +0100
@@ -96,6 +96,7 @@
sieve-code.c \
sieve-actions.c \
sieve-extensions.c \
+ sieve-plugins.c \
$(comparators) \
$(match_types) \
$(tests) \
@@ -136,6 +137,7 @@
sieve-code.h \
sieve-actions.h \
sieve-extensions.h \
+ sieve-plugins.h \
sieve.h
if INSTALL_HEADERS
diff -r 66404c1a046f -r 42de2855105d src/lib-sieve/sieve-common.h
--- a/src/lib-sieve/sieve-common.h Thu Dec 31 04:41:30 2009 +0100
+++ b/src/lib-sieve/sieve-common.h Thu Dec 31 18:10:46 2009 +0100
@@ -125,6 +125,9 @@
/* sieve-message.h */
struct sieve_message_context;
+/* sieve-plugins.h */
+struct sieve_plugin;
+
/* sieve.c */
struct sieve_ast *sieve_parse
(struct sieve_script *script, struct sieve_error_handler *ehandler);
@@ -146,6 +149,9 @@
/* Extension registry */
struct sieve_extension_registry *ext_reg;
+ /* Plugin modules */
+ struct sieve_plugin *plugins;
+
/* Limits */
size_t max_script_size;
unsigned int max_actions;
diff -r 66404c1a046f -r 42de2855105d src/lib-sieve/sieve-plugins.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-sieve/sieve-plugins.c Thu Dec 31 18:10:46 2009 +0100
@@ -0,0 +1,210 @@
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
+ */
+
+#include "lib.h"
+#include "str.h"
+#include "module-dir.h"
+
+#include "sieve-settings.h"
+#include "sieve-extensions.h"
+
+#include "sieve-common.h"
+#include "sieve-plugins.h"
+
+struct sieve_plugin {
+ struct module *module;
+ struct sieve_plugin *next;
+};
+
+/*
+ * Plugin support
+ */
+
+static struct module *sieve_modules = NULL;
+static int sieve_modules_refcount = 0;
+
+static struct module *sieve_plugin_module_find(const char *path, const char *name)
+{
+ struct module *module;
+
+ module = sieve_modules;
+ while ( module != NULL ) {
+ const char *mod_path, *mod_name;
+ char *p;
+ size_t len;
+
+ /* Strip module paths */
+
+ p = strrchr(module->path, '/');
+ if ( p == NULL ) continue;
+ while ( p > module->path && *p == '/' ) p--;
+ mod_path = t_strdup_until(module->path, p+1);
+
+ len = strlen(path);
+ if ( path[len-1] == '/' )
+ path = t_strndup(path, len-1);
+
+ /* Strip module names */
+
+ len = strlen(module->name);
+ if (len > 7 && strcmp(module->name + len - 7, "_plugin") == 0)
+ mod_name = t_strndup(module->name, len - 7);
+ else
+ mod_name = module->name;
+
+ if ( strcmp(mod_path, path) == 0 && strcmp(mod_name, name) == 0 )
+ return module;
+
+ module = module->next;
+ }
+
+ return NULL;
+}
+
+void sieve_plugins_load(struct sieve_instance *svinst, const char *path, const char *plugins)
+{
+ struct module *module;
+ const char **module_names;
+ string_t *missing_modules;
+ unsigned int i;
+
+ /* Determine what to load */
+
+ if ( path == NULL && plugins == NULL ) {
+ path = sieve_setting_get(svinst, "sieve_plugin_dir");
+ plugins = sieve_setting_get(svinst, "sieve_plugins");
+ }
+
+ if ( plugins == NULL || *plugins == '\0' )
+ return;
+
+ if ( path == NULL || *path == '\0' )
+ path = MODULEDIR"/sieve";
+
+ module_names = t_strsplit_spaces(plugins, ", ");
+
+ for (i = 0; module_names[i] != NULL; i++) {
+ /* Allow giving the module names also in non-base form. */
+ module_names[i] = module_file_get_name(module_names[i]);
+ }
+
+ /* Load missing modules
+ * FIXME: Dovecot should provide this functionality (v2.0 does)
+ */
+
+ missing_modules = t_str_new(256);
+
+ for (i = 0; module_names[i] != NULL; i++) {
+ const char *name = module_names[i];
+
+ if ( sieve_plugin_module_find(path, name) == NULL ) {
+ if ( i > 0 ) str_append_c(missing_modules, ' ');
+
+ str_append(missing_modules, name);
+ }
+ }
+
+ if ( str_len(missing_modules) > 0 ) {
+ struct module *new_modules = module_dir_load
+ (path, str_c(missing_modules), TRUE, SIEVE_VERSION);
+
+ if ( sieve_modules == NULL ) {
+ /* No modules loaded yet */
+ sieve_modules = new_modules;
+ } else {
+ /* Find the end of the list */
+ module = sieve_modules;
+ while ( module != NULL && module->next != NULL )
+ module = module->next;
+
+ /* Add newly loaded modules */
+ module->next = new_modules;
+ }
+ }
+
+ /* Call plugin load functions for this Sieve instance */
+
+ if ( svinst->plugins == NULL ) {
+ sieve_modules_refcount++;
+ }
+
+ for (i = 0; module_names[i] != NULL; i++) {
+ struct sieve_plugin *plugin;
+ const char *name = module_names[i];
+ void (*load_func)(struct sieve_instance *svinst);
+
+ /* Find the module */
+ module = sieve_plugin_module_find(path, name);
+ i_assert(module != NULL);
+
+ /* Check whether the plugin is already loaded in this instance */
+ plugin = svinst->plugins;
+ while ( plugin != NULL ) {
+ if ( plugin->module == module )
+ break;
+ plugin = plugin->next;
+ }
+
+ /* Skip it if it is loaded already */
+ if ( plugin != NULL )
+ continue;
+
+ /* Create plugin list item */
+ plugin = p_new(svinst->pool, struct sieve_plugin, 1);
+ plugin->module = module;
+
+ /* Call load function */
+ load_func = module_get_symbol
+ (module, t_strdup_printf("%s_load", module->name));
+ if ( load_func != NULL ) {
+ load_func(svinst);
+ }
+
+ /* Add plugin to the instance */
+ if ( svinst->plugins == NULL )
+ svinst->plugins = plugin;
+ else {
+ struct sieve_plugin *plugin_last;
+
+ plugin_last = svinst->plugins;
+ while ( plugin_last != NULL )
+ plugin_last = plugin_last->next;
+
+ plugin_last->next = plugin;
+ }
+ }
+}
+
+void sieve_plugins_unload(struct sieve_instance *svinst)
+{
+ struct sieve_plugin *plugin;
+
+ if ( svinst->plugins == NULL )
+ return;
+
+ /* Call plugin unload functions for this instance */
+
+ plugin = svinst->plugins;
+ while ( plugin != NULL ) {
+ struct module *module = plugin->module;
+ void (*unload_func)(struct sieve_instance *svinst);
+
+ unload_func = module_get_symbol
+ (module, t_strdup_printf("%s_unload", module->name));
+ if ( unload_func != NULL ) {
+ unload_func(svinst);
+ }
+
+ plugin = plugin->next;
+ }
+
+ /* Physically unload modules */
+
+ i_assert(sieve_modules_refcount > 0);
+
+ if ( --sieve_modules_refcount != 0 )
+ return;
+
+ module_dir_unload(&sieve_modules);
+}
+
diff -r 66404c1a046f -r 42de2855105d src/lib-sieve/sieve-plugins.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-sieve/sieve-plugins.h Thu Dec 31 18:10:46 2009 +0100
@@ -0,0 +1,12 @@
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
+ */
+
+#ifndef __SIEVE_PLUGINS_H
+#define __SIEVE_PLUGINS_H
+
+#include "sieve-common.h"
+
+void sieve_plugins_load(struct sieve_instance *svinst, const char *path, const char *plugins);
+void sieve_plugins_unload(struct sieve_instance *svinst);
+
+#endif /* __SIEVE_PLUGINS_H */
diff -r 66404c1a046f -r 42de2855105d src/lib-sieve/sieve.c
--- a/src/lib-sieve/sieve.c Thu Dec 31 04:41:30 2009 +0100
+++ b/src/lib-sieve/sieve.c Thu Dec 31 18:10:46 2009 +0100
@@ -6,11 +6,11 @@
#include "istream.h"
#include "buffer.h"
#include "eacces-error.h"
-#include "module-dir.h"
#include "sieve-limits.h"
#include "sieve-settings.h"
#include "sieve-extensions.h"
+#include "sieve-plugins.h"
#include "sieve-script.h"
#include "sieve-ast.h"
@@ -35,81 +35,6 @@
#include <stdio.h>
#include <dirent.h>
-/*
- * Plugin support
- */
-
-static struct module *sieve_modules = NULL;
-static int sieve_modules_refcount = 0;
-
-static void sieve_plugins_load(struct sieve_instance *svinst)
More information about the dovecot-cvs
mailing list