dovecot-1.2: virtual mailboxes: Support negative mailbox pattern...

dovecot at dovecot.org dovecot at dovecot.org
Fri Nov 7 16:29:46 EET 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/db0c70913765
changeset: 8390:db0c70913765
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Nov 07 16:29:42 2008 +0200
description:
virtual mailboxes: Support negative mailbox patterns/names.
This allows for example "all mailboxes, except Spam".

diffstat:

1 file changed, 58 insertions(+), 21 deletions(-)
src/plugins/virtual/virtual-config.c |   79 ++++++++++++++++++++++++----------

diffs (132 lines):

diff -r b9e34721e74c -r db0c70913765 src/plugins/virtual/virtual-config.c
--- a/src/plugins/virtual/virtual-config.c	Thu Nov 06 15:33:53 2008 +0200
+++ b/src/plugins/virtual/virtual-config.c	Fri Nov 07 16:29:42 2008 +0200
@@ -96,6 +96,7 @@ virtual_config_parse_line(struct virtual
 {
 	struct mail_user *user = ctx->mbox->storage->storage.ns->user;
 	struct virtual_backend_box *bbox;
+	const char *name;
 
 	if (*line == ' ') {
 		/* continues the previous search rule */
@@ -118,8 +119,8 @@ virtual_config_parse_line(struct virtual
 	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);
+		name = bbox->name[0] == '-' ? bbox->name +1 : bbox->name;
+		bbox->glob = imap_match_init(ctx->pool, name, TRUE, ctx->sep);
 		bbox->ns = mail_namespace_find(user->namespaces, &line);
 		ctx->have_wildcards = TRUE;
 	}
@@ -129,18 +130,28 @@ virtual_config_parse_line(struct virtual
 
 static void
 separate_wildcard_mailboxes(struct virtual_mailbox *mbox,
-			    ARRAY_TYPE(virtual_backend_box) *wildcard_boxes)
+			    ARRAY_TYPE(virtual_backend_box) *wildcard_boxes,
+			    ARRAY_TYPE(virtual_backend_box) *neg_boxes)
 {
 	struct virtual_backend_box *const *bboxes;
+	ARRAY_TYPE(virtual_backend_box) *dest;
 	unsigned int i, count;
 
 	bboxes = array_get_modifiable(&mbox->backend_boxes, &count);
 	t_array_init(wildcard_boxes, I_MIN(16, count));
+	t_array_init(neg_boxes, 4);
 	for (i = 0; i < count;) {
-		if (bboxes[i]->glob == NULL)
+		if (*bboxes[i]->name == '-')
+			dest = neg_boxes;
+		else if (bboxes[i]->glob != NULL)
+			dest = wildcard_boxes;
+		else {
+			dest = NULL;
 			i++;
-		else {
-			array_append(wildcard_boxes, &bboxes[i], 1);
+		}
+
+		if (dest != NULL) {
+			array_append(dest, &bboxes[i], 1);
 			array_delete(&mbox->backend_boxes, i, 1);
 			bboxes = array_get_modifiable(&mbox->backend_boxes,
 						      &count);
@@ -162,17 +173,45 @@ static void virtual_config_copy_expanded
 	array_append(&ctx->mbox->backend_boxes, &bbox, 1);
 }
 
+static bool virtual_config_match(const struct mailbox_info *info,
+				 ARRAY_TYPE(virtual_backend_box) *boxes_arr,
+				 unsigned int *idx_r)
+{
+	struct virtual_backend_box *const *boxes;
+	unsigned int i, count;
+
+	boxes = array_get_modifiable(boxes_arr, &count);
+	for (i = 0; i < count; i++) {
+		if (boxes[i]->glob != NULL) {
+			/* we match only one namespace for each pattern. */
+			if (boxes[i]->ns == info->ns &&
+			    imap_match(boxes[i]->glob,
+				       info->name) == IMAP_MATCH_YES) {
+				*idx_r = i;
+				return TRUE;
+			}
+		} else {
+			i_assert(boxes[i]->name[0] == '-');
+			if (strcmp(boxes[i]->name + 1, info->name) == 0) {
+				*idx_r = i;
+				return TRUE;
+			}
+		}
+	}
+	return FALSE;
+}
+
 static int virtual_config_expand_wildcards(struct virtual_parse_context *ctx)
 {
 	struct mail_user *user = ctx->mbox->storage->storage.ns->user;
-	ARRAY_TYPE(virtual_backend_box) wildcard_boxes;
+	ARRAY_TYPE(virtual_backend_box) wildcard_boxes, neg_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);
+	unsigned int i, j, count;
+
+	separate_wildcard_mailboxes(ctx->mbox, &wildcard_boxes, &neg_boxes);
 
 	/* get patterns we want to list */
 	wboxes = array_get_modifiable(&wildcard_boxes, &count);
@@ -185,17 +224,15 @@ static int virtual_config_expand_wildcar
 					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++) {
-			/* we match only one namespace for each pattern.
-			   skip non-selectable mailboxes (especially mbox
-			   directories) */
-			if (wboxes[i]->ns == info->ns &&
-			    (info->flags & MAILBOX_NOSELECT) == 0 &&
-			    imap_match(wboxes[i]->glob,
-				       info->name) == IMAP_MATCH_YES) {
-				virtual_config_copy_expanded(ctx, wboxes[i],
-							     info->name);
-			}
+		/* skip non-selectable mailboxes (especially mbox
+		   directories) */
+		if ((info->flags & MAILBOX_NOSELECT) != 0)
+			continue;
+
+		if (virtual_config_match(info, &wildcard_boxes, &i) &&
+		    !virtual_config_match(info, &neg_boxes, &j)) {
+			virtual_config_copy_expanded(ctx, wboxes[i],
+						     info->name);
 		}
 	}
 	for (i = 0; i < count; i++)


More information about the dovecot-cvs mailing list