Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8291:4296aa3fbb75 HEAD
Subscription handling fixes for subscriptions=no namespaces and shared mailboxes.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 18 Oct 2008 17:07:42 +0300 |
parents | 4402563ad86e |
children | 9ed4ecd4a866 |
files | src/imap/cmd-subscribe.c src/lib-storage/index/shared/shared-storage.c src/lib-storage/list/mailbox-list-subscriptions.c src/lib-storage/mail-namespace.c src/lib-storage/mail-namespace.h |
diffstat | 5 files changed, 61 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/src/imap/cmd-subscribe.c Sat Oct 18 16:26:04 2008 +0300 +++ b/src/imap/cmd-subscribe.c Sat Oct 18 17:07:42 2008 +0300 @@ -27,21 +27,38 @@ bool cmd_subscribe_full(struct client_command_context *cmd, bool subscribe) { - struct mail_namespace *ns; - const char *mailbox, *verify_name; + struct mail_namespace *ns, *real_ns; + struct mail_storage *storage; + const char *mailbox, *verify_name, *real_name; /* <mailbox> */ if (!client_read_string_args(cmd, 1, &mailbox)) return FALSE; + verify_name = mailbox; - verify_name = mailbox; + real_name = mailbox; + storage = client_find_storage(cmd, &real_name); + if (storage == NULL) + return TRUE; + + /* now find a namespace where the subscription can be added to */ ns = mail_namespace_find_subscribable(cmd->client->user->namespaces, &mailbox); if (ns == NULL) { - client_send_tagline(cmd, "NO Unknown namespace."); + client_send_tagline(cmd, "NO Unknown subscription namespace."); return TRUE; } + real_ns = mail_storage_get_namespace(storage); + if (ns != real_ns) { + /* subscription is being written to a different namespace + than where the mailbox exists. */ + mailbox = t_strconcat(real_ns->prefix, real_name, NULL); + /* drop the common prefix */ + i_assert(strncmp(ns->prefix, mailbox, strlen(ns->prefix)) == 0); + mailbox += strlen(ns->prefix); + } + if ((client_workarounds & WORKAROUND_TB_EXTRA_MAILBOX_SEP) != 0 && *mailbox != '\0' && mailbox[strlen(mailbox)-1] == mail_storage_get_hierarchy_sep(ns->storage)) {
--- a/src/lib-storage/index/shared/shared-storage.c Sat Oct 18 16:26:04 2008 +0300 +++ b/src/lib-storage/index/shared/shared-storage.c Sat Oct 18 17:07:42 2008 +0300 @@ -181,7 +181,8 @@ ns->type = NAMESPACE_SHARED; ns->user = user; ns->prefix = p_strdup(user->pool, str_c(prefix)); - ns->flags = NAMESPACE_FLAG_LIST | NAMESPACE_FLAG_HIDDEN; + ns->flags = NAMESPACE_FLAG_LIST | NAMESPACE_FLAG_HIDDEN | + NAMESPACE_FLAG_AUTOCREATED; ns->sep = _storage->ns->sep; location = t_str_new(256);
--- a/src/lib-storage/list/mailbox-list-subscriptions.c Sat Oct 18 16:26:04 2008 +0300 +++ b/src/lib-storage/list/mailbox-list-subscriptions.c Sat Oct 18 17:07:42 2008 +0300 @@ -12,10 +12,12 @@ struct imap_match_glob *glob, bool update_only) { - struct mail_namespace *ns = ctx->list->ns; + struct mail_namespace *default_ns = ctx->list->ns; + struct mail_namespace *namespaces = default_ns->user->namespaces; struct mailbox_list_iter_update_context update_ctx; struct subsfile_list_context *subsfile_ctx; - const char *path, *name; + struct mail_namespace *ns; + const char *path, *name, *name2, *full_name; string_t *vname; vname = t_str_new(256); @@ -35,10 +37,26 @@ update_ctx.match_parents = (ctx->flags & MAILBOX_LIST_ITER_SELECT_RECURSIVEMATCH) != 0; - while ((name = subsfile_list_next(subsfile_ctx)) != NULL) { + while ((name = subsfile_list_next(subsfile_ctx)) != NULL) T_BEGIN { + full_name = name2 = + t_strconcat(default_ns->prefix, name, NULL); + ns = mail_namespace_find_unsubscribable(namespaces, &name2); + if (ns == NULL) + ns = default_ns; + else if (ns->type == NAMESPACE_SHARED && + (ns->flags & NAMESPACE_FLAG_AUTOCREATED) == 0) { + /* we'll need to get the namespace autocreated. */ + (void)mailbox_list_is_valid_existing_name(ns->list, + name2); + name = full_name; + ns = mail_namespace_find_unsubscribable(namespaces, + &name); + } else { + name = name2; + } name = mail_namespace_get_vname(ns, vname, name); mailbox_list_iter_update(&update_ctx, name); - } + } T_END; return subsfile_list_deinit(subsfile_ctx); }
--- a/src/lib-storage/mail-namespace.c Sat Oct 18 16:26:04 2008 +0300 +++ b/src/lib-storage/mail-namespace.c Sat Oct 18 17:07:42 2008 +0300 @@ -382,7 +382,15 @@ { return mail_namespace_find_mask(namespaces, mailbox, NAMESPACE_FLAG_SUBSCRIPTIONS, - NAMESPACE_FLAG_SUBSCRIPTIONS); + NAMESPACE_FLAG_SUBSCRIPTIONS); +} + +struct mail_namespace * +mail_namespace_find_unsubscribable(struct mail_namespace *namespaces, + const char **mailbox) +{ + return mail_namespace_find_mask(namespaces, mailbox, + 0, NAMESPACE_FLAG_SUBSCRIPTIONS); } struct mail_namespace *
--- a/src/lib-storage/mail-namespace.h Sat Oct 18 16:26:04 2008 +0300 +++ b/src/lib-storage/mail-namespace.h Sat Oct 18 17:07:42 2008 +0300 @@ -20,7 +20,9 @@ NAMESPACE_FLAG_SUBSCRIPTIONS = 0x10, /* Namespace is created for internal use only. */ - NAMESPACE_FLAG_INTERNAL = 0x1000 + NAMESPACE_FLAG_INTERNAL = 0x1000, + /* Namespace was created automatically (for shared mailboxes) */ + NAMESPACE_FLAG_AUTOCREATED = 0x2000 }; struct mail_namespace { @@ -71,6 +73,10 @@ struct mail_namespace * mail_namespace_find_subscribable(struct mail_namespace *namespaces, const char **mailbox); +/* Like above, but find only from namespaces with subscriptions flag not set. */ +struct mail_namespace * +mail_namespace_find_unsubscribable(struct mail_namespace *namespaces, + const char **mailbox); /* Returns the INBOX namespace */ struct mail_namespace * mail_namespace_find_inbox(struct mail_namespace *namespaces);