1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
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;
}
|