From 50053223085da761ce3f9491f428381503ce3ec9 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Fri, 14 Nov 2014 00:59:57 -0800 Subject: [PATCH] imap: namespace { order } parameter now specifies the order returned in NAMESPACE reply. This is relevant only if there are multiple visible namespaces with the same type. The default order depends primarily on the length of the prefix because of internal sorting (the order of equal length prefixes can't really be relied on). --- src/imap/cmd-namespace.c | 79 +++++++++++++++++-------- src/lib-storage/mail-storage-settings.c | 2 + src/lib-storage/mail-storage-settings.h | 1 + 3 files changed, 57 insertions(+), 25 deletions(-) diff --git a/src/imap/cmd-namespace.c b/src/imap/cmd-namespace.c index 02af8dec58..003f2dc458 100644 --- a/src/imap/cmd-namespace.c +++ b/src/imap/cmd-namespace.c @@ -7,44 +7,73 @@ #include "imap-commands.h" #include "mail-namespace.h" +struct namespace_order { + int secondary_order; + struct mail_namespace *ns; +}; + +static int namespace_order_cmp(const struct namespace_order *no1, + const struct namespace_order *no2) +{ + if (no1->ns->set->order < no2->ns->set->order) + return -1; + if (no1->ns->set->order > no2->ns->set->order) + return 1; + + if (no1->secondary_order < no2->secondary_order) + return -1; + if (no1->secondary_order > no2->secondary_order) + return 1; + return 0; +} + static void list_namespaces(struct mail_namespace *ns, enum mail_namespace_type type, string_t *str) { - string_t *mutf7_prefix = t_str_new(64); + ARRAY(struct namespace_order) ns_order; + struct namespace_order *no; + unsigned int count = 0; + string_t *mutf7_prefix; char ns_sep; - bool found = FALSE; + + t_array_init(&ns_order, 4); while (ns != NULL) { if (ns->type == type && (ns->flags & NAMESPACE_FLAG_HIDDEN) == 0) { - if (!found) { - str_append_c(str, '('); - found = TRUE; - } - ns_sep = mail_namespace_get_sep(ns); - str_append_c(str, '('); - - str_truncate(mutf7_prefix, 0); - if (imap_utf8_to_utf7(ns->prefix, mutf7_prefix) < 0) { - i_panic("LIST: Namespace prefix not UTF-8: %s", - ns->prefix); - } - - imap_append_string(str, str_c(mutf7_prefix)); - str_append(str, " \""); - if (ns_sep == '\\') - str_append_c(str, '\\'); - str_append_c(str, ns_sep); - str_append(str, "\")"); + no = array_append_space(&ns_order); + no->ns = ns; + no->secondary_order = ++count; } - ns = ns->next; } - if (found) - str_append_c(str, ')'); - else + if (array_count(&ns_order) == 0) { str_append(str, "NIL"); + return; + } + array_sort(&ns_order, namespace_order_cmp); + + mutf7_prefix = t_str_new(64); + str_append_c(str, '('); + array_foreach_modifiable(&ns_order, no) { + ns_sep = mail_namespace_get_sep(no->ns); + str_append_c(str, '('); + + str_truncate(mutf7_prefix, 0); + if (imap_utf8_to_utf7(no->ns->prefix, mutf7_prefix) < 0) { + i_panic("LIST: Namespace prefix not UTF-8: %s", + no->ns->prefix); + } + + imap_append_string(str, str_c(mutf7_prefix)); + str_append(str, " \""); + if (ns_sep == '\\') + str_append_c(str, '\\'); + str_append_c(str, ns_sep); + str_append(str, "\")"); + } + str_append_c(str, ')'); } bool cmd_namespace(struct client_command_context *cmd) diff --git a/src/lib-storage/mail-storage-settings.c b/src/lib-storage/mail-storage-settings.c index 92c39283e8..8c29f09121 100644 --- a/src/lib-storage/mail-storage-settings.c +++ b/src/lib-storage/mail-storage-settings.c @@ -171,6 +171,7 @@ static const struct setting_define mail_namespace_setting_defines[] = { DEF(SET_BOOL, subscriptions), DEF(SET_BOOL, ignore_on_failure), DEF(SET_BOOL, disabled), + DEF(SET_UINT, order), DEFLIST_UNIQUE(mailboxes, "mailbox", &mailbox_setting_parser_info), @@ -191,6 +192,7 @@ const struct mail_namespace_settings mail_namespace_default_settings = { .subscriptions = TRUE, .ignore_on_failure = FALSE, .disabled = FALSE, + .order = 0, .mailboxes = ARRAY_INIT }; diff --git a/src/lib-storage/mail-storage-settings.h b/src/lib-storage/mail-storage-settings.h index 6e25533582..f80431b0b8 100644 --- a/src/lib-storage/mail-storage-settings.h +++ b/src/lib-storage/mail-storage-settings.h @@ -62,6 +62,7 @@ struct mail_namespace_settings { bool subscriptions; bool ignore_on_failure; bool disabled; + unsigned int order; ARRAY(struct mailbox_settings *) mailboxes; struct mail_user_settings *user_set; -- 2.47.3