dovecot-2.2: lib-storage: Added MAILBOX_METADATA_BACKEND_NAMESPACE
dovecot at dovecot.org
dovecot at dovecot.org
Sun Sep 2 19:53:03 EEST 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/5f313144c481
changeset: 15014:5f313144c481
user: Timo Sirainen <tss at iki.fi>
date: Sun Sep 02 19:52:31 2012 +0300
description:
lib-storage: Added MAILBOX_METADATA_BACKEND_NAMESPACE
diffstat:
src/lib-storage/index/imapc/imapc-storage.c | 97 +++++++++++++++++++++++++++++
src/lib-storage/index/imapc/imapc-storage.h | 9 ++
src/lib-storage/index/index-status.c | 7 +-
src/lib-storage/mail-storage.h | 9 ++-
4 files changed, 120 insertions(+), 2 deletions(-)
diffs (229 lines):
diff -r fba15565c360 -r 5f313144c481 src/lib-storage/index/imapc/imapc-storage.c
--- a/src/lib-storage/index/imapc/imapc-storage.c Sun Sep 02 19:32:55 2012 +0300
+++ b/src/lib-storage/index/imapc/imapc-storage.c Sun Sep 02 19:52:31 2012 +0300
@@ -52,6 +52,8 @@
static void imapc_untagged_status(const struct imapc_untagged_reply *reply,
struct imapc_storage *storage);
+static void imapc_untagged_namespace(const struct imapc_untagged_reply *reply,
+ struct imapc_storage *storage);
static bool
imap_resp_text_code_parse(const char *str, enum mail_error *error_r)
@@ -255,12 +257,15 @@
storage->list->storage = storage;
storage->client = imapc_client_init(&set);
+ p_array_init(&storage->remote_namespaces, _storage->pool, 4);
p_array_init(&storage->untagged_callbacks, _storage->pool, 16);
imapc_client_register_untagged(storage->client,
imapc_storage_untagged_cb, storage);
imapc_list_register_callbacks(storage->list);
imapc_storage_register_untagged(storage, "STATUS",
imapc_untagged_status);
+ imapc_storage_register_untagged(storage, "NAMESPACE",
+ imapc_untagged_namespace);
/* connect to imap server and get the hierarchy separator. */
if (imapc_storage_get_hierarchy_sep(storage, error_r) < 0) {
imapc_client_deinit(&storage->client);
@@ -600,6 +605,40 @@
}
}
+static void imapc_untagged_namespace(const struct imapc_untagged_reply *reply,
+ struct imapc_storage *storage)
+{
+ static enum mail_namespace_type ns_types[] = {
+ MAIL_NAMESPACE_TYPE_PRIVATE,
+ MAIL_NAMESPACE_TYPE_SHARED,
+ MAIL_NAMESPACE_TYPE_PUBLIC
+ };
+ struct imapc_namespace *ns;
+ const struct imap_arg *list, *list2;
+ const char *prefix, *sep;
+ unsigned int i;
+
+ array_clear(&storage->remote_namespaces);
+ for (i = 0; i < N_ELEMENTS(ns_types); i++) {
+ if (reply->args[i].type == IMAP_ARG_NIL)
+ continue;
+ if (!imap_arg_get_list(&reply->args[i], &list))
+ break;
+
+ for (; list->type != IMAP_ARG_EOL; list++) {
+ if (!imap_arg_get_list(list, &list2) ||
+ !imap_arg_get_astring(&list2[0], &prefix) ||
+ !imap_arg_get_nstring(&list2[1], &sep))
+ break;
+
+ ns = array_append_space(&storage->remote_namespaces);
+ ns->prefix = p_strdup(storage->storage.pool, prefix);
+ ns->separator = sep == NULL ? '\0' : sep[0];
+ ns->type = ns_types[i];
+ }
+ }
+}
+
static void imapc_mailbox_get_selected_status(struct imapc_mailbox *mbox,
enum mailbox_status_items items,
struct mailbox_status *status_r)
@@ -664,10 +703,58 @@
return sctx.ret;
}
+static int imapc_mailbox_get_namespaces(struct imapc_storage *storage)
+{
+ enum imapc_capability capa;
+ struct imapc_command *cmd;
+ struct imapc_simple_context sctx;
+
+ if (storage->namespaces_requested)
+ return 0;
+
+ capa = imapc_client_get_capabilities(storage->client);
+ if ((capa & IMAPC_CAPABILITY_NAMESPACE) == 0) {
+ /* NAMESPACE capability not supported */
+ return 0;
+ }
+
+ imapc_simple_context_init(&sctx, storage);
+ cmd = imapc_client_cmd(storage->client,
+ imapc_simple_callback, &sctx);
+ imapc_command_send(cmd, "NAMESPACE");
+ imapc_simple_run(&sctx);
+
+ if (sctx.ret < 0)
+ return -1;
+ storage->namespaces_requested = TRUE;
+ return 0;
+}
+
+static const struct imapc_namespace *
+imapc_namespace_find_mailbox(struct imapc_storage *storage, const char *name)
+{
+ const struct imapc_namespace *ns, *best_ns = NULL;
+ unsigned int best_len = -1U, len;
+
+ array_foreach(&storage->remote_namespaces, ns) {
+ len = strlen(ns->prefix);
+ if (strncmp(ns->prefix, name, len) == 0) {
+ if (best_len > len) {
+ best_ns = ns;
+ best_len = len;
+ }
+ }
+ }
+ return best_ns;
+}
+
static int imapc_mailbox_get_metadata(struct mailbox *box,
enum mailbox_metadata_items items,
struct mailbox_metadata *metadata_r)
{
+ struct imapc_mailbox *mbox = (struct imapc_mailbox *)box;
+ const struct imapc_namespace *ns;
+
if (index_mailbox_get_metadata(box, items, metadata_r) < 0)
return -1;
if ((items & MAILBOX_METADATA_GUID) != 0) {
@@ -675,6 +762,16 @@
FIXME: if indexes are enabled, keep this there. */
mail_generate_guid_128_hash(box->name, metadata_r->guid);
}
+ if ((items & MAILBOX_METADATA_BACKEND_NAMESPACE) != 0) {
+ if (imapc_mailbox_get_namespaces(mbox->storage) < 0)
+ return -1;
+
+ ns = imapc_namespace_find_mailbox(mbox->storage, box->name);
+ if (ns != NULL) {
+ metadata_r->backend_ns_prefix = ns->prefix;
+ metadata_r->backend_ns_type = ns->type;
+ }
+ }
return 0;
}
diff -r fba15565c360 -r 5f313144c481 src/lib-storage/index/imapc/imapc-storage.h
--- a/src/lib-storage/index/imapc/imapc-storage.h Sun Sep 02 19:32:55 2012 +0300
+++ b/src/lib-storage/index/imapc/imapc-storage.h Sun Sep 02 19:52:31 2012 +0300
@@ -34,6 +34,12 @@
#define IMAPC_BOX_HAS_FEATURE(mbox, feature) \
(((mbox)->storage->set->parsed_features & feature) != 0)
+struct imapc_namespace {
+ const char *prefix;
+ char separator;
+ enum mail_namespace_type type;
+};
+
struct imapc_storage {
struct mail_storage storage;
const struct imapc_settings *set;
@@ -46,7 +52,10 @@
struct mailbox_status *cur_status;
unsigned int reopen_count;
+ ARRAY(struct imapc_namespace) remote_namespaces;
ARRAY(struct imapc_storage_event_callback) untagged_callbacks;
+
+ unsigned int namespaces_requested:1;
};
struct imapc_mail_cache {
diff -r fba15565c360 -r 5f313144c481 src/lib-storage/index/index-status.c
--- a/src/lib-storage/index/index-status.c Sun Sep 02 19:32:55 2012 +0300
+++ b/src/lib-storage/index/index-status.c Sun Sep 02 19:52:31 2012 +0300
@@ -4,8 +4,8 @@
#include "array.h"
#include "mail-cache.h"
#include "mail-search-build.h"
+#include "mail-index-modseq.h"
#include "index-storage.h"
-#include "mail-index-modseq.h"
static void
get_last_cached_seq(struct mailbox *box, uint32_t *last_cached_seq_r)
@@ -365,5 +365,10 @@
get_metadata_cache_fields(box, metadata_r);
if ((items & MAILBOX_METADATA_PRECACHE_FIELDS) != 0)
get_metadata_precache_fields(box, metadata_r);
+ if ((items & MAILBOX_METADATA_BACKEND_NAMESPACE) != 0) {
+ metadata_r->backend_ns_prefix = "";
+ metadata_r->backend_ns_type =
+ mailbox_list_get_namespace(box->list)->type;
+ }
return 0;
}
diff -r fba15565c360 -r 5f313144c481 src/lib-storage/mail-storage.h
--- a/src/lib-storage/mail-storage.h Sun Sep 02 19:32:55 2012 +0300
+++ b/src/lib-storage/mail-storage.h Sun Sep 02 19:52:31 2012 +0300
@@ -8,6 +8,7 @@
#include "guid.h"
#include "mail-types.h"
#include "mail-error.h"
+#include "mail-namespace.h"
#include "mailbox-list.h"
/* If some operation is taking long, call notify_ok every n seconds. */
@@ -81,7 +82,8 @@
MAILBOX_METADATA_GUID = 0x01,
MAILBOX_METADATA_VIRTUAL_SIZE = 0x02,
MAILBOX_METADATA_CACHE_FIELDS = 0x04,
- MAILBOX_METADATA_PRECACHE_FIELDS = 0x08
+ MAILBOX_METADATA_PRECACHE_FIELDS = 0x08,
+ MAILBOX_METADATA_BACKEND_NAMESPACE = 0x10
};
enum mailbox_search_result_flags {
@@ -245,6 +247,11 @@
const ARRAY_TYPE(mailbox_cache_field) *cache_fields;
/* Fields that should be precached */
enum mail_fetch_field precache_fields;
+ /* imapc backend returns this based on the remote NAMESPACE reply,
+ while currently other backends return "" and type the same as the
+ mailbox's real namespace type */
+ const char *backend_ns_prefix;
+ enum mail_namespace_type backend_ns_type;
};
struct mailbox_update {
More information about the dovecot-cvs
mailing list