mail-storage.c revision ba8ff75a149d6936f769a2d1dfceaab9da87863b
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch/* Copyright (c) 2002-2014 Dovecot authors, see the included COPYING file */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschextern struct mail_search_register *mail_search_register_imap;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschextern struct mail_search_register *mail_search_register_human;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschstruct mail_storage_module_register mail_storage_module_register = { 0 };
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschstruct mail_module_register mail_module_register = { 0 };
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschstruct mail_storage_mail_index_module mail_storage_mail_index_module =
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch MODULE_CONTEXT_INIT(&mail_index_module_register);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch mail_search_register_deinit(&mail_search_register_human);
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch mail_search_register_deinit(&mail_search_register_imap);
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Boschvoid mail_storage_class_register(struct mail_storage *storage_class)
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch i_assert(mail_storage_find_class(storage_class->name) == NULL);
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch /* append it after the list, so the autodetection order is correct */
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch array_append(&mail_storage_classes, &storage_class, 1);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschvoid mail_storage_class_unregister(struct mail_storage *storage_class)
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch unsigned int i, count;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch classes = array_get(&mail_storage_classes, &count);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch for (i = 0; i < count; i++) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschstruct mail_storage *mail_storage_find_class(const char *name)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch unsigned int i, count;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch classes = array_get(&mail_storage_classes, &count);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch for (i = 0; i < count; i++) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschmail_storage_autodetect(const struct mail_namespace *ns,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch unsigned int i, count;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch classes = array_get(&mail_storage_classes, &count);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch for (i = 0; i < count; i++) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschmail_storage_set_autodetection(const char **data, const char **driver)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch const char *p;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* check if data is in driver:data format (eg. mbox:~/mail) */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* no autodetection if the storage driver is given. */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschmail_storage_get_class(struct mail_namespace *ns, const char *driver,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch enum mail_storage_flags flags, const char **error_r)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* no mail_location, autodetect */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* explicit autodetection with "auto" driver. */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* handle the same as with driver=NULL */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch storage_class = mail_user_get_storage_class(ns->user, driver);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (list_set->root_dir == NULL || *list_set->root_dir == '\0') {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* no root directory given. is this allowed? */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch (flags & MAIL_STORAGE_FLAG_NO_AUTODETECTION) == 0) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* autodetection should take care of this */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch (storage_class->class_flags & MAIL_STORAGE_CLASS_FLAG_NO_ROOT) != 0) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* root not required for this storage */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch (list->props & MAILBOX_LIST_PROP_NO_ROOT) != 0) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* root not required for this layout */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch storage_class->v.get_list_settings(ns, list_set);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch storage_class = mail_storage_autodetect(ns, list_set);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (home == NULL || *home == '\0') home = "(not set)";
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (ns->set->location == NULL || *ns->set->location == '\0') {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch "Mail storage autodetection failed with home=%s", home);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch } else if (strncmp(ns->set->location, "auto:", 5) == 0) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch "Autodetection failed for %s (home=%s)",
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch "Ambiguous mail location setting, "
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch "don't know what to do with it: %s "
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch "(try prefixing it with mbox: or maildir:)",
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschmail_storage_verify_root(const char *root_dir, bool autocreate,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch const char **error_r)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch *error_r = mail_error_eacces_msg("stat", root_dir);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch } else if (errno != ENOENT && errno != ENOTDIR) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch *error_r = t_strdup_printf("stat(%s) failed: %m", root_dir);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch } else if (!autocreate) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch "Root mail directory doesn't exist: %s", root_dir);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* doesn't exist */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschmail_storage_create_root(struct mailbox_list *list,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch enum mail_storage_flags flags, const char **error_r)
639bb36b12b9f9bb54c8bb1be50eac623622f8a0Timo Sirainen if (!mailbox_list_get_root_path(list, MAILBOX_LIST_PATH_TYPE_MAILBOX,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* storage doesn't use directories (e.g. shared root) */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if ((flags & MAIL_STORAGE_FLAG_NO_AUTOVERIFY) != 0) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* we don't need to verify, but since debugging is
639bb36b12b9f9bb54c8bb1be50eac623622f8a0Timo Sirainen enabled, check and log if the root doesn't exist */
4351efdddced25735d629496f6c68c9d0cfb896aTimo Sirainen if (mail_storage_verify_root(root_dir, FALSE, &error) < 0) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch i_debug("Namespace %s: Creating storage despite: %s",
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch autocreate = (flags & MAIL_STORAGE_FLAG_NO_AUTOCREATE) == 0;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch ret = mail_storage_verify_root(root_dir, autocreate, error_r);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch ret = mailbox_list_try_mkdir_root(list, root_dir,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschmail_storage_match_class(struct mail_storage *storage,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (strcmp(storage->name, storage_class->name) != 0)
639bb36b12b9f9bb54c8bb1be50eac623622f8a0Timo Sirainen if ((storage->class_flags & MAIL_STORAGE_CLASS_FLAG_UNIQUE_ROOT) != 0 &&
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch strcmp(storage->unique_root_dir, set->root_dir) != 0)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* allow multiple independent shared namespaces */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch struct mail_storage *storage = user->storages;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch for (; storage != NULL; storage = storage->next) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (mail_storage_match_class(storage, storage_class, set))
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschint mail_storage_create_full(struct mail_namespace *ns, const char *driver,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch const char *data, enum mail_storage_flags flags,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch const char **error_r)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch struct mail_storage *storage_class, *storage = NULL;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch const char *p;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if ((flags & MAIL_STORAGE_FLAG_KEEP_HEADER_MD5) == 0 &&
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* if pop3_uidl_format contains %m, we want to keep the
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch header MD5 sums stored even if we're not running POP3
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch right now. */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* autodetect */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch } else if (driver != NULL && strcmp(driver, "shared") == 0) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* internal shared namespace */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch mail_storage_set_autodetection(&data, &driver);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (mailbox_list_settings_parse(ns->user, data, &list_set,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch storage_class = mail_storage_get_class(ns, driver, &list_set, flags,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* first storage for namespace */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (mail_storage_is_mailbox_file(storage_class))
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch list_flags |= MAILBOX_LIST_FLAG_MAILBOX_FILES;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if ((storage_class->class_flags & MAIL_STORAGE_CLASS_FLAG_NO_ROOT) != 0)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch list_flags |= MAILBOX_LIST_FLAG_NO_MAIL_FILES;
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch if (mailbox_list_create(list_set.layout, ns, &list_set,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch *error_r = t_strdup_printf("Mailbox list driver %s: %s",
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if ((storage_class->class_flags & MAIL_STORAGE_CLASS_FLAG_NO_ROOT) == 0) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (mail_storage_create_root(ns->list, flags, error_r) < 0)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch storage = mail_storage_find(ns->user, storage_class, &list_set);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* using an existing storage */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch p_array_init(&storage->module_contexts, storage->pool, 5);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch storage->v.create(storage, ns, error_r) < 0) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch *error_r = t_strdup_printf("%s: %s", storage->name, *error_r);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschint mail_storage_create(struct mail_namespace *ns, const char *driver,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch enum mail_storage_flags flags, const char **error_r)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch return mail_storage_create_full(ns, driver, ns->set->location,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschvoid mail_storage_unref(struct mail_storage **_storage)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* set *_storage=NULL only after calling destroy() callback.
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch for example mdbox wants to access ns->storage */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch i_panic("Trying to deinit storage without freeing mailbox %s",
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch i_panic("Trying to deinit storage before freeing its objects");
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch DLLIST_REMOVE(&storage->user->storages, storage);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschvoid mail_storage_obj_ref(struct mail_storage *storage)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschvoid mail_storage_obj_unref(struct mail_storage *storage)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschvoid mail_storage_clear_error(struct mail_storage *storage)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschvoid mail_storage_set_error(struct mail_storage *storage,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschvoid mail_storage_set_internal_error(struct mail_storage *storage)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch const char *str;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch str = t_strflocaltime(MAIL_ERRSTR_CRITICAL_MSG_STAMP, ioloop_time);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschvoid mail_storage_set_critical(struct mail_storage *storage,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch const char *fmt, ...)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* critical errors may contain sensitive data, so let user
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch see only "Internal error" with a timestamp to make it
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch easier to look from log files the actual error message. */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschvoid mail_storage_copy_error(struct mail_storage *dest,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch const char *str;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch str = mail_storage_get_last_error(src, &error);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschvoid mail_storage_copy_list_error(struct mail_storage *storage,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch const char *str;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch str = mailbox_list_get_last_error(list, &error);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschvoid mailbox_set_index_error(struct mailbox *box)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch mail_storage_set_internal_error(box->storage);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschmail_storage_get_settings(struct mail_storage *storage)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschstruct mail_user *mail_storage_get_user(struct mail_storage *storage)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschvoid mail_storage_set_callbacks(struct mail_storage *storage,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschint mail_storage_purge(struct mail_storage *storage)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschconst char *mail_storage_get_last_error(struct mail_storage *storage,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* We get here only in error situations, so we have to return some
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch error. If storage->error is NONE, it means we forgot to set it at
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch some point.. */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch return storage->error_string != NULL ? storage->error_string :
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch "BUG: Unknown internal error";
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* This shouldn't happen.. */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschconst char *mailbox_get_last_error(struct mailbox *box,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch return mail_storage_get_last_error(box->storage, error_r);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschenum mail_error mailbox_get_last_mail_error(struct mailbox *box)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch mail_storage_get_last_error(box->storage, &error);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschbool mail_storage_is_mailbox_file(struct mail_storage *storage)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch MAIL_STORAGE_CLASS_FLAG_MAILBOX_IS_FILE) != 0;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschbool mail_storage_set_error_from_errno(struct mail_storage *storage)
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (!mail_error_from_errno(&error, &error_string))
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (storage->set->mail_debug && error != MAIL_ERROR_NOTFOUND) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* debugging is enabled - admin may be debugging a
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch (permission) problem, so return FALSE to get the caller to
05262e3132642bbdc4a8087c17b0903cf2ff22d2Stephan Bosch log the full error message. */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch mail_storage_set_error(storage, error, error_string);
05262e3132642bbdc4a8087c17b0903cf2ff22d2Stephan Boschmailbox_settings_find(struct mail_user *user, const char *vname)
05262e3132642bbdc4a8087c17b0903cf2ff22d2Stephan Bosch ns = mail_namespace_find(user->namespaces, vname);
05262e3132642bbdc4a8087c17b0903cf2ff22d2Stephan Bosch strncmp(ns->prefix, vname, ns->prefix_len-1) == 0) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (vname[ns->prefix_len-1] == mail_namespace_get_sep(ns))
05262e3132642bbdc4a8087c17b0903cf2ff22d2Stephan Bosch /* namespace prefix itself */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschstruct mailbox *mailbox_alloc(struct mailbox_list *list, const char *vname,
05262e3132642bbdc4a8087c17b0903cf2ff22d2Stephan Bosch /* make sure INBOX shows up in uppercase everywhere. do this
05262e3132642bbdc4a8087c17b0903cf2ff22d2Stephan Bosch regardless of whether we're in inbox=yes namespace, because
05262e3132642bbdc4a8087c17b0903cf2ff22d2Stephan Bosch clients expect INBOX to be case insensitive regardless of
05262e3132642bbdc4a8087c17b0903cf2ff22d2Stephan Bosch server's internal configuration. */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch else if (vname[5] != mail_namespace_get_sep(list->ns))
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* not INBOX prefix */ ;
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch else if (strncasecmp(list->ns->prefix, vname, 6) == 0 &&
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch "Invalid server configuration: "
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch "Namespace prefix=%s must be uppercase INBOX",
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch vname = t_strconcat("INBOX", vname + 5, NULL);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (mailbox_list_get_storage(&new_list, vname, &storage) < 0) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* do a delayed failure at mailbox_open() */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch storage = mail_namespace_get_default_storage(list->ns);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch errstr = mailbox_list_get_last_error(new_list, &open_error);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch box = storage->v.mailbox_alloc(storage, new_list, vname, flags);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch box->set = mailbox_settings_find(storage->user, vname);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch mail_storage_set_error(storage, open_error, errstr);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch DLLIST_PREPEND(&box->storage->mailboxes, box);
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschstruct mailbox *mailbox_alloc_guid(struct mailbox_list *list,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (mailbox_guid_cache_find(list, guid, &vname) < 0) {
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID,
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch /* GUID mismatch, refresh cache and try again */
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch /* successfully opened the correct mailbox */
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch "Couldn't verify mailbox GUID: %s",
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch vname = t_strdup_printf("(nonexistent mailbox with GUID=%s)",
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Bosch vname = t_strdup_printf("(error in mailbox with GUID=%s)",
8fe8f97e688779add9cd042a9db4ddb7b117cce2Stephan Boschstatic bool mailbox_is_autocreated(struct mailbox *box)
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch strcmp(box->set->autocreate, MAILBOX_SET_AUTO_NO) != 0;
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Boschstatic int mailbox_autocreate(struct mailbox *box)
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch "Failed to autocreate mailbox %s: %s",
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch "Failed to autosubscribe to mailbox %s: %s",
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch box->vname, mailbox_get_last_error(box, NULL));
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Boschstatic int mailbox_autocreate_and_reopen(struct mailbox *box)
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch !box->storage->user->inbox_open_error_logged) {
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch box->storage->user->inbox_open_error_logged = TRUE;
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch "Opening INBOX failed: %s",
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Boschmailbox_name_verify_separators(const char *vname, char sep,
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch const char **error_r)
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch unsigned int i;
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch /* Make sure the vname is correct: non-empty, doesn't begin or end
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch with separator and no adjacent separators */
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch *error_r = "Has adjacent hierarchy separators";
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch if (prev_sep && i > 0) {
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Boschstatic int mailbox_verify_name(struct mailbox *box)
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch /* this is INBOX - don't bother with further checks */
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch list_sep = mailbox_list_get_hierarchy_sep(box->list);
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch /* vname is either "namespace/box" or "namespace" */
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch i_assert(strncmp(vname, ns->prefix, ns->prefix_len-1) == 0);
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch i_assert(vname[0] == ns->prefix[ns->prefix_len-1]);
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch /* "namespace/" isn't a valid mailbox name. */
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch "Invalid mailbox name");
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch if (ns_sep != list_sep && box->list->set.escape_char == '\0' &&
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch mail_storage_set_error(box->storage, MAIL_ERROR_PARAMS, t_strdup_printf(
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch "Character not allowed in mailbox name: '%c'", list_sep));
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch !box->storage->set->mail_full_filesystem_access) {
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch mail_storage_set_error(box->storage, MAIL_ERROR_PARAMS,
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch "Invalid mailbox name: Begins with hierarchy separator");
const char *path;
&path) < 0)
return TRUE;
return FALSE;
const char *name)
NAMESPACE_FLAG_LIST_CHILDREN)) == 0)
return TRUE;
return FALSE;
case MAIL_ERROR_NOTFOUND:
int ret;
case MAIL_ERROR_NOTFOUND:
MAIL_STORAGE_CLASS_FLAG_OPEN_STREAMS) == 0) {
T_BEGIN {
} T_END;
} T_END;
if (ret < 0) {
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
const char *index_dir;
int ret;
&index_dir);
if (ret <= 0)
int ret;
return ret;
const char *name1;
return FALSE;
return TRUE;
bool directory)
int ret;
if (ret == 0)
return ret;
int ret;
return ret;
int ret;
if (ret < 0)
if (del)
int ret;
return ret;
int ret;
return ret;
const char **error_r)
return TRUE;
return FALSE;
return FALSE;
return TRUE;
const char **error_r)
return FALSE;
return FALSE;
return FALSE;
return TRUE;
struct mail_namespace *
return FALSE;
i_unreached();
const char **str_r)
const unsigned char *data;
int ret;
return ret;
int ret;
return ret;
struct mailbox_attribute_iter *
const char *prefix)
struct mailbox_sync_context *
T_BEGIN {
} T_END;
return ctx;
const char *errormsg;
int ret;
if (ret == 0)
return ret;
struct mail_search_context *
int ret;
return ret;
bool tryagain;
if (!tryagain)
return FALSE;
return TRUE;
return FALSE;
return TRUE;
int ret;
if (ret < 0)
return ret;
struct mailbox_transaction_context *
return trans;
int ret;
return ret;
int ret;
T_BEGIN {
} T_END;
return ret;
struct mailbox *
return t->box;
struct mail_save_context *
return ctx;
const char *const *keywords_list;
const char *envelope)
unsigned int order)
int ret;
if (ret < 0) {
int ret;
if (pvt_flags != 0)
t->save_count++;
return ret;
struct mailbox_transaction_context *
int ret;
if (ret == 0) {
if (pvt_flags != 0)
t->save_count++;
return ret;
const char **path_r)
int ret;
if (ret < 0) {
return ret;
int *fd_r)
int fd;
const char *root_dir;
int ret;
return ret;
&mail_dir) < 0)
unsigned int secs)
#ifndef MMAP_CONFLICTS_WRITE
return index_flags;