mail-namespace.c revision 2dd39e478269d6fb0bb26d12b394aa30ee965e38
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (C) 2005-2007 Timo Sirainen */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
c977374bd4651cafc1626ebe308aa66dfd8b30e0Timo Sirainen#include "lib.h"
c977374bd4651cafc1626ebe308aa66dfd8b30e0Timo Sirainen#include "file-lock.h"
c977374bd4651cafc1626ebe308aa66dfd8b30e0Timo Sirainen#include "mail-storage.h"
c977374bd4651cafc1626ebe308aa66dfd8b30e0Timo Sirainen#include "mail-namespace.h"
65b94e73c305dcb209cf958f938b93ec061c67a9Timo Sirainen
c977374bd4651cafc1626ebe308aa66dfd8b30e0Timo Sirainen#include <stdlib.h>
65b94e73c305dcb209cf958f938b93ec061c67a9Timo Sirainen
c977374bd4651cafc1626ebe308aa66dfd8b30e0Timo Sirainenstatic void namespace_init_storage(struct mail_namespace *ns)
65b94e73c305dcb209cf958f938b93ec061c67a9Timo Sirainen{
c977374bd4651cafc1626ebe308aa66dfd8b30e0Timo Sirainen ns->list = mail_storage_get_list(ns->storage);
c977374bd4651cafc1626ebe308aa66dfd8b30e0Timo Sirainen ns->prefix_len = strlen(ns->prefix);
c977374bd4651cafc1626ebe308aa66dfd8b30e0Timo Sirainen ns->real_sep = mailbox_list_get_hierarchy_sep(ns->list);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (ns->sep == '\0')
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ns->sep = ns->real_sep;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (ns->sep == '"' || ns->sep == '\\') {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ns->sep_str[0] = '\\';
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ns->sep_str[1] = ns->sep;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen } else {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ns->sep_str[0] = ns->sep;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
9955f6cba7652469b1d600a3674e8d27dd4e61bdTimo Sirainen}
9955f6cba7652469b1d600a3674e8d27dd4e61bdTimo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic struct mail_namespace *
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainennamespace_add_env(pool_t pool, const char *data, unsigned int num,
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen const char *user, enum mail_storage_flags flags,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen enum file_lock_method lock_method)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mail_namespace *ns;
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen const char *sep, *type, *prefix, *error;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ns = p_new(pool, struct mail_namespace, 1);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen sep = getenv(t_strdup_printf("NAMESPACE_%u_SEP", num));
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen type = getenv(t_strdup_printf("NAMESPACE_%u_TYPE", num));
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen prefix = getenv(t_strdup_printf("NAMESPACE_%u_PREFIX", num));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (getenv(t_strdup_printf("NAMESPACE_%u_INBOX", num)) != NULL)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ns->flags |= NAMESPACE_FLAG_INBOX;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (getenv(t_strdup_printf("NAMESPACE_%u_HIDDEN", num)) != NULL)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ns->flags |= NAMESPACE_FLAG_HIDDEN;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen if ((ns->flags & NAMESPACE_FLAG_HIDDEN) == 0 &&
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen getenv(t_strdup_printf("NAMESPACE_%u_LIST", num)) != NULL)
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen ns->flags |= NAMESPACE_FLAG_LIST;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (type == NULL || *type == '\0' || strncmp(type, "private", 7) == 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ns->type = NAMESPACE_PRIVATE;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen else if (strncmp(type, "shared", 6) == 0)
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen ns->type = NAMESPACE_SHARED;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen else if (strncmp(type, "public", 6) == 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ns->type = NAMESPACE_PUBLIC;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen else {
461ffead9720d1e516b959d5e41f049c73d38c7cTimo Sirainen i_error("Unknown namespace type: %s", type);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return NULL;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (prefix == NULL)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen prefix = "";
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if ((flags & MAIL_STORAGE_FLAG_DEBUG) != 0) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_info("Namespace: type=%s, prefix=%s, sep=%s, "
c18ff860dc22960fd37c272d929f889c7939a2c8Timo Sirainen "inbox=%s, hidden=%s, list=%s",
73a87c2ff65c6116cde6fb158dfddb8ef7346901Timo Sirainen type == NULL ? "" : type, prefix, sep == NULL ? "" : sep,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen (ns->flags & NAMESPACE_FLAG_INBOX) ? "yes" : "no",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen (ns->flags & NAMESPACE_FLAG_HIDDEN) ? "yes" : "no",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen (ns->flags & NAMESPACE_FLAG_LIST) ? "yes" : "no");
73a87c2ff65c6116cde6fb158dfddb8ef7346901Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ns->prefix = p_strdup(pool, prefix);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (mail_storage_create(ns, NULL, data, user, flags, lock_method,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen &error) < 0) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_error("Namespace '%s': %s", ns->prefix, error);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return NULL;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (sep != NULL)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ns->sep = *sep;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen namespace_init_storage(ns);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return ns;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic bool namespaces_check(struct mail_namespace *namespaces)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mail_namespace *ns, *inbox_ns = NULL, *private_ns = NULL;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int private_ns_count = 0;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen char list_sep = '\0';
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen for (ns = namespaces; ns != NULL; ns = ns->next) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if ((ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (inbox_ns != NULL) {
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen i_error("namespace configuration error: "
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "There can be only one namespace with "
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen "inbox=yes");
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen return FALSE;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen }
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen inbox_ns = ns;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (ns->type == NAMESPACE_PRIVATE) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen private_ns = ns;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen private_ns_count++;
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (*ns->prefix != '\0' &&
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen (ns->flags & NAMESPACE_FLAG_LIST) != 0 &&
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen ns->prefix[strlen(ns->prefix)-1] != ns->sep) {
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen i_error("namespace configuration error: "
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "list=yes requires prefix=%s "
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "to end with separator", ns->prefix);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return FALSE;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen if ((ns->flags & NAMESPACE_FLAG_LIST) != 0) {
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen if (list_sep == '\0')
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen list_sep = ns->sep;
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen else if (list_sep != ns->sep) {
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen i_error("namespace configuration error: "
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "All list=yes namespaces must use "
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen "the same separator");
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen return FALSE;
6ae329de09afb7214c906d762320847e05469d53Timo Sirainen }
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen }
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen }
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (inbox_ns == NULL) {
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen if (private_ns_count == 1) {
6ae329de09afb7214c906d762320847e05469d53Timo Sirainen /* just one private namespace. we'll assume it's
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen the INBOX namespace. */
637455ebee0453f860c9bce0626c485e35fb83deTimo Sirainen private_ns->flags |= NAMESPACE_FLAG_INBOX;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen } else {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_error("namespace configuration error: "
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "inbox=yes namespace missing");
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return FALSE;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (list_sep == '\0') {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_error("namespace configuration error: "
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "no list=yes namespaces");
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return FALSE;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return TRUE;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
e790c9b1fc56bca7ebd59dc289cb5035e3afcee5Timo Sirainen
e790c9b1fc56bca7ebd59dc289cb5035e3afcee5Timo Sirainenstatic struct mail_namespace *
e790c9b1fc56bca7ebd59dc289cb5035e3afcee5Timo Sirainennamespaces_sort(struct mail_namespace *src)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mail_namespace **tmp, *next, *dest = NULL;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen for (; src != NULL; src = next) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen next = src->next;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
d22301419109ed4a38351715e6760011421dadecTimo Sirainen for (tmp = &dest; *tmp != NULL; tmp = &(*tmp)->next) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (strlen(src->prefix) < strlen((*tmp)->prefix))
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen break;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
65b94e73c305dcb209cf958f938b93ec061c67a9Timo Sirainen src->next = *tmp;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen *tmp = src;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen }
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen return dest;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
73a87c2ff65c6116cde6fb158dfddb8ef7346901Timo Sirainenint mail_namespaces_init(pool_t pool, const char *user,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mail_namespace **namespaces_r)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
73a87c2ff65c6116cde6fb158dfddb8ef7346901Timo Sirainen struct mail_namespace *namespaces, *ns, **ns_p;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen enum mail_storage_flags flags;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen enum file_lock_method lock_method;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen const char *mail, *data, *error;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen unsigned int i;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen mail_storage_parse_env(&flags, &lock_method);
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen namespaces = NULL; ns_p = &namespaces;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen /* first try NAMESPACE_* environments */
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen for (i = 1; ; i++) {
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen t_push();
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen data = getenv(t_strdup_printf("NAMESPACE_%u", i));
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen t_pop();
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen if (data == NULL)
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen break;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen t_push();
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen *ns_p = namespace_add_env(pool, data, i, user, flags,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen lock_method);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen t_pop();
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (*ns_p == NULL)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen ns_p = &(*ns_p)->next;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (namespaces != NULL) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (!namespaces_check(namespaces))
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen return -1;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen namespaces = namespaces_sort(namespaces);
d0b2bd9e2246eb68ed952c7f2e13d1969d657c8fTimo Sirainen *namespaces_r = namespaces;
d0b2bd9e2246eb68ed952c7f2e13d1969d657c8fTimo Sirainen return 0;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen }
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen /* fallback to MAIL */
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen mail = getenv("MAIL");
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (mail == NULL) {
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen /* support also maildir-specific environment */
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen mail = getenv("MAILDIR");
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (mail != NULL)
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen mail = t_strconcat("maildir:", mail, NULL);
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen }
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen ns = p_new(pool, struct mail_namespace, 1);
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen ns->type = NAMESPACE_PRIVATE;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen ns->flags = NAMESPACE_FLAG_INBOX | NAMESPACE_FLAG_LIST;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen ns->prefix = "";
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen if (mail_storage_create(ns, NULL, mail, user, flags, lock_method,
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen &error) < 0) {
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen if (mail != NULL && *mail != '\0')
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_error("mail_location: %s", error);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen else {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_error("mail_location not set and "
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen "autodetection failed: %s", error);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return -1;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
3f91e60401495a4046c73992fabaa5e77200a451Timo Sirainen namespace_init_storage(ns);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen *namespaces_r = ns;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return 0;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainenstruct mail_namespace *mail_namespaces_init_empty(pool_t pool)
dd4f30895ebbddd77e000472fbadcb3128ae2883Timo Sirainen{
dd4f30895ebbddd77e000472fbadcb3128ae2883Timo Sirainen struct mail_namespace *ns;
dd4f30895ebbddd77e000472fbadcb3128ae2883Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ns = p_new(pool, struct mail_namespace, 1);
f71c2d4e6b802bf8e622bcd5df29286262d05d5aTimo Sirainen ns->prefix = "";
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen ns->flags = NAMESPACE_FLAG_INBOX | NAMESPACE_FLAG_LIST;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return ns;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid mail_namespaces_deinit(struct mail_namespace **_namespaces)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mail_namespace *namespaces = *_namespaces;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen *_namespaces = NULL;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen while (namespaces != NULL) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (namespaces->storage != NULL)
3f91e60401495a4046c73992fabaa5e77200a451Timo Sirainen mail_storage_destroy(&namespaces->storage);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen namespaces = namespaces->next;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenconst char *mail_namespace_fix_sep(struct mail_namespace *ns, const char *name)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen char *ret, *p;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen if (ns->sep == ns->real_sep)
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen return name;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen ret = p_strdup(unsafe_data_stack_pool, name);
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen for (p = ret; *p != '\0'; p++) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (*p == ns->sep)
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen *p = ns->real_sep;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen }
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen return ret;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainenchar mail_namespace_get_root_sep(struct mail_namespace *namespaces)
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen{
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen while ((namespaces->flags & NAMESPACE_FLAG_LIST) == 0)
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen namespaces = namespaces->next;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return namespaces->sep;
ddb018bc886680f462463b2c87f983fdedbf6cf0Timo Sirainen}
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic struct mail_namespace *
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenmail_namespace_find_int(struct mail_namespace *namespaces, const char **mailbox,
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen bool show_hidden)
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen{
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen#define CHECK_VISIBILITY(ns, show_hidden) \
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen (((ns)->flags & NAMESPACE_FLAG_HIDDEN) == 0 || (show_hidden))
37ee89f3cba22cd975912a882f0d3097fa5031e1Timo Sirainen struct mail_namespace *ns = namespaces;
37ee89f3cba22cd975912a882f0d3097fa5031e1Timo Sirainen const char *box = *mailbox;
37ee89f3cba22cd975912a882f0d3097fa5031e1Timo Sirainen struct mail_namespace *best = NULL;
37ee89f3cba22cd975912a882f0d3097fa5031e1Timo Sirainen size_t best_len = 0;
37ee89f3cba22cd975912a882f0d3097fa5031e1Timo Sirainen bool inbox;
37ee89f3cba22cd975912a882f0d3097fa5031e1Timo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen inbox = strncasecmp(box, "INBOX", 5) == 0;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (inbox && box[5] == '\0') {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* find the INBOX namespace */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen *mailbox = "INBOX";
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen while (ns != NULL) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if ((ns->flags & NAMESPACE_FLAG_INBOX) != 0 &&
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen CHECK_VISIBILITY(ns, show_hidden))
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return ns;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (*ns->prefix == '\0')
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen best = ns;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ns = ns->next;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return best;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen for (; ns != NULL; ns = ns->next) {
d22301419109ed4a38351715e6760011421dadecTimo Sirainen if (ns->prefix_len >= best_len &&
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen (strncmp(ns->prefix, box, ns->prefix_len) == 0 ||
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen (inbox && strncmp(ns->prefix, "INBOX", 5) == 0 &&
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen strncmp(ns->prefix+5, box+5, ns->prefix_len-5) == 0)) &&
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen CHECK_VISIBILITY(ns, show_hidden)) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen best = ns;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen best_len = ns->prefix_len;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen }
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (best != NULL) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (best_len > 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen *mailbox += best_len;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen else if (inbox && (box[5] == best->sep || box[5] == '\0'))
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen *mailbox = t_strconcat("INBOX", box+5, NULL);
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen *mailbox = mail_namespace_fix_sep(best, *mailbox);
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen }
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen return best;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen}
4fded1eec06aba9ce37887ac30619768760cd0d0Timo Sirainen
4fded1eec06aba9ce37887ac30619768760cd0d0Timo Sirainenstruct mail_namespace *
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainenmail_namespace_find(struct mail_namespace *namespaces, const char **mailbox)
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen{
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen return mail_namespace_find_int(namespaces, mailbox, TRUE);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct mail_namespace *
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenmail_namespace_find_visible(struct mail_namespace *namespaces,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const char **mailbox)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return mail_namespace_find_int(namespaces, mailbox, FALSE);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct mail_namespace *
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenmail_namespace_find_inbox(struct mail_namespace *namespaces)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen while ((namespaces->flags & NAMESPACE_FLAG_INBOX) == 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen namespaces = namespaces->next;
f71c2d4e6b802bf8e622bcd5df29286262d05d5aTimo Sirainen return namespaces;
f71c2d4e6b802bf8e622bcd5df29286262d05d5aTimo Sirainen}
f71c2d4e6b802bf8e622bcd5df29286262d05d5aTimo Sirainen
f71c2d4e6b802bf8e622bcd5df29286262d05d5aTimo Sirainenbool mail_namespace_update_name(struct mail_namespace *ns,
d22301419109ed4a38351715e6760011421dadecTimo Sirainen const char **mailbox)
5b62dea2f88165f3f4d87bba9011343f3ff415ffTimo Sirainen{
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mail_namespace tmp_ns = *ns;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* FIXME: a bit kludgy.. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen tmp_ns.next = NULL;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return mail_namespace_find_int(&tmp_ns, mailbox, TRUE) != NULL;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen}
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen
struct mail_namespace *
mail_namespace_find_prefix(struct mail_namespace *namespaces,
const char *prefix)
{
struct mail_namespace *ns;
unsigned int len = strlen(prefix);
for (ns = namespaces; ns != NULL; ns = ns->next) {
if (ns->prefix_len == len &&
strcmp(ns->prefix, prefix) == 0)
return ns;
}
return NULL;
}
struct mail_namespace *
mail_namespace_find_prefix_nosep(struct mail_namespace *namespaces,
const char *prefix)
{
struct mail_namespace *ns;
unsigned int len = strlen(prefix);
for (ns = namespaces; ns != NULL; ns = ns->next) {
if (ns->prefix_len == len + 1 &&
strncmp(ns->prefix, prefix, len) == 0 &&
ns->prefix[len] == ns->sep)
return ns;
}
return NULL;
}