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