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