dovecot-2.2-pigeonhole: doveadm-sieve: Fixed synchronization of ...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Thu May 9 12:29:05 EEST 2013


details:   http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/676ca33ea4f6
changeset: 1760:676ca33ea4f6
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Thu May 09 11:28:44 2013 +0200
description:
doveadm-sieve: Fixed synchronization of script deletions.
Sieve storage now updates sieve attributes in the user's INBOX if used by ManageSieve.

diffstat:

 src/lib-sievestorage/sieve-storage-private.h     |   12 ++-
 src/lib-sievestorage/sieve-storage-save.c        |   26 +++--
 src/lib-sievestorage/sieve-storage-script.c      |   10 +-
 src/lib-sievestorage/sieve-storage.c             |  113 +++++++++++++++++++++-
 src/lib-sievestorage/sieve-storage.h             |   22 +++-
 src/managesieve/managesieve-client.c             |    2 +-
 src/plugins/doveadm-sieve/doveadm-sieve-plugin.c |   12 +--
 7 files changed, 162 insertions(+), 35 deletions(-)

diffs (truncated from 386 to 300 lines):

diff -r e2e1ecc75a72 -r 676ca33ea4f6 src/lib-sievestorage/sieve-storage-private.h
--- a/src/lib-sievestorage/sieve-storage-private.h	Mon May 06 22:48:59 2013 +0200
+++ b/src/lib-sievestorage/sieve-storage-private.h	Thu May 09 11:28:44 2013 +0200
@@ -36,12 +36,14 @@
 	char *active_fname;
 	char *link_path;
 	char *error;
-	char *user; /* name of user accessing the storage */
+	char *username; /* name of user accessing the storage */
 
 	mode_t dir_create_mode;
 	mode_t file_create_mode;
 	gid_t file_create_gid;
 
+	struct mailbox *inbox;
+
 	uint64_t max_scripts;
 	uint64_t max_storage;
 
@@ -55,5 +57,13 @@
 struct sieve_script *sieve_storage_script_init_from_path
 	(struct sieve_storage *storage, const char *path, const char *scriptname);
 
+void sieve_storage_inbox_script_attribute_set
+	(struct sieve_storage *storage, const char *name);
+void sieve_storage_inbox_script_attribute_rename
+	(struct sieve_storage *storage, const char *oldname, const char *newname);
+void sieve_storage_inbox_script_attribute_unset
+	(struct sieve_storage *storage, const char *name);
+
+
 #endif
 
diff -r e2e1ecc75a72 -r 676ca33ea4f6 src/lib-sievestorage/sieve-storage-save.c
--- a/src/lib-sievestorage/sieve-storage-save.c	Mon May 06 22:48:59 2013 +0200
+++ b/src/lib-sievestorage/sieve-storage-save.c	Thu May 09 11:28:44 2013 +0200
@@ -361,25 +361,31 @@
 	}
 }
 
-int sieve_storage_save_commit(struct sieve_save_context **ctx)
+int sieve_storage_save_commit(struct sieve_save_context **_ctx)
 {
+	struct sieve_save_context *ctx = *_ctx;
+	struct sieve_storage *storage = ctx->storage;
 	const char *dest_path;
 	bool failed = FALSE;
 
-	i_assert((*ctx)->output == NULL);
-	i_assert((*ctx)->finished);
-	i_assert((*ctx)->scriptname != NULL);
+	i_assert(ctx->output == NULL);
+	i_assert(ctx->finished);
+	i_assert(ctx->scriptname != NULL);
 
 	T_BEGIN {
-		dest_path = t_strconcat((*ctx)->storage->dir, "/",
-			sieve_scriptfile_from_name((*ctx)->scriptname), NULL);
+		dest_path = t_strconcat(storage->dir, "/",
+			sieve_scriptfile_from_name(ctx->scriptname), NULL);
 
-		failed = !sieve_storage_script_move((*ctx), dest_path);
-		if ( (*ctx)->mtime != (time_t)-1 )
-			sieve_storage_update_mtime(dest_path, (*ctx)->mtime);
+		failed = !sieve_storage_script_move(ctx, dest_path);
+		if ( ctx->mtime != (time_t)-1 )
+			sieve_storage_update_mtime(dest_path, ctx->mtime);
 	} T_END;
 
-	sieve_storage_save_destroy(ctx);
+	/* set INBOX mailbox attribute */
+	if ( !failed )
+		sieve_storage_inbox_script_attribute_set(storage, ctx->scriptname);
+
+	sieve_storage_save_destroy(_ctx);
 
 	return ( failed ? -1 : 0 );
 }
diff -r e2e1ecc75a72 -r 676ca33ea4f6 src/lib-sievestorage/sieve-storage-script.c
--- a/src/lib-sievestorage/sieve-storage-script.c	Mon May 06 22:48:59 2013 +0200
+++ b/src/lib-sievestorage/sieve-storage-script.c	Thu May 09 11:28:44 2013 +0200
@@ -391,6 +391,10 @@
 		}
 	}
 
+	/* unset INBOX mailbox attribute */
+	if ( ret >= 0 )
+		sieve_storage_inbox_script_attribute_unset(storage, (*script)->name);
+
 	/* Always deinitialize the script object */
 	sieve_script_unref(script);
 	return ret;
@@ -609,7 +613,7 @@
 	struct sieve_storage_script *st_script =
 		(struct sieve_storage_script *) script;
 	struct sieve_storage *storage = st_script->storage;
-	const char *newpath, *newfile, *link_path;
+	const char *oldname = script->name, *newpath, *newfile, *link_path;
 	int ret = 0;
 
 	/* Check script name */
@@ -680,6 +684,10 @@
 		}
 	} T_END;
 
+	/* rename INBOX mailbox attribute */
+	if ( ret >= 0 && oldname != NULL )
+		sieve_storage_inbox_script_attribute_rename(storage, oldname, newname);
+
 	return ret;
 }
 
diff -r e2e1ecc75a72 -r 676ca33ea4f6 src/lib-sievestorage/sieve-storage.c
--- a/src/lib-sievestorage/sieve-storage.c	Mon May 06 22:48:59 2013 +0200
+++ b/src/lib-sievestorage/sieve-storage.c	Thu May 09 11:28:44 2013 +0200
@@ -7,6 +7,7 @@
 #include "mkdir-parents.h"
 #include "eacces-error.h"
 #include "unlink-old-files.h"
+#include "mail-storage-private.h"
 
 #include "sieve.h"
 #include "sieve-common.h"
@@ -202,15 +203,36 @@
 	return 1;
 }
 
+static int _sieve_storage_open_inbox
+(struct mail_user *user, struct mailbox **box_r)
+{
+	struct mail_namespace *ns;
+	struct mailbox *box;
+	enum mailbox_flags flags = MAILBOX_FLAG_IGNORE_ACLS;
+	enum mail_error error;
+
+	ns = mail_namespace_find_inbox(user->namespaces);
+	*box_r = box = mailbox_alloc(ns->list, "INBOX", flags);
+	if (mailbox_open(box) == 0)
+		return 0;
+
+	i_warning("sieve-storage: "
+		"Failed to open user INBOX for attribute modifications: %s",
+		mailbox_get_last_error(box, &error));
+	return -1;
+}
+
 static struct sieve_storage *_sieve_storage_create
-(struct sieve_instance *svinst, const char *user, const char *home,
+(struct sieve_instance *svinst, struct mail_user *user, const char *home,
 	enum sieve_storage_flags flags)
 {
 	pool_t pool;
 	struct sieve_storage *storage;
+	struct mailbox *inbox = NULL;
 	bool debug = ( (flags & SIEVE_STORAGE_FLAG_DEBUG) != 0 );
 	const char *tmp_dir, *link_path, *path;
 	const char *sieve_data, *active_path, *active_fname, *storage_dir;
+	const char *username = user->username;
 	mode_t dir_create_mode, file_create_mode;
 	gid_t file_create_gid;
 	const char *file_create_gid_origin;
@@ -265,7 +287,8 @@
 	path = home_expand_tilde(active_path, home);
 	if ( path == NULL ) {
 		i_error("sieve-storage: userdb(%s) didn't return a home directory "
-			"for substitition in active script path (sieve=%s)", user, active_path);
+			"for substitition in active script path (sieve=%s)",
+			username, active_path);
 		return NULL;
 	}
 
@@ -368,7 +391,7 @@
 	if ( path == NULL ) {
 		i_error("sieve-storage: userdb(%s) didn't return a home directory "
 			"for substitition in storage root directory (sieve_dir=%s)",
-			user, storage_dir);
+			username, storage_dir);
 		return NULL;
 	}
 
@@ -414,6 +437,10 @@
 		file_create_gid_origin, debug) < 0 )
 		return NULL;
 
+	/* Open user's INBOX for attribute updates if necessary */
+	if ( (flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) == 0 )
+		(void)_sieve_storage_open_inbox(user, &inbox);
+
 	/*
 	 * Create storage object
 	 */
@@ -424,7 +451,7 @@
 	storage->flags = flags;
 	storage->pool = pool;
 	storage->dir = p_strdup(pool, storage_dir);
-	storage->user = p_strdup(pool, user);
+	storage->username = p_strdup(pool, username);
 	storage->active_path = p_strdup(pool, active_path);
 	storage->active_fname = p_strdup(pool, active_fname);
 	storage->prev_mtime = st.st_mtime;
@@ -433,6 +460,8 @@
 	storage->file_create_mode = file_create_mode;
 	storage->file_create_gid = file_create_gid;
 
+	storage->inbox = inbox;
+
 	/* Get the path to be prefixed to the script name in the symlink pointing
 	 * to the active script.
 	 */
@@ -474,7 +503,7 @@
 }
 
 struct sieve_storage *sieve_storage_create
-(struct sieve_instance *svinst, const char *user, const char *home,
+(struct sieve_instance *svinst, struct mail_user *user, const char *home,
 	enum sieve_storage_flags flags)
 {
 	struct sieve_storage *storage;
@@ -486,9 +515,10 @@
 	return storage;
 }
 
-
 void sieve_storage_free(struct sieve_storage *storage)
 {
+	if (storage->inbox != NULL)
+		mailbox_free(&storage->inbox);
 	sieve_error_handler_unref(&storage->ehandler);
 
 	pool_unref(&storage->pool);
@@ -641,3 +671,74 @@
 
 	return storage->error != NULL ? storage->error : "Unknown error";
 }
+
+/*
+ * INBOX attributes
+ */
+
+static void sieve_storage_inbox_transaction_finish
+(struct sieve_storage *storage, struct mailbox_transaction_context **t)
+{
+	struct mailbox *inbox = storage->inbox;
+
+	if (mailbox_transaction_commit(t) < 0) {
+		enum mail_error error;
+		
+		i_warning("sieve-storage: Failed to update INBOX attributes: %s",
+			mail_storage_get_last_error(mailbox_get_storage(inbox), &error));
+	}
+}
+
+void sieve_storage_inbox_script_attribute_set
+(struct sieve_storage *storage, const char *name)
+{
+	struct mailbox_transaction_context *t;
+	const char *key;
+
+	if (storage->inbox == NULL)
+		return;
+
+	key = t_strconcat
+		(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, name, NULL);
+	t = mailbox_transaction_begin(storage->inbox, 0);	
+	mail_index_attribute_set(t->itrans, TRUE, key, ioloop_time, 0);
+	sieve_storage_inbox_transaction_finish(storage, &t);
+}
+
+void sieve_storage_inbox_script_attribute_rename
+(struct sieve_storage *storage, const char *oldname, const char *newname)
+{
+	struct mailbox_transaction_context *t;
+	const char *oldkey, *newkey;
+
+	if (storage->inbox == NULL)
+		return;
+
+	oldkey = t_strconcat
+		(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, oldname, NULL);
+	newkey = t_strconcat
+		(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, newname, NULL);
+
+	t = mailbox_transaction_begin(storage->inbox, 0);	
+	mail_index_attribute_unset(t->itrans, TRUE, oldkey, ioloop_time);
+	mail_index_attribute_set(t->itrans, TRUE, newkey, ioloop_time, 0);
+	sieve_storage_inbox_transaction_finish(storage, &t);
+}
+
+void sieve_storage_inbox_script_attribute_unset
+(struct sieve_storage *storage, const char *name)
+{
+	struct mailbox_transaction_context *t;
+	const char *key;
+
+	if (storage->inbox == NULL)
+		return;
+
+	key = t_strconcat
+		(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES, name, NULL);
+	


More information about the dovecot-cvs mailing list