shared-storage.c revision c7194d1d3872ffb2901737e1df337cc227a3fa77
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2008 Dovecot authors, see the included COPYING file */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen#include "lib.h"
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen#include "array.h"
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen#include "str.h"
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen#include "var-expand.h"
a1607f6001a9949e1cf9d49eb0aa936dbb4c77ffTimo Sirainen#include "shared-storage.h"
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
00d58fcfe8191d6ce7efa801d289a5c0fe88d1aeTimo Sirainen#define SHARED_LIST_CONTEXT(obj) \
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen MODULE_CONTEXT(obj, shared_mailbox_list_module)
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainenextern struct mail_storage shared_storage;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenextern struct mailbox shared_mailbox;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(shared_mailbox_list_module,
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen &mailbox_list_module_register);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstatic struct mail_storage *shared_alloc(void)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen{
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct shared_storage *storage;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen pool_t pool;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen pool = pool_alloconly_create("shared storage", 256);
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen storage = p_new(pool, struct shared_storage, 1);
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen storage->storage = shared_storage;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen storage->storage.pool = pool;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen return &storage->storage;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen}
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenstatic int shared_create(struct mail_storage *_storage, const char *data,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen const char **error_r)
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen{
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen struct shared_storage *storage = (struct shared_storage *)_storage;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen struct mailbox_list_settings list_set;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen const char *driver, *p;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen bool have_username;
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen /* data must begin with the actual mailbox driver */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen p = strchr(data, ':');
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen if (p == NULL) {
4462bd7b4c7ef3de006f060e155a90e5de7cae21Timo Sirainen *error_r = "Shared mailbox location not prefixed with driver";
f6c1297c26b355c4aec2a08978f51ec3efecb351Timo Sirainen return -1;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen }
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen driver = t_strdup_until(data, p);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen storage->location = p_strdup(_storage->pool, data);
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen storage->storage_class = mail_storage_find_class(driver);
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen if (storage->storage_class == NULL) {
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen *error_r = t_strconcat("Unknown shared storage driver: ",
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen driver, NULL);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen return -1;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen }
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen _storage->mailbox_is_file = storage->storage_class->mailbox_is_file;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen p = strchr(_storage->ns->prefix, '%');
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen if (p == NULL) {
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen *error_r = "Shared namespace prefix doesn't contain %";
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen return -1;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen }
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen storage->ns_prefix_pattern = p_strdup(_storage->pool, p);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen _storage->ns->prefix = p_strdup_until(_storage->ns->user->pool,
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen _storage->ns->prefix, p);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen have_username = FALSE;
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainen for (p = storage->ns_prefix_pattern; *p != '\0'; p++) {
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen if (*p != '%')
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen continue;
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainen if (*++p == '\0')
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen break;
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen if (*p == 'u' || *p == 'n')
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen have_username = TRUE;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen else if (*p != 'd')
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainen break;
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen }
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen if (*p != '\0') {
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen *error_r = "Shared namespace prefix contains unknown variables";
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen return -1;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen }
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen if (!have_username) {
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen *error_r = "Shared namespace prefix doesn't contain %u or %n";
e07bf3772a2bc075de4915ad0961beb8d083c22dTimo Sirainen return -1;
e07bf3772a2bc075de4915ad0961beb8d083c22dTimo Sirainen }
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen if (mailbox_list_alloc("shared", &_storage->list, error_r) < 0)
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen return -1;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen MODULE_CONTEXT_SET_FULL(_storage->list, shared_mailbox_list_module,
e07bf3772a2bc075de4915ad0961beb8d083c22dTimo Sirainen storage, &storage->list_module_ctx);
e07bf3772a2bc075de4915ad0961beb8d083c22dTimo Sirainen
e07bf3772a2bc075de4915ad0961beb8d083c22dTimo Sirainen memset(&list_set, 0, sizeof(list_set));
e07bf3772a2bc075de4915ad0961beb8d083c22dTimo Sirainen list_set.mail_storage_flags = &_storage->flags;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen list_set.lock_method = &_storage->lock_method;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen mailbox_list_init(_storage->list, _storage->ns, &list_set,
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen mail_storage_get_list_flags(_storage->flags));
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen return 0;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen}
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainenint shared_storage_get_namespace(struct mail_storage *_storage,
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen const char **_name,
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen struct mail_namespace **ns_r)
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen{
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen struct shared_storage *storage = (struct shared_storage *)_storage;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen struct mail_user *user = _storage->ns->user;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen static struct var_expand_table static_tab[] = {
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen { 'u', NULL },
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen { 'n', NULL },
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen { 'd', NULL },
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen { '\0', NULL }
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen };
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen struct var_expand_table *tab;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen struct mail_namespace *ns;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen const char *domain = NULL, *username = NULL, *userdomain = NULL;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen const char *name, *p, *next, **dest, *error;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen string_t *prefix, *location;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen p = storage->ns_prefix_pattern;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen for (name = *_name; *p != '\0';) {
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen if (*p != '%') {
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen if (*p != *name)
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen return -1;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen p++; name++;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen continue;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen }
d66be2bebfa96e7d3d20e2153f60e6e25dcc9a18Timo Sirainen switch (*++p) {
e376e08040b5f21ff79a15ae728d2532a34207f6Timo Sirainen case 'd':
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen dest = &domain;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen break;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen case 'n':
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen dest = &username;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen break;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen case 'u':
fd35227c47190afc832579ca5c76524792701bf7Timo Sirainen dest = &userdomain;
fd35227c47190afc832579ca5c76524792701bf7Timo Sirainen break;
fd35227c47190afc832579ca5c76524792701bf7Timo Sirainen default:
fd35227c47190afc832579ca5c76524792701bf7Timo Sirainen /* we checked this already above */
fd35227c47190afc832579ca5c76524792701bf7Timo Sirainen i_unreached();
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen }
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen p++;
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen next = strchr(name, *p != '\0' ? *p : _storage->ns->sep);
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen if (next == NULL)
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen return -1;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen *dest = t_strdup_until(name, next);
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen name = next;
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen }
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen /* successfully matched the name. */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen if (userdomain == NULL) {
d66be2bebfa96e7d3d20e2153f60e6e25dcc9a18Timo Sirainen i_assert(username != NULL);
d66be2bebfa96e7d3d20e2153f60e6e25dcc9a18Timo Sirainen userdomain = domain == NULL ? username :
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen t_strconcat(username, "@", domain, NULL);
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen } else {
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen domain = strchr(userdomain, '@');
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen if (domain == NULL)
783278c012551bc2f25f065a8d3ec1a3cfc0d296Timo Sirainen username = userdomain;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen else {
5d49cbcf87354f0ddf3b71bc5f0cefdc02b14f68Timo Sirainen username = t_strdup_until(userdomain, domain);
ce3faaaaab3e2d45b023396287e02f88e5c76e74Timo Sirainen domain++;
fd35227c47190afc832579ca5c76524792701bf7Timo Sirainen }
ce3faaaaab3e2d45b023396287e02f88e5c76e74Timo Sirainen }
ce3faaaaab3e2d45b023396287e02f88e5c76e74Timo Sirainen
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen /* expand the namespace prefix and see if it already exists.
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen this should normally happen only when the mailbox is being opened */
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen tab = t_malloc(sizeof(static_tab));
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen memcpy(tab, static_tab, sizeof(static_tab));
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen tab[0].value = userdomain;
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen tab[1].value = username;
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen tab[2].value = domain;
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen prefix = t_str_new(128);
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen str_append(prefix, _storage->ns->prefix);
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen var_expand(prefix, storage->ns_prefix_pattern, tab);
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen ns = mail_namespace_find_prefix(user->namespaces, str_c(prefix));
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen if (ns != NULL) {
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen *_name = mail_namespace_fix_sep(ns, name);
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen *ns_r = ns;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen return 0;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen }
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen /* create the new namespace */
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen ns = p_new(user->pool, struct mail_namespace, 1);
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen ns->type = NAMESPACE_SHARED;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen ns->user = user;
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen ns->prefix = p_strdup(user->pool, str_c(prefix));
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen ns->flags = NAMESPACE_FLAG_LIST | NAMESPACE_FLAG_HIDDEN;
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen ns->sep = _storage->ns->sep;
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen location = t_str_new(256);
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen var_expand(location, storage->location, tab);
2e263a9d901483a902720a30c474761bd3324fe8Timo Sirainen if (mail_storage_create(ns, NULL, str_c(location), _storage->flags,
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen _storage->lock_method, &error) < 0) {
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen i_error("Namespace '%s': %s", ns->prefix, error);
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen return -1;
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen }
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen /* FIXME: we could remove namespaces here that don't have usable
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen mailboxes. otherwise the memory usage could just keep growing. */
bbd4c4cf902539c25c471157eb9849459734759cTimo Sirainen mail_user_add_namespace(user, ns);
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen
3e7565a7b39694bcdf448d8eb2a7f0774733297bTimo Sirainen *_name = mail_namespace_fix_sep(ns, name);
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen *ns_r = ns;
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen return 0;
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen}
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenstatic void shared_mailbox_copy_error(struct mail_storage *shared_storage,
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen struct mail_namespace *backend_ns)
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen{
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen const char *str;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen enum mail_error error;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen str = mail_storage_get_last_error(backend_ns->storage, &error);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen mail_storage_set_error(shared_storage, error, str);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen}
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenstatic struct mailbox *
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenshared_mailbox_open(struct mail_storage *storage, const char *name,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen struct istream *input, enum mailbox_open_flags flags)
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen{
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen struct mail_namespace *ns;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct mailbox *box;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen if (input != NULL) {
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen mail_storage_set_critical(storage,
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen "Shared storage doesn't support streamed mailboxes");
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen return NULL;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen }
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen if (shared_storage_get_namespace(storage, &name, &ns) < 0)
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen return NULL;
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen box = mailbox_open(ns->storage, name, NULL, flags);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen if (box == NULL)
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen shared_mailbox_copy_error(storage, ns);
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen return box;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen}
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainenstatic int shared_mailbox_create(struct mail_storage *storage,
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen const char *name, bool directory)
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen{
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen struct mail_namespace *ns;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen int ret;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen if (shared_storage_get_namespace(storage, &name, &ns) < 0)
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen return -1;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen ret = mail_storage_mailbox_create(ns->storage, name, directory);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen if (ret < 0)
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen shared_mailbox_copy_error(storage, ns);
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen return ret;
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen}
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainenstruct mail_storage shared_storage = {
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen MEMBER(name) SHARED_STORAGE_NAME,
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen MEMBER(mailbox_is_file) FALSE, /* unknown at this point */
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen {
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen NULL,
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen NULL,
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen shared_alloc,
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen shared_create,
bd4d0a1a7c0626452b8d82f37e3ec07267ac9896Timo Sirainen index_storage_destroy,
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen NULL,
bd4d0a1a7c0626452b8d82f37e3ec07267ac9896Timo Sirainen shared_mailbox_open,
bd4d0a1a7c0626452b8d82f37e3ec07267ac9896Timo Sirainen shared_mailbox_create
bd4d0a1a7c0626452b8d82f37e3ec07267ac9896Timo Sirainen }
cf7164ece50797a67fc4bfb5889022ac93a36a8aTimo Sirainen};
cbc61fcb33b370d049c16a3c44568b4deb4e2b33Timo Sirainen