diff options
Diffstat (limited to 'src/imap/cmd-namespace.c')
-rw-r--r-- | src/imap/cmd-namespace.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/imap/cmd-namespace.c b/src/imap/cmd-namespace.c new file mode 100644 index 0000000..23d2286 --- /dev/null +++ b/src/imap/cmd-namespace.c @@ -0,0 +1,99 @@ +/* Copyright (c) 2003-2018 Dovecot authors, see the included COPYING file */ + +#include "imap-common.h" +#include "str.h" +#include "imap-utf7.h" +#include "imap-quote.h" +#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) +{ + ARRAY(struct namespace_order) ns_order; + struct namespace_order *no; + unsigned int count = 0; + string_t *mutf7_prefix; + char ns_sep; + + t_array_init(&ns_order, 4); + + while (ns != NULL) { + if (ns->type == type && + (ns->flags & NAMESPACE_FLAG_HIDDEN) == 0) { + no = array_append_space(&ns_order); + no->ns = ns; + no->secondary_order = ++count; + } + ns = ns->next; + } + + 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) +{ + struct client *client = cmd->client; + string_t *str; + + str = t_str_new(256); + str_append(str, "* NAMESPACE "); + + list_namespaces(client->user->namespaces, + MAIL_NAMESPACE_TYPE_PRIVATE, str); + str_append_c(str, ' '); + list_namespaces(client->user->namespaces, + MAIL_NAMESPACE_TYPE_SHARED, str); + str_append_c(str, ' '); + list_namespaces(client->user->namespaces, + MAIL_NAMESPACE_TYPE_PUBLIC, str); + + client_send_line(client, str_c(str)); + client_send_tagline(cmd, "OK Namespace completed."); + return TRUE; +} |