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