dovecot: Code cleanups
dovecot at dovecot.org
dovecot at dovecot.org
Wed Jun 27 16:38:21 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/6ae0dc6dc3b3
changeset: 5803:6ae0dc6dc3b3
user: Timo Sirainen <tss at iki.fi>
date: Wed Jun 27 16:10:00 2007 +0300
description:
Code cleanups
diffstat:
1 file changed, 98 insertions(+), 57 deletions(-)
src/imap/cmd-list.c | 155 ++++++++++++++++++++++++++++++++-------------------
diffs (231 lines):
diff -r 8416f66ac5ab -r 6ae0dc6dc3b3 src/imap/cmd-list.c
--- a/src/imap/cmd-list.c Wed Jun 27 15:17:58 2007 +0300
+++ b/src/imap/cmd-list.c Wed Jun 27 16:10:00 2007 +0300
@@ -225,24 +225,21 @@ skip_namespace_prefix(const char **prefi
}
}
-static void
-list_namespace_init(struct client_command_context *cmd,
- struct cmd_list_context *ctx)
-{
- struct client *client = cmd->client;
- struct mail_namespace *ns = ctx->ns;
+static bool
+skip_namespace_prefix_refmask(struct cmd_list_context *ctx,
+ const char **cur_ns_prefix_r,
+ const char **cur_ref_r, const char **cur_mask_r)
+{
const char *cur_ns_prefix, *cur_ref, *cur_mask;
- enum imap_match_result match;
- enum imap_match_result inbox_match;
- struct imap_match_glob *inbox_glob;
- unsigned int count;
- size_t len;
-
- cur_ns_prefix = ns->prefix;
+
+ if (*ctx->ns->prefix == '\0')
+ return TRUE;
+
+ cur_ns_prefix = ctx->ns->prefix;
cur_ref = ctx->ref;
cur_mask = ctx->mask;
- if (*cur_ref != '\0' && *cur_ns_prefix != '\0') {
+ if (*cur_ref != '\0') {
/* reference argument given. skip namespace prefix using it.
cur_ns_prefix = foo/bar/
@@ -251,24 +248,25 @@ list_namespace_init(struct client_comman
cur_ref = foo/bar/baz
-> cur_ns_prefix="", cur_ref="baz"
*/
- skip_namespace_prefix(&cur_ns_prefix, &cur_ref, TRUE, ns->sep);
+ skip_namespace_prefix(&cur_ns_prefix, &cur_ref, TRUE,
+ ctx->ns->sep);
if (*cur_ref != '\0' && *cur_ns_prefix != '\0') {
/* reference parameter didn't match with
namespace prefix. skip this. */
- return;
+ return FALSE;
}
}
if (*cur_ns_prefix != '\0') {
- /* no reference parameter. skip namespace prefix from mask. */
+ /* skip namespace prefix using mask */
const char *old_ns_prefix = cur_ns_prefix;
const char *old_mask = cur_mask;
i_assert(*cur_ref == '\0');
skip_namespace_prefix(&cur_ns_prefix, &cur_mask,
- cur_ref == ctx->ref, ns->sep);
+ cur_ref == ctx->ref, ctx->ns->sep);
if (*cur_mask == '\0' && *cur_ns_prefix == '\0') {
/* trying to list the namespace prefix itself. */
@@ -277,20 +275,86 @@ list_namespace_init(struct client_comman
}
}
+ *cur_ns_prefix_r = cur_ns_prefix;
+ *cur_ref_r = cur_ref;
+ *cur_mask_r = cur_mask;
+ return TRUE;
+}
+
+static enum imap_match_result
+list_use_inboxcase(struct client_command_context *cmd,
+ struct cmd_list_context *ctx)
+{
+ struct imap_match_glob *inbox_glob;
+
+ if (*ctx->ns->prefix != '\0' && !ctx->ns->inbox)
+ return IMAP_MATCH_NO;
+
/* if the original reference and mask combined produces something
that matches INBOX, the INBOX casing is on. */
inbox_glob = imap_match_init(cmd->pool,
t_strconcat(ctx->ref, ctx->mask, NULL),
- TRUE, ns->sep);
- inbox_match = *ns->prefix == '\0' || ns->inbox ?
- imap_match(inbox_glob, "INBOX") : FALSE;
+ TRUE, ctx->ns->sep);
+ return imap_match(inbox_glob, "INBOX");
+}
+
+static void
+skip_mask_wildcard_prefix(const char *cur_ns_prefix, char sep,
+ const char **cur_mask_p)
+{
+ const char *cur_mask = *cur_mask_p;
+ unsigned int count;
+
+ for (count = 1; *cur_ns_prefix != '\0'; cur_ns_prefix++) {
+ if (*cur_ns_prefix == sep)
+ count++;
+ }
+
+ for (; count > 0; count--) {
+ /* skip over one hierarchy */
+ while (*cur_mask != '\0' && *cur_mask != '*' &&
+ *cur_mask != sep)
+ cur_mask++;
+
+ if (*cur_mask == '*') {
+ /* we'll just request "*" and filter it
+ ourself. otherwise this gets too complex. */
+ cur_mask = "*";
+ break;
+ }
+ if (*cur_mask == '\0') {
+ /* mask ended too early. we won't be listing
+ any mailboxes. */
+ break;
+ }
+ cur_mask++;
+ }
+
+ *cur_mask_p = cur_mask;
+}
+
+static void
+list_namespace_init(struct client_command_context *cmd,
+ struct cmd_list_context *ctx)
+{
+ struct client *client = cmd->client;
+ struct mail_namespace *ns = ctx->ns;
+ const char *cur_ns_prefix, *cur_ref, *cur_mask;
+ enum imap_match_result match;
+ enum imap_match_result inbox_match;
+ size_t len;
+
+ if (!skip_namespace_prefix_refmask(ctx, &cur_ns_prefix,
+ &cur_ref, &cur_mask))
+ return;
+
+ inbox_match = list_use_inboxcase(cmd, ctx);
ctx->match_inbox = inbox_match == IMAP_MATCH_YES;
ctx->glob = imap_match_init(cmd->pool, ctx->mask,
(inbox_match == IMAP_MATCH_YES ||
inbox_match == IMAP_MATCH_PARENT) &&
- cur_mask == ctx->mask,
- ns->sep);
+ cur_mask == ctx->mask, ns->sep);
if (*cur_ns_prefix != '\0') {
/* namespace prefix still wasn't completely skipped over.
@@ -300,7 +364,8 @@ list_namespace_init(struct client_comman
i_assert(*cur_ref == '\0');
/* drop the trailing separator in namespace prefix.
- don't do it if we're listing only the prefix itself. */
+ don't do it if we're listing only the prefix itself
+ (LIST "" foo/ needs to return "foo/" entry) */
len = strlen(cur_ns_prefix);
if (cur_ns_prefix[len-1] == ns->sep &&
strcmp(cur_mask, cur_ns_prefix) != 0) {
@@ -319,9 +384,10 @@ list_namespace_init(struct client_comman
len = strlen(ns->prefix);
if (match == IMAP_MATCH_YES && ctx->ns->list_prefix &&
(ctx->list_flags & MAILBOX_LIST_ITER_SUBSCRIBED) == 0 &&
- (!ctx->ns->inbox ||
+ (!ctx->match_inbox ||
strncmp(ns->prefix, "INBOX", len-1) != 0)) {
- /* The prefix itself matches */
+ /* The prefix itself matches. Because we want to know
+ INBOX flags, it's handled elsewhere. */
enum mailbox_info_flags flags;
string_t *str = t_str_new(128);
@@ -343,40 +409,15 @@ list_namespace_init(struct client_comman
We have already verified that the mask matches the namespace
prefix, so we'll just have to skip over as many hierarchies
- from mask as there exists in namespace prefix.
-
- The "INBOX" namespace match reply was already sent. We're
- only listing the actual mailboxes now. */
+ from mask as there exists in namespace prefix. */
i_assert(*cur_ref == '\0');
-
- for (count = 1; *cur_ns_prefix != '\0'; cur_ns_prefix++) {
- if (*cur_ns_prefix == ns->sep)
- count++;
- }
-
- for (; count > 0; count--) {
- /* skip over one hierarchy */
- while (*cur_mask != '\0' && *cur_mask != '*' &&
- *cur_mask != ns->sep)
- cur_mask++;
-
- if (*cur_mask == '*') {
- /* we'll just request "*" and filter it
- ourself. otherwise this gets too complex. */
- cur_mask = "*";
- break;
- }
- if (*cur_mask == '\0') {
- /* mask ended too early. we won't be listing
- any mailboxes. */
- break;
- }
- cur_mask++;
- }
+ skip_mask_wildcard_prefix(cur_ns_prefix, ns->sep, &cur_mask);
if (*cur_mask == '\0' && ctx->match_inbox) {
- /* oh what a horrible hack. ns_prefix="INBOX/" and
- we wanted to list "%". INBOX should match. */
+ /* oh what a horrible hack. ns_prefix="INBOX/" and we
+ wanted to list "%". INBOX should match and we want
+ to know its flags. for non-INBOX prefixes this is
+ handled elsewhere because it doesn't need flags. */
cur_mask = "INBOX";
}
}
More information about the dovecot-cvs
mailing list