dovecot: Fixes to returning mailboxes
dovecot at dovecot.org
dovecot at dovecot.org
Sun Jul 15 06:46:05 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/ed6c07975ccb
changeset: 6010:ed6c07975ccb
user: Timo Sirainen <tss at iki.fi>
date: Sun Jul 15 06:46:00 2007 +0300
description:
Fixes to returning mailboxes
diffstat:
2 files changed, 167 insertions(+), 158 deletions(-)
src/lib-storage/list/mailbox-list-maildir-iter.c | 195 +++++++++++----------
src/lib-storage/list/mailbox-list-subscriptions.c | 130 ++++++--------
diffs (truncated from 385 to 300 lines):
diff -r 62f92a68fc72 -r ed6c07975ccb src/lib-storage/list/mailbox-list-maildir-iter.c
--- a/src/lib-storage/list/mailbox-list-maildir-iter.c Sun Jul 15 06:45:36 2007 +0300
+++ b/src/lib-storage/list/mailbox-list-maildir-iter.c Sun Jul 15 06:46:00 2007 +0300
@@ -22,81 +22,37 @@ struct maildir_list_iterate_context {
struct mailbox_info info;
};
-static int
-maildir_fill_readdir(struct maildir_list_iterate_context *ctx,
- struct imap_match_glob *glob, bool update_only)
-{
- DIR *dirp;
- struct dirent *d;
- const char *p, *mailbox_c;
- string_t *mailbox;
- enum mailbox_info_flags flags;
- enum imap_match_result match;
- struct mailbox_node *node;
+static void node_fix_parents(struct mailbox_node *node)
+{
+ /* Fix parent nodes' children states. also if we happened to create any
+ of the parents, we need to mark them nonexistent. */
+ node = node->parent;
+ for (; node != NULL; node = node->parent) {
+ if ((node->flags & MAILBOX_MATCHED) == 0)
+ node->flags |= MAILBOX_NONEXISTENT;
+
+ node->flags |= MAILBOX_CHILDREN;
+ node->flags &= ~MAILBOX_NOCHILDREN;
+ }
+}
+
+static void maildir_fill_parents(struct maildir_list_iterate_context *ctx,
+ struct imap_match_glob *glob, bool update_only,
+ string_t *mailbox, const char *mailbox_c,
+ enum mailbox_info_flags flags)
+{
+ struct mailbox_node *node;
+ const char *p;
+ char hierarchy_sep;
bool created;
- char hierarchy_sep;
- int ret;
-
- dirp = opendir(ctx->dir);
- if (dirp == NULL) {
- if (errno != ENOENT) {
- mailbox_list_set_critical(ctx->ctx.list,
- "opendir(%s) failed: %m", ctx->dir);
- return -1;
- }
- return 0;
- }
hierarchy_sep = ctx->ctx.list->hierarchy_sep;
t_push();
- mailbox = t_str_new(PATH_MAX);
- while ((d = readdir(dirp)) != NULL) {
- const char *fname = d->d_name;
-
- if (fname[0] != hierarchy_sep)
- continue;
-
- /* skip . and .. */
- if (fname[0] == '.' &&
- (fname[1] == '\0' || (fname[1] == '.' && fname[2] == '\0')))
- continue;
-
- /* make sure the pattern matches */
- str_truncate(mailbox, 0);
- str_append(mailbox, ctx->prefix);
- str_append(mailbox, fname + 1);
- mailbox_c = str_c(mailbox);
-
- match = imap_match(glob, mailbox_c);
- if ((match & (IMAP_MATCH_YES | IMAP_MATCH_PARENT)) == 0)
- continue;
-
- /* check if this is an actual mailbox */
- flags = 0;
- ret = ctx->ctx.list->v.
- iter_is_mailbox(&ctx->ctx, ctx->dir, fname,
- mailbox_list_get_file_type(d), &flags);
- if (ret < 0) {
- t_pop();
- return -1;
- }
- if (ret == 0)
- continue;
-
- if ((match & IMAP_MATCH_PARENT) != 0) {
- /* get the name of the parent mailbox that matches */
- t_push();
- while ((p = strrchr(mailbox_c,
- hierarchy_sep)) != NULL) {
- str_truncate(mailbox, (size_t) (p-mailbox_c));
- mailbox_c = str_c(mailbox);
- if (imap_match(glob, mailbox_c) ==
- IMAP_MATCH_YES)
- break;
- }
- i_assert(p != NULL);
-
+ while ((p = strrchr(mailbox_c, hierarchy_sep)) != NULL) {
+ str_truncate(mailbox, (size_t) (p-mailbox_c));
+ mailbox_c = str_c(mailbox);
+ if (imap_match(glob, mailbox_c) == IMAP_MATCH_YES) {
created = FALSE;
node = update_only ?
mailbox_tree_lookup(ctx->tree_ctx, mailbox_c) :
@@ -110,11 +66,85 @@ maildir_fill_readdir(struct maildir_list
}
if (!update_only)
node->flags |= MAILBOX_MATCHED;
- node->flags |= MAILBOX_CHILDREN;
+ node->flags |= MAILBOX_CHILDREN | flags;
node->flags &= ~MAILBOX_NOCHILDREN;
+ node_fix_parents(node);
}
-
+ }
+ }
+ t_pop();
+}
+
+static int
+maildir_fill_readdir(struct maildir_list_iterate_context *ctx,
+ struct imap_match_glob *glob, bool update_only)
+{
+ DIR *dirp;
+ struct dirent *d;
+ const char *mailbox_c;
+ string_t *mailbox;
+ enum mailbox_info_flags flags;
+ enum imap_match_result match;
+ struct mailbox_node *node;
+ bool created;
+ char hierarchy_sep;
+ int ret;
+
+ dirp = opendir(ctx->dir);
+ if (dirp == NULL) {
+ if (errno != ENOENT) {
+ mailbox_list_set_critical(ctx->ctx.list,
+ "opendir(%s) failed: %m", ctx->dir);
+ return -1;
+ }
+ return 0;
+ }
+
+ hierarchy_sep = ctx->ctx.list->hierarchy_sep;
+
+ t_push();
+ mailbox = t_str_new(PATH_MAX);
+ while ((d = readdir(dirp)) != NULL) {
+ const char *fname = d->d_name;
+
+ if (fname[0] != hierarchy_sep)
+ continue;
+
+ /* skip . and .. */
+ if (fname[0] == '.' &&
+ (fname[1] == '\0' || (fname[1] == '.' && fname[2] == '\0')))
+ continue;
+
+ /* make sure the pattern matches */
+ str_truncate(mailbox, 0);
+ str_append(mailbox, ctx->prefix);
+ str_append(mailbox, fname + 1);
+ mailbox_c = str_c(mailbox);
+
+ match = imap_match(glob, mailbox_c);
+ if ((match & (IMAP_MATCH_YES | IMAP_MATCH_PARENT)) == 0)
+ continue;
+
+ /* check if this is an actual mailbox */
+ flags = 0;
+ ret = ctx->ctx.list->v.
+ iter_is_mailbox(&ctx->ctx, ctx->dir, fname,
+ mailbox_list_get_file_type(d), &flags);
+ if (ret < 0) {
t_pop();
+ return -1;
+ }
+ if (ret == 0)
+ continue;
+
+ /* we know the children flags ourself, so ignore if any of
+ them were set. */
+ flags &= ~(MAILBOX_NOINFERIORS |
+ MAILBOX_CHILDREN | MAILBOX_NOCHILDREN);
+
+ if ((match & IMAP_MATCH_PARENT) != 0) {
+ maildir_fill_parents(ctx, glob, update_only,
+ mailbox, mailbox_c, flags);
} else {
created = FALSE;
node = update_only ?
@@ -129,25 +159,8 @@ maildir_fill_readdir(struct maildir_list
node->flags &= ~MAILBOX_NONEXISTENT;
if (!update_only)
node->flags |= MAILBOX_MATCHED;
- }
- }
- if (node != NULL) {
- /* apply flags given by storage. we know the children
- flags ourself, so ignore if any of them were set. */
- node->flags |= flags & ~(MAILBOX_NOINFERIORS |
- MAILBOX_CHILDREN |
- MAILBOX_NOCHILDREN);
-
- /* Fix parent nodes' children states. also if we
- happened to create any of the parents, we need to
- mark them nonexistent. */
- node = node->parent;
- for (; node != NULL; node = node->parent) {
- if ((node->flags & MAILBOX_MATCHED) == 0)
- node->flags |= MAILBOX_NONEXISTENT;
-
- node->flags |= MAILBOX_CHILDREN;
- node->flags &= ~MAILBOX_NOCHILDREN;
+ node->flags |= flags;
+ node_fix_parents(node);
}
}
}
diff -r 62f92a68fc72 -r ed6c07975ccb src/lib-storage/list/mailbox-list-subscriptions.c
--- a/src/lib-storage/list/mailbox-list-subscriptions.c Sun Jul 15 06:45:36 2007 +0300
+++ b/src/lib-storage/list/mailbox-list-subscriptions.c Sun Jul 15 06:46:00 2007 +0300
@@ -7,15 +7,68 @@
#include "mailbox-list-private.h"
#include "mailbox-list-subscriptions.h"
-static void nodes_add_child_subscribed(struct mailbox_node *node)
+static void node_fix_parents(struct mailbox_node *node)
{
- while (node != NULL) {
- if (node->children != NULL) {
- node->flags |= MAILBOX_MATCHED |
- MAILBOX_CHILD_SUBSCRIBED;
- }
- node = node->next;
+ /* If we happened to create any of the parents, we need to mark them
+ nonexistent. */
+ node = node->parent;
+ for (; node != NULL; node = node->parent) {
+ if ((node->flags & MAILBOX_MATCHED) == 0)
+ node->flags |= MAILBOX_NONEXISTENT;
}
+}
+
+static void
+mailbox_list_subscription_add(struct mailbox_list_iterate_context *ctx,
+ struct mailbox_tree_context *tree_ctx,
+ struct imap_match_glob *glob,
+ bool update_only, const char *name)
+{
+ struct mailbox_node *node;
+ enum mailbox_info_flags create_flags, always_flags;
+ enum imap_match_result match;
+ const char *p;
+ bool created;
+
+ create_flags = (update_only ||
+ (ctx->flags & MAILBOX_LIST_ITER_RETURN_NO_FLAGS) == 0) ?
+ (MAILBOX_NONEXISTENT | MAILBOX_NOCHILDREN) : 0;
+ always_flags = MAILBOX_SUBSCRIBED;
+
+ t_push();
+ for (;;) {
+ created = FALSE;
+ match = imap_match(glob, name);
+ if (match == IMAP_MATCH_YES) {
+ node = update_only ?
+ mailbox_tree_lookup(tree_ctx, name) :
+ mailbox_tree_get(tree_ctx, name, &created);
+ if (created) {
+ node->flags = create_flags;
+ if (create_flags != 0)
+ node_fix_parents(node);
+ }
+ if (node != NULL) {
+ if (!update_only)
+ node->flags |= MAILBOX_MATCHED;
+ node->flags |= always_flags;
+ }
+ } else if ((match & IMAP_MATCH_PARENT) == 0)
+ break;
+
+ if ((ctx->flags & MAILBOX_LIST_ITER_SELECT_RECURSIVEMATCH) == 0)
+ break;
+
+ /* see if parent matches */
+ p = strrchr(name, ctx->list->hierarchy_sep);
+ if (p == NULL)
+ break;
+
+ name = t_strdup_until(name, p);
+ create_flags &= ~MAILBOX_NOCHILDREN;
More information about the dovecot-cvs
mailing list