bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2008-2018 Dovecot authors, see the included COPYING file */
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch#include "lib.h"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch#include "imap-match.h"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch#include "mailbox-tree.h"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch#include "mailbox-list-private.h"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch#include "index-storage.h"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch#include "shared-storage.h"
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschextern struct mailbox_list shared_mailbox_list;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstatic struct mailbox_list *shared_list_alloc(void)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch{
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct mailbox_list *list;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch pool_t pool;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch pool = pool_alloconly_create("shared list", 2048);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch list = p_new(pool, struct mailbox_list, 1);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch *list = shared_mailbox_list;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch list->pool = pool;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch return list;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch}
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstatic void shared_list_deinit(struct mailbox_list *list)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch{
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch pool_unref(&list->pool);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch}
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstatic void shared_list_copy_error(struct mailbox_list *shared_list,
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct mail_namespace *backend_ns)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch{
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch const char *str;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch enum mail_error error;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch str = mailbox_list_get_last_error(backend_ns->list, &error);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch mailbox_list_set_error(shared_list, error, str);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch}
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstatic int
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschshared_get_storage(struct mailbox_list **list, const char *vname,
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct mail_storage **storage_r)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch{
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct mail_namespace *ns = (*list)->ns;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch const char *name;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch name = mailbox_list_get_storage_name(*list, vname);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch if (*name == '\0' && (ns->flags & NAMESPACE_FLAG_AUTOCREATED) == 0) {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch /* trying to access the shared/ prefix itself */
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch *storage_r = ns->storage;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch return 0;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch }
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch if (shared_storage_get_namespace(&ns, &name) < 0)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch return -1;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch *list = ns->list;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch return mailbox_list_get_storage(list, vname, storage_r);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch}
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstatic char shared_list_get_hierarchy_sep(struct mailbox_list *list ATTR_UNUSED)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch{
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch return '/';
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch}
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstatic int
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschshared_list_get_path(struct mailbox_list *list, const char *name,
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch enum mailbox_list_path_type type, const char **path_r)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch{
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct mail_namespace *ns = list->ns;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch if (mail_namespace_get_default_storage(list->ns) == NULL ||
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch name == NULL ||
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch shared_storage_get_namespace(&ns, &name) < 0) {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch /* we don't have a directory we can use. */
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch *path_r = NULL;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch return 0;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch }
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch return mailbox_list_get_path(ns->list, name, type, path_r);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch}
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstatic const char *
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschshared_list_get_temp_prefix(struct mailbox_list *list, bool global ATTR_UNUSED)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch{
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch i_panic("shared mailbox list: Can't return a temp prefix for '%s'",
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch list->ns->prefix);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch}
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstatic const char *
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschshared_list_join_refpattern(struct mailbox_list *list,
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch const char *ref, const char *pattern)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch{
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct mail_namespace *ns = list->ns;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch const char *ns_ref, *prefix = list->ns->prefix;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch size_t prefix_len = strlen(prefix);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch if (*ref != '\0' && strncmp(ref, prefix, prefix_len) == 0)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch ns_ref = ref + prefix_len;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch else
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch ns_ref = NULL;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch if (ns_ref != NULL && *ns_ref != '\0' &&
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch shared_storage_get_namespace(&ns, &ns_ref) == 0)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch return mailbox_list_join_refpattern(ns->list, ref, pattern);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch /* fallback to default behavior */
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch if (*ref != '\0')
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch pattern = t_strconcat(ref, pattern, NULL);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch return pattern;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch}
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstatic void
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschshared_list_create_missing_namespaces(struct mailbox_list *list,
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch const char *const *patterns)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch{
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct mail_namespace *ns;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch char sep = mail_namespace_get_sep(list->ns);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch const char *list_pat, *name;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch unsigned int i;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch for (i = 0; patterns[i] != NULL; i++) {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch const char *last = NULL, *p;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch /* we'll require that the pattern begins with the list's
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch namespace prefix. we could also handle other patterns
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch (e.g. %/user/%), but it's more of a theoretical problem. */
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch if (strncmp(list->ns->prefix, patterns[i],
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch list->ns->prefix_len) != 0)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch continue;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch list_pat = patterns[i] + list->ns->prefix_len;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch for (p = list_pat; *p != '\0'; p++) {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch if (*p == '%' || *p == '*')
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch break;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch if (*p == sep)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch last = p;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch }
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch if (last != NULL) {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch ns = list->ns;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch name = t_strdup_until(list_pat, last);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch (void)shared_storage_get_namespace(&ns, &name);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch }
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch }
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch}
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstatic struct mailbox_list_iterate_context *
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschshared_list_iter_init(struct mailbox_list *list, const char *const *patterns,
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch enum mailbox_list_iter_flags flags)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch{
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct mailbox_list_iterate_context *ctx;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch pool_t pool;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch char sep = mail_namespace_get_sep(list->ns);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch pool = pool_alloconly_create("mailbox list shared iter", 1024);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch ctx = p_new(pool, struct mailbox_list_iterate_context, 1);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch ctx->pool = pool;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch ctx->list = list;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch ctx->flags = flags;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch ctx->glob = imap_match_init_multiple(pool, patterns, FALSE, sep);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch array_create(&ctx->module_contexts, pool, sizeof(void *), 5);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch if ((flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) == 0 &&
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch (list->ns->flags & NAMESPACE_FLAG_AUTOCREATED) == 0) T_BEGIN {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch shared_list_create_missing_namespaces(list, patterns);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch } T_END;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch return ctx;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch}
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstatic const struct mailbox_info *
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschshared_list_iter_next(struct mailbox_list_iterate_context *ctx ATTR_UNUSED)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch{
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch return NULL;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch}
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstatic int shared_list_iter_deinit(struct mailbox_list_iterate_context *ctx)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch{
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch pool_unref(&ctx->pool);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch return 0;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch}
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstatic int
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschshared_list_subscriptions_refresh(struct mailbox_list *src_list,
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct mailbox_list *dest_list)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch{
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch char sep;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch if (dest_list->subscriptions == NULL) {
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch sep = mail_namespace_get_sep(src_list->ns);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch dest_list->subscriptions = mailbox_tree_init(sep);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch }
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch return 0;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch}
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Boschstatic int shared_list_set_subscribed(struct mailbox_list *list,
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch const char *name, bool set)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch{
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch struct mail_namespace *ns = list->ns;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch int ret;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch if (shared_storage_get_namespace(&ns, &name) < 0)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch return -1;
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch ret = mailbox_list_set_subscribed(ns->list, name, set);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch if (ret < 0)
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch shared_list_copy_error(list, ns);
30116399ebac74cf4ea0daefb65c9fba742e0773Stephan Bosch return ret;
}
static int
shared_list_delete_mailbox(struct mailbox_list *list, const char *name)
{
struct mail_namespace *ns = list->ns;
int ret;
if (shared_storage_get_namespace(&ns, &name) < 0)
return -1;
ret = ns->list->v.delete_mailbox(ns->list, name);
if (ret < 0)
shared_list_copy_error(list, ns);
return ret;
}
static int
shared_list_delete_dir(struct mailbox_list *list, const char *name)
{
struct mail_namespace *ns = list->ns;
int ret;
if (shared_storage_get_namespace(&ns, &name) < 0)
return -1;
ret = mailbox_list_delete_dir(ns->list, name);
if (ret < 0)
shared_list_copy_error(list, ns);
return ret;
}
static int
shared_list_delete_symlink(struct mailbox_list *list, const char *name)
{
struct mail_namespace *ns = list->ns;
int ret;
if (shared_storage_get_namespace(&ns, &name) < 0)
return -1;
ret = mailbox_list_delete_symlink(ns->list, name);
if (ret < 0)
shared_list_copy_error(list, ns);
return ret;
}
static int shared_list_rename_get_ns(struct mailbox_list *oldlist,
const char **oldname,
struct mailbox_list *newlist,
const char **newname,
struct mail_namespace **ns_r)
{
struct mail_namespace *old_ns = oldlist->ns, *new_ns = newlist->ns;
if (shared_storage_get_namespace(&old_ns, oldname) < 0 ||
shared_storage_get_namespace(&new_ns, newname) < 0)
return -1;
if (old_ns != new_ns) {
mailbox_list_set_error(oldlist, MAIL_ERROR_NOTPOSSIBLE,
"Can't rename shared mailboxes across storages.");
return -1;
}
*ns_r = old_ns;
return 0;
}
static int
shared_list_rename_mailbox(struct mailbox_list *oldlist, const char *oldname,
struct mailbox_list *newlist, const char *newname)
{
struct mail_namespace *ns;
int ret;
if (shared_list_rename_get_ns(oldlist, &oldname,
newlist, &newname, &ns) < 0)
return -1;
ret = ns->list->v.rename_mailbox(ns->list, oldname, ns->list, newname);
if (ret < 0)
shared_list_copy_error(oldlist, ns);
return ret;
}
struct mailbox_list shared_mailbox_list = {
.name = "shared",
.props = 0,
.mailbox_name_max_length = MAILBOX_LIST_NAME_MAX_LENGTH,
.v = {
.alloc = shared_list_alloc,
.deinit = shared_list_deinit,
.get_storage = shared_get_storage,
.get_hierarchy_sep = shared_list_get_hierarchy_sep,
.get_vname = mailbox_list_default_get_vname,
.get_storage_name = mailbox_list_default_get_storage_name,
.get_path = shared_list_get_path,
.get_temp_prefix = shared_list_get_temp_prefix,
.join_refpattern = shared_list_join_refpattern,
.iter_init = shared_list_iter_init,
.iter_next = shared_list_iter_next,
.iter_deinit = shared_list_iter_deinit,
.subscriptions_refresh = shared_list_subscriptions_refresh,
.set_subscribed = shared_list_set_subscribed,
.delete_mailbox = shared_list_delete_mailbox,
.delete_dir = shared_list_delete_dir,
.delete_symlink = shared_list_delete_symlink,
.rename_mailbox = shared_list_rename_mailbox,
}
};