changeset 4074:dadc6e2cccb8 HEAD

Replaced mail_use_modules and mail_modules settings with mail_plugins and mail_plugin_dir. Now instead of loading all plugins from the directory, you'll have to give a list of plugins to load. If the plugin couldn't be loaded, the process exits instead of just ignoring the problem (this is important with ACL plugin).
author Timo Sirainen <tss@iki.fi>
date Sun, 26 Feb 2006 14:15:34 +0200
parents cd701884900c
children bd7aafc736eb
files dovecot-example.conf src/auth/password-scheme.c src/dict/main.c src/imap/main.c src/lib/module-dir.c src/lib/module-dir.h src/master/mail-process.c src/master/master-settings.c src/master/master-settings.h src/pop3/main.c
diffstat 10 files changed, 101 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/dovecot-example.conf	Sun Feb 26 13:24:35 2006 +0200
+++ b/dovecot-example.conf	Sun Feb 26 14:15:34 2006 +0200
@@ -439,9 +439,10 @@
   # "Too long argument" or "IMAP command line too large" errors often.
   #imap_max_line_length = 65536
 
-  # Support for dynamically loadable modules.
-  #mail_use_modules = no
-  #mail_modules = /usr/lib/dovecot/imap
+  # Support for dynamically loadable plugins. mail_plugins is a space separated
+  # list of plugins to load.
+  #mail_plugins = 
+  #mail_plugin_dir = /usr/lib/dovecot/imap
 
   # Send IMAP capabilities in greeting message. This makes it unnecessary for
   # clients to request it with CAPABILITY command, so it saves one round-trip.
@@ -533,9 +534,10 @@
   #  %s - mailbox size in bytes (before deletion)
   #pop3_logout_format = top=%t/%T, retr=%r/%R, del=%d/%m, size=%s
 
-  # Support for dynamically loadable modules.
-  #mail_use_modules = no
-  #mail_modules = /usr/lib/dovecot/pop3
+  # Support for dynamically loadable plugins. mail_plugins is a space separated
+  # list of plugins to load.
+  #mail_plugins = 
+  #mail_plugin_dir = /usr/lib/dovecot/pop3
 
   # Workarounds for various client bugs:
   #   outlook-no-nuls:
--- a/src/auth/password-scheme.c	Sun Feb 26 13:24:35 2006 +0200
+++ b/src/auth/password-scheme.c	Sun Feb 26 14:15:34 2006 +0200
@@ -474,7 +474,8 @@
 		buffer_append(schemes_buf, s, sizeof(*s));
 
 #ifdef HAVE_MODULES
-	scheme_modules = module_dir_load(AUTH_MODULE_DIR"/password", FALSE);
+	scheme_modules = module_dir_load(AUTH_MODULE_DIR"/password",
+					 NULL, FALSE);
 	for (mod = scheme_modules; mod != NULL; mod = mod->next) {
 		t_push();
 		symbol = t_strconcat(mod->name, "_scheme", NULL);
--- a/src/dict/main.c	Sun Feb 26 13:24:35 2006 +0200
+++ b/src/dict/main.c	Sun Feb 26 14:15:34 2006 +0200
@@ -62,7 +62,7 @@
 	dict_sql_register();
 
 	modules = getenv("MODULE_DIR") == NULL ? NULL :
-		module_dir_load(getenv("MODULE_DIR"), TRUE);
+		module_dir_load(getenv("MODULE_DIR"), NULL, TRUE);
 
 	path = getenv("DICT_LISTEN_FROM_FD");
 	fd = path == NULL ? -1 : DICT_MASTER_LISTENER_FD;
--- a/src/imap/main.c	Sun Feb 26 13:24:35 2006 +0200
+++ b/src/imap/main.c	Sun Feb 26 14:15:34 2006 +0200
@@ -165,8 +165,14 @@
 	clients_init();
 	commands_init();
 
-	modules = getenv("MODULE_DIR") == NULL ? NULL :
-		module_dir_load(getenv("MODULE_DIR"), TRUE);
+	if (getenv("MODULE_LIST") == NULL)
+		modules = NULL;
+	else {
+		if (getenv("MODULE_DIR") == NULL)
+			i_fatal("MODULE_LIST given but MODULE_DIR was not");
+		modules = module_dir_load(getenv("MODULE_DIR"),
+					  getenv("MODULE_LIST"), TRUE);
+	}
 
 	str = getenv("IMAP_MAX_LINE_LENGTH");
 	imap_max_line_length = str != NULL ?
--- a/src/lib/module-dir.c	Sun Feb 26 13:24:35 2006 +0200
+++ b/src/lib/module-dir.c	Sun Feb 26 14:15:34 2006 +0200
@@ -98,21 +98,44 @@
 
 static int module_name_cmp(const void *p1, const void *p2)
 {
-	const char *n1 = p1, *n2 = p2;
+	const char *const *n1 = p1, *const *n2 = p2;
+	const char *s1 = *n1, *s2 = *n2;
 
-	if (strncmp(n1, "lib", 3) == 0)
-		n1 += 3;
-	if (strncmp(n2, "lib", 3) == 0)
-		n2 += 3;
+	if (strncmp(s1, "lib", 3) == 0)
+		s1 += 3;
+	if (strncmp(s2, "lib", 3) == 0)
+		s2 += 3;
 
-	return strcmp(n2, n1);
+	return strcmp(s1, s2);
 }
 
-struct module *module_dir_load(const char *dir, bool require_init_funcs)
+static bool module_want_load(const char **names, const char *name)
+{
+	size_t len;
+
+	if (names == NULL)
+		return TRUE;
+
+	len = strlen(name);
+	if (len > 7 && strcmp(name + len - 7, "_plugin") == 0)
+		name = t_strndup(name, len - 7);
+
+	for (; *names != NULL; names++) {
+		if (strcmp(*names, name) == 0) {
+			*names = "";
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+struct module *module_dir_load(const char *dir, const char *module_names,
+			       bool require_init_funcs)
 {
 	DIR *dirp;
 	struct dirent *d;
 	const char *name, *path, *p, *stripped_name, **names_p;
+	const char **module_names_arr;
 	struct module *modules, *module;
 	unsigned int i, count;
 	array_t ARRAY_DEFINE(names, const char *);
@@ -150,6 +173,9 @@
 	count = array_count(&names);
 	qsort(names_p, count, sizeof(const char *), module_name_cmp);
 
+	t_push();
+	module_names_arr = module_names == NULL ? NULL :
+		t_strsplit_spaces(module_names, ", ");
 	for (i = 0; i < count; i++) {
 		const char *name = names_p[i];
 
@@ -170,8 +196,15 @@
 
 		t_push();
 		stripped_name = t_strdup_until(stripped_name, p);
-		path = t_strconcat(dir, "/", name, NULL);
-		module = module_load(path, stripped_name, require_init_funcs);
+		if (!module_want_load(module_names_arr, stripped_name))
+			module = NULL;
+		else {
+			path = t_strconcat(dir, "/", name, NULL);
+			module = module_load(path, stripped_name,
+					     require_init_funcs);
+			if (module == NULL && module_names_arr != NULL)
+				exit(FATAL_DEFAULT);
+		}
 		t_pop();
 
 		if (module != NULL) {
@@ -179,6 +212,16 @@
 			modules = module;
 		}
 	}
+	if (module_names_arr != NULL) {
+		/* make sure all modules were found */
+		for (; *module_names_arr != NULL; module_names_arr++) {
+			if (**module_names_arr != '\0') {
+				i_fatal("Plugin %s not found from directory %s",
+					*module_names_arr, dir);
+			}
+		}
+	}
+	t_pop();
 	pool_unref(pool);
 
 	if (closedir(dirp) < 0)
--- a/src/lib/module-dir.h	Sun Feb 26 13:24:35 2006 +0200
+++ b/src/lib/module-dir.h	Sun Feb 26 14:15:34 2006 +0200
@@ -10,8 +10,10 @@
         struct module *next;
 };
 
-/* Load all modules in given directory. */
-struct module *module_dir_load(const char *dir, bool require_init_funcs);
+/* Load modules in given directory. module_names is a space separated list of
+   module names to load, or NULL to load everything. */
+struct module *module_dir_load(const char *dir, const char *module_names,
+			       bool require_init_funcs);
 /* Call deinit() in all modules and mark them NULL so module_dir_unload()
    won't do it again. */
 void module_dir_deinit(struct module *modules);
--- a/src/master/mail-process.c	Sun Feb 26 13:24:35 2006 +0200
+++ b/src/master/mail-process.c	Sun Feb 26 14:15:34 2006 +0200
@@ -258,10 +258,9 @@
 	env_put(t_strdup_printf("MBOX_MIN_INDEX_SIZE=%u",
 				set->mbox_min_index_size));
 
-	if (set->mail_use_modules &&
-	    set->mail_modules != NULL && *set->mail_modules != '\0') {
-		env_put(t_strconcat("MODULE_DIR=",
-				    set->mail_modules, NULL));
+	if (*set->mail_plugins != '\0') {
+		env_put(t_strconcat("MODULE_DIR=", set->mail_plugin_dir, NULL));
+		env_put(t_strconcat("MODULE_LIST=", set->mail_plugins, NULL));
 	}
 
 	/* user given environment - may be malicious. virtual_user comes from
--- a/src/master/master-settings.c	Sun Feb 26 13:24:35 2006 +0200
+++ b/src/master/master-settings.c	Sun Feb 26 14:15:34 2006 +0200
@@ -132,8 +132,8 @@
 
 	DEF(SET_STR, mail_executable),
 	DEF(SET_INT, mail_process_size),
-	DEF(SET_BOOL, mail_use_modules),
-	DEF(SET_STR, mail_modules),
+	DEF(SET_STR, mail_plugins),
+	DEF(SET_STR, mail_plugin_dir),
 	DEF(SET_STR, mail_log_prefix),
 
 	/* imap */
@@ -337,8 +337,8 @@
 
 	MEMBER(mail_executable) PKG_LIBEXECDIR"/imap",
 	MEMBER(mail_process_size) 256,
-	MEMBER(mail_use_modules) FALSE,
-	MEMBER(mail_modules) MODULEDIR"/imap",
+	MEMBER(mail_plugins) "",
+	MEMBER(mail_plugin_dir) MODULEDIR"/imap",
 	MEMBER(mail_log_prefix) "%Us(%u): ",
 
 	/* imap */
@@ -578,16 +578,17 @@
 	}
 
 #ifdef HAVE_MODULES
-	if (set->mail_use_modules &&
-	    access(set->mail_modules, R_OK | X_OK) < 0) {
+	if (*set->mail_plugins != '\0' &&
+	    access(set->mail_plugin_dir, R_OK | X_OK) < 0) {
 		i_error("Can't access mail module directory: %s: %m",
-			set->mail_modules);
+			set->mail_plugin_dir);
 		return FALSE;
 	}
 #else
-	if (set->mail_use_modules) {
-		i_warning("Module support wasn't built into Dovecot, "
-			  "ignoring mail_use_modules setting");
+	if (*set->mail_plugins != '\0') {
+		i_error("Module support wasn't built into Dovecot, "
+			"can't load modules: %s", set->mail_plugins);
+		return FALSE;
 	}
 #endif
 
@@ -985,13 +986,13 @@
 	server->imap->protocol = MAIL_PROTOCOL_IMAP;
 	server->imap->login_executable = PKG_LIBEXECDIR"/imap-login";
 	server->imap->mail_executable = PKG_LIBEXECDIR"/imap";
-	server->imap->mail_modules = MODULEDIR"/imap";
+	server->imap->mail_plugin_dir = MODULEDIR"/imap";
 
 	server->pop3->server = server;
 	server->pop3->protocol = MAIL_PROTOCOL_POP3;
 	server->pop3->login_executable = PKG_LIBEXECDIR"/pop3-login";
 	server->pop3->mail_executable = PKG_LIBEXECDIR"/pop3";
-	server->pop3->mail_modules = MODULEDIR"/pop3";
+	server->pop3->mail_plugin_dir = MODULEDIR"/pop3";
 
 	return server;
 }
--- a/src/master/master-settings.h	Sun Feb 26 13:24:35 2006 +0200
+++ b/src/master/master-settings.h	Sun Feb 26 14:15:34 2006 +0200
@@ -95,8 +95,8 @@
 
 	const char *mail_executable;
 	unsigned int mail_process_size;
-	bool mail_use_modules;
-	const char *mail_modules;
+	const char *mail_plugins;
+	const char *mail_plugin_dir;
 	const char *mail_log_prefix;
 
 	/* imap */
--- a/src/pop3/main.c	Sun Feb 26 13:24:35 2006 +0200
+++ b/src/pop3/main.c	Sun Feb 26 14:15:34 2006 +0200
@@ -173,8 +173,14 @@
 	mail_storage_register_all();
 	clients_init();
 
-	modules = getenv("MODULE_DIR") == NULL ? NULL :
-		module_dir_load(getenv("MODULE_DIR"), TRUE);
+	if (getenv("MODULE_LIST") == NULL)
+		modules = NULL;
+	else {
+		if (getenv("MODULE_DIR") == NULL)
+			i_fatal("MODULE_LIST given but MODULE_DIR was not");
+		modules = module_dir_load(getenv("MODULE_DIR"),
+					  getenv("MODULE_LIST"), TRUE);
+	}
 
 	mail = getenv("MAIL");
 	if (mail == NULL) {