mail-namespace.c revision 94ce7e7700cda14a8342cb08e7285507b4b531da
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
89b548af722113acb5d63dfffb44423cb60f91e4Timo Sirainenvoid (*hook_mail_namespaces_created)(struct mail_namespace *namespaces);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_namespace_init_storage(struct mail_namespace *ns)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ns->list = mail_storage_get_list(ns->storage);
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen ns->real_sep = mailbox_list_get_hierarchy_sep(ns->list);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void mail_namespace_free(struct mail_namespace *ns)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ns->owner != ns->user && ns->owner != NULL)
8fa41238067c854435884c459963fde6f8c6436bTimo Sirainennamespace_add_env(const char *data, unsigned int num,
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen struct mail_user *user, enum mail_storage_flags flags,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *sep, *type, *prefix, *driver, *error, *list, *alias_for;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen sep = getenv(t_strdup_printf("NAMESPACE_%u_SEP", num));
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen type = getenv(t_strdup_printf("NAMESPACE_%u_TYPE", num));
5aeb15e5817fbd4b1d8de540aa7673e3819a8030Timo Sirainen prefix = getenv(t_strdup_printf("NAMESPACE_%u_PREFIX", num));
5aeb15e5817fbd4b1d8de540aa7673e3819a8030Timo Sirainen list = getenv(t_strdup_printf("NAMESPACE_%u_LIST", num));
41e1c7380edda701719d8ce1fb4d465d2ec4c84dTimo Sirainen alias_for = getenv(t_strdup_printf("NAMESPACE_%u_ALIAS", num));
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen if (getenv(t_strdup_printf("NAMESPACE_%u_INBOX", num)) != NULL)
3ccab0bac68040f179a7de45c516cec258e28fdbTimo Sirainen if (getenv(t_strdup_printf("NAMESPACE_%u_HIDDEN", num)) != NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (getenv(t_strdup_printf("NAMESPACE_%u_SUBSCRIPTIONS", num)) != NULL)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen if (type == NULL || *type == '\0' || strncmp(type, "private", 7) == 0) {
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen ns->alias_for = mail_namespace_find_prefix(prev_namespaces,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_error("Invalid namespace alias_for: %s", alias_for);
b780aa272b742a43579cdb523cc79cc8d4521306Timo Sirainen i_error("Chained namespace alias_for: %s", alias_for);
b780aa272b742a43579cdb523cc79cc8d4521306Timo Sirainen ns->alias_chain_next = ns->alias_for->alias_chain_next;
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen i_info("Namespace: type=%s, prefix=%s, sep=%s, "
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen "inbox=%s, hidden=%s, list=%s, subscriptions=%s",
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen type == NULL ? "" : type, prefix, sep == NULL ? "" : sep,
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen (ns->flags & NAMESPACE_FLAG_INBOX) ? "yes" : "no",
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen (ns->flags & NAMESPACE_FLAG_HIDDEN) ? "yes" : "no",
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen if (ns->type == NAMESPACE_SHARED && strchr(ns->prefix, '%') != NULL) {
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen /* dynamic shared namespace */
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen if (mail_storage_create(ns, driver, data, flags, lock_method,
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen i_error("Namespace '%s': %s", ns->prefix, error);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenstatic bool namespaces_check(struct mail_namespace *namespaces)
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen struct mail_namespace *ns, *inbox_ns = NULL, *private_ns = NULL;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen unsigned int private_ns_count = 0;
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen unsigned int subscriptions_count = 0;
ffd9a1898a18fadfc5dce399162c25d50548f905Timo Sirainen for (ns = namespaces; ns != NULL; ns = ns->next) {
ffd9a1898a18fadfc5dce399162c25d50548f905Timo Sirainen if ((ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
1e923fcf497665fe071a154c31fb452766b0b2deTimo Sirainen "There can be only one namespace with "
d161e3c2cde2bd8d5917840f68823a2259ed426eTimo Sirainen "inbox=yes");
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen (ns->flags & NAMESPACE_FLAG_LIST_PREFIX) != 0 &&
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen ns->prefix[strlen(ns->prefix)-1] != ns->sep) {
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen "list=yes requires prefix=%s "
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen if ((ns->flags & (NAMESPACE_FLAG_LIST_PREFIX |
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen "All list=yes namespaces must use "
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen "the same separator");
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen (ns->flags & NAMESPACE_FLAG_LIST_PREFIX) == 0) {
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen "Empty prefix requires list=yes");
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if ((ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) != 0)
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen /* just one private namespace. we'll assume it's
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen the INBOX namespace. */
da985034a708db2f61394b30d117050ae6829ee5Timo Sirainen "inbox=yes namespace missing");
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen "no list=yes namespaces");
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen "no subscriptions=yes namespaces");
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainenint mail_namespaces_init(struct mail_user *user)
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen struct mail_namespace *namespaces, *ns, **ns_p;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen unsigned int i;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen /* first try NAMESPACE_* environments */
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen for (i = 1; ; i++) {
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen data = getenv(t_strdup_printf("NAMESPACE_%u", i));
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen *ns_p = namespace_add_env(data, i, user, flags,
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen /* fallback to MAIL */
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen /* support also maildir-specific environment */
6825360d446542046757b06064282301c4c6b27cTimo Sirainen ns->flags = NAMESPACE_FLAG_INBOX | NAMESPACE_FLAG_LIST_PREFIX |
6825360d446542046757b06064282301c4c6b27cTimo Sirainen if (mail_storage_create(ns, NULL, mail, flags, lock_method,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenmail_namespaces_init_empty(struct mail_user *user)
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen ns->flags = NAMESPACE_FLAG_INBOX | NAMESPACE_FLAG_LIST_PREFIX |
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainenvoid mail_namespaces_deinit(struct mail_namespace **_namespaces)
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen struct mail_namespace *ns, *namespaces = *_namespaces;
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainenvoid mail_namespace_destroy(struct mail_namespace *ns)
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen /* remove from user's namespaces list */
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen for (nsp = &ns->user->namespaces; *nsp != NULL; nsp = &(*nsp)->next) {
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainenconst char *mail_namespace_fix_sep(struct mail_namespace *ns, const char *name)
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainenconst char *mail_namespace_get_vname(struct mail_namespace *ns, string_t *dest,
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen if ((ns->flags & NAMESPACE_FLAG_INBOX) == 0 ||
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainenchar mail_namespace_get_root_sep(const struct mail_namespace *namespaces)
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen while ((namespaces->flags & NAMESPACE_FLAG_LIST_PREFIX) == 0)
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainenmail_namespace_find_mask(struct mail_namespace *namespaces,
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen const char **mailbox,
c53e8ee216904ffe6de4f6518d9f9f5107b7610eTimo Sirainen /* find the INBOX namespace */
c53e8ee216904ffe6de4f6518d9f9f5107b7610eTimo Sirainen if ((ns->flags & NAMESPACE_FLAG_INBOX) != 0 &&
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen (strncmp(ns->prefix, box, ns->prefix_len) == 0 ||
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen (inbox && strncmp(ns->prefix, "INBOX", 5) == 0 &&
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen strncmp(ns->prefix+5, box+5, ns->prefix_len-5) == 0)) &&
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen else if (inbox && (box[5] == best->sep || box[5] == '\0'))
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen *mailbox = mail_namespace_fix_sep(best, *mailbox);
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainenmail_namespace_find(struct mail_namespace *namespaces, const char **mailbox)
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen return mail_namespace_find_mask(namespaces, mailbox, 0, 0);
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainenmail_namespace_find_visible(struct mail_namespace *namespaces,
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen const char **mailbox)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return mail_namespace_find_mask(namespaces, mailbox, 0,
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainenmail_namespace_find_subscribable(struct mail_namespace *namespaces,
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen const char **mailbox)
d22390f33eedbd2413debabc0662dde5241b1aa6Timo Sirainen return mail_namespace_find_mask(namespaces, mailbox,
14b8bbb81e0b546436d4d5d5f38e45027c146b9bTimo Sirainenmail_namespace_find_unsubscribable(struct mail_namespace *namespaces,
14b8bbb81e0b546436d4d5d5f38e45027c146b9bTimo Sirainen const char **mailbox)
14b8bbb81e0b546436d4d5d5f38e45027c146b9bTimo Sirainen return mail_namespace_find_mask(namespaces, mailbox,
e8fd7988ec183fb6c104aed19a61f1a096c51d34Timo Sirainenmail_namespace_find_inbox(struct mail_namespace *namespaces)
e8fd7988ec183fb6c104aed19a61f1a096c51d34Timo Sirainen while ((namespaces->flags & NAMESPACE_FLAG_INBOX) == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenbool mail_namespace_update_name(const struct mail_namespace *ns,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char **mailbox)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* FIXME: a bit kludgy.. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return mail_namespace_find_mask(&tmp_ns, mailbox, 0, 0) != NULL;
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainenmail_namespace_find_prefix(struct mail_namespace *namespaces,
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen for (ns = namespaces; ns != NULL; ns = ns->next) {
94aa90d2d17a7aebcda5a4193a62e80ddbb169b7Timo Sirainenmail_namespace_find_prefix_nosep(struct mail_namespace *namespaces,
94aa90d2d17a7aebcda5a4193a62e80ddbb169b7Timo Sirainen for (ns = namespaces; ns != NULL; ns = ns->next) {