dovecot-1.2: virtual mailboxes: Added support for using wildcard...

dovecot at dovecot.org dovecot at dovecot.org
Fri Aug 8 23:50:48 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/3aec087609f0
changeset: 8080:3aec087609f0
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Aug 08 16:50:39 2008 -0400
description:
virtual mailboxes: Added support for using wildcards in mailbox names.
The wildcards don't span namespaces so that "*" won't also match
mailboxes in virtual namespace.

diffstat:

2 files changed, 98 insertions(+), 3 deletions(-)
src/plugins/virtual/virtual-config.c  |   93 ++++++++++++++++++++++++++++++++-
src/plugins/virtual/virtual-storage.h |    8 ++

diffs (175 lines):

diff -r 4e1b54eb7407 -r 3aec087609f0 src/plugins/virtual/virtual-config.c
--- a/src/plugins/virtual/virtual-config.c	Fri Aug 08 16:48:44 2008 -0400
+++ b/src/plugins/virtual/virtual-config.c	Fri Aug 08 16:50:39 2008 -0400
@@ -5,8 +5,10 @@
 #include "istream.h"
 #include "str.h"
 #include "imap-parser.h"
+#include "imap-match.h"
 #include "mail-search-build.h"
 #include "virtual-storage.h"
+#include "virtual-plugin.h"
 
 #include <unistd.h>
 #include <fcntl.h>
@@ -18,6 +20,9 @@ struct virtual_parse_context {
 	pool_t pool;
 	string_t *rule;
 	unsigned int rule_idx;
+
+	char sep;
+	bool have_wildcards;
 };
 
 static struct mail_search_args *
@@ -65,6 +70,8 @@ virtual_config_add_rule(struct virtual_p
 		return -1;
 	}
 
+	/* update at all the mailboxes that were introduced since the previous
+	   rule. */
 	bboxes = array_get(&ctx->mbox->backend_boxes, &count);
 	i_assert(ctx->rule_idx < count);
 	for (i = ctx->rule_idx; i < count; i++) {
@@ -96,11 +103,90 @@ virtual_config_parse_line(struct virtual
 	if (virtual_config_add_rule(ctx, error_r) < 0)
 		return -1;
 
-	/* new mailbox */
+	/* new mailbox. the search args are added to it later. */
 	bbox = p_new(ctx->pool, struct virtual_backend_box, 1);
 	bbox->name = p_strdup(ctx->pool, line);
+	if (strchr(bbox->name, '*') != NULL ||
+	    strchr(bbox->name, '%') != NULL) {
+		bbox->glob = imap_match_init(ctx->pool, bbox->name,
+					     TRUE, ctx->sep);
+		bbox->ns = mail_namespace_find(virtual_all_namespaces, &line);
+		ctx->have_wildcards = TRUE;
+	}
 	array_append(&ctx->mbox->backend_boxes, &bbox, 1);
 	return 0;
+}
+
+static void
+separate_wildcard_mailboxes(struct virtual_mailbox *mbox,
+			    ARRAY_TYPE(virtual_backend_box) *wildcard_boxes)
+{
+	struct virtual_backend_box *const *bboxes;
+	unsigned int i, count;
+
+	bboxes = array_get_modifiable(&mbox->backend_boxes, &count);
+	t_array_init(wildcard_boxes, I_MIN(16, count));
+	for (i = 0; i < count;) {
+		if (bboxes[i]->glob == NULL)
+			i++;
+		else {
+			array_append(wildcard_boxes, &bboxes[i], 1);
+			array_delete(&mbox->backend_boxes, i, 1);
+			bboxes = array_get_modifiable(&mbox->backend_boxes,
+						      &count);
+		}
+	}
+}
+
+static void virtual_config_copy_expanded(struct virtual_parse_context *ctx,
+					 struct virtual_backend_box *wbox,
+					 const char *name)
+{
+	struct virtual_backend_box *bbox;
+
+	bbox = p_new(ctx->pool, struct virtual_backend_box, 1);
+	*bbox = *wbox;
+	bbox->name = p_strdup(ctx->pool, name);
+	bbox->glob = NULL;
+	mail_search_args_ref(bbox->search_args);
+	array_append(&ctx->mbox->backend_boxes, &bbox, 1);
+}
+
+static int virtual_config_expand_wildcards(struct virtual_parse_context *ctx)
+{
+	ARRAY_TYPE(virtual_backend_box) wildcard_boxes;
+	struct mailbox_list_iterate_context *iter;
+	struct virtual_backend_box *const *wboxes;
+	const char **patterns;
+	const struct mailbox_info *info;
+	unsigned int i, count;
+
+	separate_wildcard_mailboxes(ctx->mbox, &wildcard_boxes);
+
+	/* get patterns we want to list */
+	wboxes = array_get_modifiable(&wildcard_boxes, &count);
+	patterns = t_new(const char *, count + 1);
+	for (i = 0; i < count; i++)
+		patterns[i] = wboxes[i]->name;
+
+	/* match listed mailboxes to wildcards */
+	iter = mailbox_list_iter_init_namespaces(
+					virtual_all_namespaces, patterns,
+					MAILBOX_LIST_ITER_VIRTUAL_NAMES |
+					MAILBOX_LIST_ITER_RETURN_NO_FLAGS);
+	while ((info = mailbox_list_iter_next(iter)) != NULL) {
+		for (i = 0; i < count; i++) {
+			if (wboxes[i]->ns == info->ns &&
+			    imap_match(wboxes[i]->glob,
+				       info->name) == IMAP_MATCH_YES) {
+				virtual_config_copy_expanded(ctx, wboxes[i],
+							     info->name);
+			}
+		}
+	}
+	for (i = 0; i < count; i++)
+		mail_search_args_unref(&wboxes[i]->search_args);
+	return mailbox_list_iter_deinit(&iter);
 }
 
 int virtual_config_read(struct virtual_mailbox *mbox)
@@ -127,6 +213,7 @@ int virtual_config_read(struct virtual_m
 	}
 
 	memset(&ctx, 0, sizeof(ctx));
+	ctx.sep = mail_namespace_get_root_sep(virtual_all_namespaces);
 	ctx.mbox = mbox;
 	ctx.pool = mbox->ibox.box.pool;
 	ctx.rule = t_str_new(256);
@@ -149,6 +236,9 @@ int virtual_config_read(struct virtual_m
 	if (ret == 0)
 		ret = virtual_config_add_rule(&ctx, &error);
 
+	if (ret == 0 && ctx.have_wildcards)
+		ret = virtual_config_expand_wildcards(&ctx);
+
 	if (ret == 0 && array_count(&mbox->backend_boxes) == 0) {
 		mail_storage_set_critical(mbox->ibox.storage,
 					  "%s: No mailboxes defined", path);
@@ -168,4 +258,3 @@ void virtual_config_free(struct virtual_
 	for (i = 0; i < count; i++)
 		mail_search_args_unref(&bboxes[i]->search_args);
 }
-
diff -r 4e1b54eb7407 -r 3aec087609f0 src/plugins/virtual/virtual-storage.h
--- a/src/plugins/virtual/virtual-storage.h	Fri Aug 08 16:48:44 2008 -0400
+++ b/src/plugins/virtual/virtual-storage.h	Fri Aug 08 16:50:39 2008 -0400
@@ -73,8 +73,14 @@ struct virtual_backend_box {
 	struct mail *sync_mail;
 	/* pending removed UIDs */
 	ARRAY_TYPE(seq_range) sync_pending_removes;
+
+	/* name contains a wildcard, this is a glob for it */
+	struct imap_match_glob *glob;
+	struct mail_namespace *ns;
+
 	unsigned int sync_seen:1;
 };
+ARRAY_DEFINE_TYPE(virtual_backend_box, struct virtual_backend_box *);
 
 struct virtual_mailbox {
 	struct index_mailbox ibox;
@@ -88,7 +94,7 @@ struct virtual_mailbox {
 	uint32_t highest_mailbox_id;
 
 	/* Mailboxes this virtual mailbox consists of, sorted by mailbox_id */
-	ARRAY_DEFINE(backend_boxes, struct virtual_backend_box *);
+	ARRAY_TYPE(virtual_backend_box) backend_boxes;
 
 	unsigned int uids_mapped:1;
 	unsigned int sync_initialized:1;


More information about the dovecot-cvs mailing list