dovecot-2.2-pigeonhole: doveadm-sieve: Implemented handling the ...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Wed Apr 3 00:14:45 EEST 2013


details:   http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/8b8bba6e8c2c
changeset: 1735:8b8bba6e8c2c
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Tue Apr 02 23:14:13 2013 +0200
description:
doveadm-sieve: Implemented handling the situation when the main active script is a regular file.
Tested whether this change breaks ManageSieve and basic dsync, but not much more.
More tests pending. If you use sync be careful with this commit.

diffstat:

 src/lib-sieve/sieve-plugins.c                    |   17 +-
 src/lib-sievestorage/sieve-storage-list.c        |    2 +-
 src/lib-sievestorage/sieve-storage-save.c        |   55 ++++-
 src/lib-sievestorage/sieve-storage-save.h        |    6 +
 src/lib-sievestorage/sieve-storage-script.c      |   95 +++++--
 src/lib-sievestorage/sieve-storage-script.h      |   22 +-
 src/lib-sievestorage/sieve-storage.c             |   67 ++--
 src/plugins/doveadm-sieve/doveadm-sieve-plugin.c |  262 +++++++++++++++++-----
 8 files changed, 365 insertions(+), 161 deletions(-)

diffs (truncated from 932 to 300 lines):

diff -r 5323b5e65289 -r 8b8bba6e8c2c src/lib-sieve/sieve-plugins.c
--- a/src/lib-sieve/sieve-plugins.c	Thu Mar 28 22:14:21 2013 +0100
+++ b/src/lib-sieve/sieve-plugins.c	Tue Apr 02 23:14:13 2013 +0200
@@ -58,7 +58,7 @@
 void sieve_plugins_load
 (struct sieve_instance *svinst, const char *path, const char *plugins)
 {
-	struct module *new_modules, *module;
+	struct module *module;
 	struct module_dir_load_settings mod_set;
 	const char **module_names;
 	unsigned int i;
@@ -83,22 +83,9 @@
 
 	/* Load missing plugin modules */
 
-	new_modules = module_dir_load_missing
+	sieve_modules = module_dir_load_missing
 		(sieve_modules, path, plugins, &mod_set);
 
-	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 ) {
diff -r 5323b5e65289 -r 8b8bba6e8c2c src/lib-sievestorage/sieve-storage-list.c
--- a/src/lib-sievestorage/sieve-storage-list.c	Thu Mar 28 22:14:21 2013 +0100
+++ b/src/lib-sievestorage/sieve-storage-list.c	Tue Apr 02 23:14:13 2013 +0200
@@ -45,7 +45,7 @@
 
 	T_BEGIN {
 		/* Get the name of the active script */
-		if ( sieve_storage_get_active_scriptfile(storage, &active) < 0) {
+		if ( sieve_storage_active_script_get_file(storage, &active) < 0) {
 			ctx = NULL;
 		} else {
 			pool = pool_alloconly_create("sieve_list_context", 4096);
diff -r 5323b5e65289 -r 8b8bba6e8c2c src/lib-sievestorage/sieve-storage-save.c
--- a/src/lib-sievestorage/sieve-storage-save.c	Thu Mar 28 22:14:21 2013 +0100
+++ b/src/lib-sievestorage/sieve-storage-save.c	Tue Apr 02 23:14:13 2013 +0200
@@ -9,6 +9,7 @@
 #include "ostream.h"
 #include "str.h"
 #include "eacces-error.h"
+#include "safe-mkstemp.h"
 
 #include "sieve-script.h"
 #include "sieve-script-file.h"
@@ -324,7 +325,7 @@
 		const char *scriptname;
 		int ret;
 
-		ret = sieve_storage_get_active_scriptname(ctx->storage, &scriptname);
+		ret = sieve_storage_active_script_get_name(ctx->storage, &scriptname);
 		if ( ret > 0 ) {
 		 	/* Is the requested script active? */
 			result = ( strcmp(ctx->scriptname, scriptname) == 0 );
@@ -368,3 +369,55 @@
 
 	sieve_storage_save_destroy(ctx);
 }
+
+int sieve_storage_save_as_active_script(struct sieve_storage *storage,
+	struct istream *input)
+{
+	int fd;
+	string_t *temp_path;
+	struct ostream *output;
+
+	temp_path = t_str_new(256);
+	str_append(temp_path, storage->active_path);
+	str_append_c(temp_path, '.');
+	fd = safe_mkstemp_hostpid
+		(temp_path, storage->file_create_mode, (uid_t)-1, (gid_t)-1);
+	if ( fd < 0 ) {
+		if ( errno == EACCES ) {
+			sieve_storage_set_critical(storage,
+				"failed to create temporary file: %s",
+				eacces_error_get_creating("open", str_c(temp_path)));
+		} else {
+			sieve_storage_set_critical(storage,
+				"failed to create temporary file: open(%s) failed: %m",
+				str_c(temp_path));
+		}
+		return -1;
+	}
+
+	output = o_stream_create_fd(fd, 0, FALSE);
+	if (o_stream_send_istream(output, input) < 0) {
+		sieve_storage_set_critical(storage,
+			"o_stream_send_istream(%s) failed: %m", str_c(temp_path));
+		o_stream_destroy(&output);
+		(void)unlink(str_c(temp_path));
+		return -1;
+	}
+	o_stream_destroy(&output);
+
+	if (rename(str_c(temp_path), storage->active_path) < 0) {
+		if ( ENOSPACE(errno) ) {
+			sieve_storage_set_error(storage,
+				SIEVE_ERROR_NO_SPACE, "Not enough disk space");
+		} else if ( errno == EACCES ) {
+			sieve_storage_set_critical(storage,
+				"%s", eacces_error_get("rename", storage->active_path));
+		} else {
+			sieve_storage_set_critical(storage,
+				"rename(%s, %s) failed: %m", str_c(temp_path), storage->active_path);
+		}
+	}
+
+	(void)unlink(str_c(temp_path));
+	return 0;
+}
diff -r 5323b5e65289 -r 8b8bba6e8c2c src/lib-sievestorage/sieve-storage-save.h
--- a/src/lib-sievestorage/sieve-storage-save.h	Thu Mar 28 22:14:21 2013 +0100
+++ b/src/lib-sievestorage/sieve-storage-save.h	Tue Apr 02 23:14:13 2013 +0200
@@ -26,5 +26,11 @@
 
 int sieve_storage_save_commit(struct sieve_save_context **ctx);
 
+/* Saves input directly as a regular file at the active script path.
+ * This is needed for the doveadm-sieve plugin.
+ */
+int sieve_storage_save_as_active_script(struct sieve_storage *storage,
+	struct istream *input);
+
 #endif
 
diff -r 5323b5e65289 -r 8b8bba6e8c2c src/lib-sievestorage/sieve-storage-script.c
--- a/src/lib-sievestorage/sieve-storage-script.c	Thu Mar 28 22:14:21 2013 +0100
+++ b/src/lib-sievestorage/sieve-storage-script.c	Tue Apr 02 23:14:13 2013 +0200
@@ -41,7 +41,7 @@
 	/* Prevent initializing the active script link as a script when it
 	 * resides in the sieve storage directory.
 	 */
-	if ( *(storage->link_path) == '\0' ) {
+	if ( scriptname != NULL && *(storage->link_path) == '\0' ) {
 		const char *fname;
 
 		fname = strrchr(path, '/');
@@ -154,7 +154,7 @@
 	return 1;
 }
 
-static const char *sieve_storage_parse_link
+static const char *sieve_storage_parse_active_link
 (struct sieve_storage *storage, const char *link, const char **scriptname_r)
 {
 	const char *fname, *scriptname, *scriptpath;
@@ -197,7 +197,7 @@
 	return fname;
 }
 
-int sieve_storage_get_active_scriptfile
+int sieve_storage_active_script_get_file
 (struct sieve_storage *storage, const char **file_r)
 {
 	const char *link, *scriptfile;
@@ -210,7 +210,7 @@
 		return ret;
 
 	/* Parse the link */
-	scriptfile = sieve_storage_parse_link(storage, link, NULL);
+	scriptfile = sieve_storage_parse_active_link(storage, link, NULL);
 
 	if (scriptfile == NULL) {
 		/* Obviously someone has been playing with our symlink,
@@ -224,7 +224,7 @@
 	return 1;
 }
 
-int sieve_storage_get_active_scriptname
+int sieve_storage_active_script_get_name
 (struct sieve_storage *storage, const char **name_r)
 {
 	const char *link;
@@ -236,7 +236,7 @@
 	if ( (ret=sieve_storage_read_active_link(storage, &link)) <= 0 )
 		return ret;
 
-	if ( sieve_storage_parse_link(storage, link, name_r) == NULL ) {
+	if ( sieve_storage_parse_active_link(storage, link, name_r) == NULL ) {
 		/* Obviously someone has been playing with our symlink,
 		 * ignore this situation and report 'no active script'.
 		 * Activation should fix this situation.
@@ -247,7 +247,13 @@
 	return 1;
 }
 
-struct sieve_script *sieve_storage_get_active_script
+const char *sieve_storage_active_script_get_path
+	(struct sieve_storage *storage)
+{
+	return storage->active_path;
+}
+
+struct sieve_script *sieve_storage_active_script_get
 (struct sieve_storage *storage)
 {
 	struct sieve_script *script;
@@ -268,7 +274,7 @@
 	}
 
 	/* Parse the link */
-	scriptfile = sieve_storage_parse_link(storage, link, NULL);
+	scriptfile = sieve_storage_parse_active_link(storage, link, NULL);
 
 	if (scriptfile == NULL) {
 		/* Obviously someone has been playing with our symlink,
@@ -289,6 +295,54 @@
 	return script;
 }
 
+int sieve_storage_active_script_get_last_change
+(struct sieve_storage *storage, time_t *last_change_r)
+{
+	struct stat st;
+
+	/* Try direct lstat first */
+	if (lstat(storage->active_path, &st) == 0) {
+		*last_change_r = st.st_mtime;
+		return 0;
+	}
+
+	/* Check error */
+	if (errno != ENOENT) {
+		sieve_storage_set_critical(storage, "lstat(%s) failed: %m",
+			   storage->active_path);
+	}
+
+	/* Fall back to statting storage directory */
+	return sieve_storage_get_last_change(storage, last_change_r);
+}
+
+int
+sieve_storage_active_script_is_no_link(struct sieve_storage *storage)
+{
+	struct stat st;
+
+	/* Stat the file */
+	if ( lstat(storage->active_path, &st) != 0 ) {
+		if ( errno != ENOENT ) {
+			sieve_storage_set_critical(storage,
+				"Failed to stat active sieve script symlink (%s): %m.",
+				storage->active_path);
+			return -1;
+		}
+		return 0;
+	}
+
+	if ( S_ISLNK( st.st_mode ) )
+		return 0;
+	if ( !S_ISREG( st.st_mode ) ) {
+		sieve_storage_set_critical( storage,
+			"Active sieve script file '%s' is no symlink nor a regular file.",
+			storage->active_path );
+		return -1;
+	}
+	return 1;
+}
+
 int sieve_storage_script_is_active(struct sieve_script *script)
 {
 	struct sieve_storage_script *st_script =
@@ -297,7 +351,7 @@
 	int ret = 0;
 
 	T_BEGIN {
-		ret = sieve_storage_get_active_scriptfile(st_script->storage, &afile);
+		ret = sieve_storage_active_script_get_file(st_script->storage, &afile);
 
 		if ( ret > 0 ) {
 		 	/* Is the requested script active? */
@@ -486,7 +540,7 @@
 	 * resolves automatically. This step is only necessary to provide a
 	 * proper return value indicating whether the script was already active.
 	 */
-	ret = sieve_storage_get_active_scriptfile(storage, &afile);
+	ret = sieve_storage_active_script_get_file(storage, &afile);
 
 	/* Is the requested script already active? */
 	if ( ret <= 0 || strcmp(st_script->file.filename, afile) != 0 )
@@ -545,27 +599,6 @@
 	return ret;
 }
 
-int sieve_storage_get_active_script_last_change
-(struct sieve_storage *storage, time_t *last_change_r)
-{


More information about the dovecot-cvs mailing list