mail-storage.c revision 34c28a6c5bd2089a09ef6105da31418e2d6c21d5
bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Boschstruct mail_storage_module_register mail_storage_module_register = { 0 };
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschstruct mail_module_register mail_module_register = { 0 };
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschstruct mail_storage_mail_index_module mail_storage_mail_index_module =
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch MODULE_CONTEXT_INIT(&mail_index_module_register);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid mail_storage_class_register(struct mail_storage *storage_class)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch i_assert(mail_storage_find_class(storage_class->name) == NULL);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* append it after the list, so the autodetection order is correct */
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch array_append(&mail_storage_classes, &storage_class, 1);
f883bf3eff62f5d27df5ee9ee664edc38a77937fStephan Boschvoid mail_storage_class_unregister(struct mail_storage *storage_class)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch unsigned int i, count;
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch classes = array_get(&mail_storage_classes, &count);
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch for (i = 0; i < count; i++) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschstruct mail_storage *mail_storage_find_class(const char *name)
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch unsigned int i, count;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch classes = array_get(&mail_storage_classes, &count);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch for (i = 0; i < count; i++) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschmail_storage_autodetect(const struct mail_namespace *ns,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch unsigned int i, count;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch classes = array_get(&mail_storage_classes, &count);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch for (i = 0; i < count; i++) {
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Boschmail_storage_set_autodetection(const char **data, const char **driver)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const char *p;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* check if data is in driver:data format (eg. mbox:~/mail) */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch while (i_isalnum(*p)) p++;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* no autodetection if the storage driver is given. */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschmail_storage_get_class(struct mail_namespace *ns, const char *driver,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const char **error_r)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch storage_class = mail_storage_find_class(driver);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch storage_class->v.get_list_settings(ns, list_set);
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch storage_class = mail_storage_autodetect(ns, list_set);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (ns->set->location == NULL || *ns->set->location == '\0') {
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch if (home == NULL || *home == '\0') home = "(not set)";
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch "Mail storage autodetection failed with home=%s", home);
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch "Ambiguous mail location setting, "
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch "don't know what to do with it: %s "
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Bosch "(try prefixing it with mbox: or maildir:)",
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschmail_storage_create_root(struct mailbox_list *list,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch enum mail_storage_flags flags, const char **error_r)
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch /* storage doesn't use directories (e.g. shared root) */
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch *error_r = mail_error_eacces_msg("stat", root_dir);
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Bosch } else if (errno != ENOENT && errno != ENOTDIR) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch *error_r = t_strdup_printf("stat(%s) failed: %m", root_dir);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch } else if (list->ns->type == NAMESPACE_SHARED) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* can't create a new user, but we don't want to fail
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch the storage creation. */
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch } else if ((flags & MAIL_STORAGE_FLAG_NO_AUTOCREATE) != 0) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch "Root mail directory doesn't exist: %s", root_dir);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* we need to create the root directory. */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch mailbox_list_get_dir_permissions(list, NULL, &mode, &gid, &origin);
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch if (mkdir_parents_chgrp(root_dir, mode, gid, origin) < 0 &&
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch *error_r = mail_error_create_eacces_msg("mkdir", root_dir);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* created */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch struct mail_storage *storage = user->storages;
17c29e3e2246972c3d988e05d91b9286398a624fStephan Bosch for (; storage != NULL; storage = storage->next) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (strcmp(storage->name, storage_class->name) == 0 &&
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch strcmp(storage->unique_root_dir, set->root_dir) == 0))
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschint mail_storage_create(struct mail_namespace *ns, const char *driver,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch enum mail_storage_flags flags, const char **error_r)
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch struct mail_storage *storage_class, *storage = NULL;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const char *p;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if ((flags & MAIL_STORAGE_FLAG_KEEP_HEADER_MD5) == 0 &&
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch /* if pop3_uidl_format contains %m, we want to keep the
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch header MD5 sums stored even if we're not running POP3
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch right now. */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* autodetect */
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch } else if (driver != NULL && strcmp(driver, "shared") == 0) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* internal shared namespace */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch mail_storage_set_autodetection(&data, &driver);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (mailbox_list_settings_parse(data, &list_set, ns,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if ((list_set.root_dir == NULL || *list_set.root_dir == '\0') &&
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch (flags & MAIL_STORAGE_FLAG_NO_AUTODETECTION) != 0)) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch storage_class = mail_storage_get_class(ns, driver, &list_set, error_r);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* first storage for namespace */
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch if (mail_storage_is_mailbox_file(storage_class))
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch list_flags |= MAILBOX_LIST_FLAG_MAILBOX_FILES;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (mailbox_list_create(list_set.layout, ns, &list_set,
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch *error_r = t_strdup_printf("Mailbox list driver %s: %s",
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (mail_storage_create_root(ns->list, flags, error_r) < 0)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch storage = mail_storage_find(ns->user, storage_class, &list_set);
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch /* using an existing storage */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch p_array_init(&storage->module_contexts, storage->pool, 5);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch storage->v.create(storage, ns, error_r) < 0) {
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch *error_r = t_strdup_printf("%s: %s", storage->name, *error_r);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid mail_storage_ref(struct mail_storage *storage)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid mail_storage_unref(struct mail_storage **_storage)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* set *_storage=NULL only after calling destroy() callback.
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch for example mdbox wants to access ns->storage */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch DLLIST_REMOVE(&storage->user->storages, storage);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid mail_storage_clear_error(struct mail_storage *storage)
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Boschvoid mail_storage_set_error(struct mail_storage *storage,
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Boschvoid mail_storage_set_internal_error(struct mail_storage *storage)
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Bosch i_strdup(str) : i_strdup(MAIL_ERRSTR_CRITICAL_MSG);
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Boschvoid mail_storage_set_critical(struct mail_storage *storage,
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Bosch const char *fmt, ...)
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Bosch /* critical errors may contain sensitive data, so let user
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Bosch see only "Internal error" with a timestamp to make it
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Bosch easier to look from log files the actual error message. */
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Boschvoid mail_storage_copy_list_error(struct mail_storage *storage,
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Bosch const char *str;
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Bosch str = mailbox_list_get_last_error(list, &error);
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Boschvoid mail_storage_set_index_error(struct mailbox *box)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch mail_storage_set_internal_error(box->storage);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschmail_storage_get_settings(struct mail_storage *storage)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschstruct mail_user *mail_storage_get_user(struct mail_storage *storage)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid mail_storage_set_callbacks(struct mail_storage *storage,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschint mail_storage_purge(struct mail_storage *storage)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschconst char *mail_storage_get_last_error(struct mail_storage *storage,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* We get here only in error situations, so we have to return some
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch error. If storage->error is NONE, it means we forgot to set it at
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch some point.. */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch return storage->error_string != NULL ? storage->error_string :
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch "BUG: Unknown internal error";
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* This shouldn't happen.. */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschbool mail_storage_is_mailbox_file(struct mail_storage *storage)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch MAIL_STORAGE_CLASS_FLAG_MAILBOX_IS_FILE) != 0;
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Boschbool mail_storage_set_error_from_errno(struct mail_storage *storage)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (!mail_error_from_errno(&error, &error_string))
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch if (storage->set->mail_debug && error != MAIL_ERROR_NOTFOUND) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* debugging is enabled - admin may be debugging a
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch (permission) problem, so return FALSE to get the caller to
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch log the full error message. */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch mail_storage_set_error(storage, error, error_string);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschstruct mailbox *mailbox_alloc(struct mailbox_list *list, const char *name,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (mailbox_list_get_storage(&new_list, &name, &storage) < 0) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* just use the first storage. FIXME: does this break? */
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch box = storage->v.mailbox_alloc(storage, new_list, name, flags);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschstatic int mailbox_open_full(struct mailbox *box, struct istream *input)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (!mailbox_list_is_valid_existing_name(box->list, box->name)) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch mail_storage_set_error(box->storage, MAIL_ERROR_PARAMS,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch "Invalid mailbox name");
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch "Storage doesn't support streamed mailboxes");
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (ret < 0 && box->storage->error == MAIL_ERROR_NOTFOUND &&
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* INBOX should always exist. try to create it and retry. */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (ret < 0 && !box->storage->user->inbox_open_error_logged) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch box->storage->user->inbox_open_error_logged = TRUE;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch mail_storage_get_last_error(box->storage, NULL));
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch box->list->ns->flags |= NAMESPACE_FLAG_USABLE;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschint mailbox_open_stream(struct mailbox *box, struct istream *input)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschint mailbox_enable(struct mailbox *box, enum mailbox_feature features)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschenum mailbox_feature mailbox_get_enabled_features(struct mailbox *box)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch i_panic("Trying to close mailbox %s with open transactions",
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschint mailbox_create(struct mailbox *box, const struct mailbox_update *update,
e9c433c5b8ef9a1b4246ebe10beb90fa01e05cafPhil Carmody if (!mailbox_list_is_valid_create_name(box->list, box->name)) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch mail_storage_set_error(box->storage, MAIL_ERROR_PARAMS,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch "Invalid mailbox name");
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (box->list->v.create_mailbox_dir(box->list, box->name,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch mail_storage_copy_list_error(box->storage, box->list);
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Boschint mailbox_update(struct mailbox *box, const struct mailbox_update *update)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschstatic int mailbox_mark_index_deleted(struct mailbox *box, bool del)
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch enum mail_index_transaction_flags trans_flags = 0;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch trans_flags = del ? 0 : MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL;
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch trans = mail_index_transaction_begin(box->view, trans_flags);
289ce1246b1c7511f8ceec02344316064ffbe546Phil Carmody if (mail_index_transaction_commit(&trans) < 0) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* sync the mailbox. this finishes the index deletion and it can
e87b25495e78a6f61f236b188bfd68070eff3295Phil Carmody succeed only for a single session. we do it here, so the rest of
289ce1246b1c7511f8ceec02344316064ffbe546Phil Carmody the deletion code doesn't have to worry about race conditions. */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch return mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschstatic bool mailbox_try_undelete(struct mailbox *box)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (mail_index_get_modification_time(box->index, &mtime) < 0)
f883bf3eff62f5d27df5ee9ee664edc38a77937fStephan Bosch if (mtime + MAILBOX_DELETE_RETRY_SECS > time(NULL))
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch if (mailbox_mark_index_deleted(box, FALSE) < 0)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch mail_storage_set_error(box->storage, MAIL_ERROR_PARAMS,
e87b25495e78a6f61f236b188bfd68070eff3295Phil Carmody "Storage root can't be deleted");
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
e87b25495e78a6f61f236b188bfd68070eff3295Phil Carmody "INBOX can't be deleted.");
e87b25495e78a6f61f236b188bfd68070eff3295Phil Carmody (void)mail_storage_get_last_error(box->storage, &error);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* \noselect mailbox */
289ce1246b1c7511f8ceec02344316064ffbe546Phil Carmody /* if deletion happened a long time ago, it means it
289ce1246b1c7511f8ceec02344316064ffbe546Phil Carmody crashed while doing it. undelete the mailbox in
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch that case. */
289ce1246b1c7511f8ceec02344316064ffbe546Phil Carmodymail_storages_rename_compatible(struct mail_storage *storage1,
289ce1246b1c7511f8ceec02344316064ffbe546Phil Carmody if (strcmp(storage1->name, storage2->name) != 0)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if ((storage1->class_flags & MAIL_STORAGE_CLASS_FLAG_UNIQUE_ROOT) != 0)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschstatic bool nullequals(const void *p1, const void *p2)
e87b25495e78a6f61f236b188bfd68070eff3295Phil Carmody return (p1 == NULL && p2 == NULL) || (p1 != NULL && p2 != NULL);
e87b25495e78a6f61f236b188bfd68070eff3295Phil Carmodymailbox_lists_rename_compatible(struct mailbox_list *list1,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch return nullequals(list1->set.alt_dir, list2->set.alt_dir) &&
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch nullequals(list1->set.index_dir, list2->set.index_dir) &&
e87b25495e78a6f61f236b188bfd68070eff3295Phil Carmody nullequals(list1->set.control_dir, list2->set.control_dir);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschint mailbox_rename(struct mailbox *src, struct mailbox *dest,
e87b25495e78a6f61f236b188bfd68070eff3295Phil Carmody if (!mailbox_list_is_valid_existing_name(src->list, src->name) ||
289ce1246b1c7511f8ceec02344316064ffbe546Phil Carmody !mailbox_list_is_valid_create_name(dest->list, dest->name)) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch mail_storage_set_error(src->storage, MAIL_ERROR_PARAMS,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch "Invalid mailbox name");
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (!mail_storages_rename_compatible(src->storage, dest->storage) ||
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch !mailbox_lists_rename_compatible(src->list, dest->list)) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch mail_storage_set_error(src->storage, MAIL_ERROR_NOTPOSSIBLE,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch "Can't rename mailboxes across specified storages.");
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (src->list->ns->type != NAMESPACE_PRIVATE ||
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch mail_storage_set_error(src->storage, MAIL_ERROR_NOTPOSSIBLE,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch "Renaming not supported across non-private namespaces.");
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch return src->v.rename(src, dest, rename_children);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschstruct mail_storage *mailbox_get_storage(const struct mailbox *box)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschmailbox_get_namespace(const struct mailbox *box)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschconst struct mail_storage_settings *mailbox_get_settings(struct mailbox *box)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschconst char *mailbox_get_name(const struct mailbox *box)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschconst char *mailbox_get_vname(const struct mailbox *box)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschbool mailbox_allow_new_keywords(struct mailbox *box)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschbool mailbox_backends_equal(const struct mailbox *box1,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch struct mail_namespace *ns1 = box1->list->ns, *ns2 = box2->list->ns;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschint mailbox_get_guid(struct mailbox *box, uint8_t guid[MAIL_GUID_128_SIZE])
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch "Storage doesn't support mailbox GUIDs");
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschmailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch i_panic("Trying to sync mailbox %s with open transactions",
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschbool mailbox_sync_next(struct mailbox_sync_context *ctx,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch return ctx->box->v.sync_next(ctx, sync_rec_r);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschint mailbox_sync_deinit(struct mailbox_sync_context **_ctx,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch !box->storage->user->inbox_open_error_logged) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch errormsg = mail_storage_get_last_error(box->storage, &error);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch box->storage->user->inbox_open_error_logged = TRUE;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch i_error("Syncing INBOX failed: %s", errormsg);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschint mailbox_sync(struct mailbox *box, enum mailbox_sync_flags flags)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* we don't care about mailbox's current state, so we might
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch as well fix inconsistency state */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid mailbox_notify_changes(struct mailbox *box, unsigned int min_interval,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch mailbox_notify_callback_t *callback, void *context)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid mailbox_notify_changes_stop(struct mailbox *box)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschint mailbox_keywords_create(struct mailbox *box, const char *const keywords[],
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch return box->v.keywords_create(box, keywords, keywords_r, FALSE);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschmailbox_keywords_create_valid(struct mailbox *box,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const char *const keywords[])
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (box->v.keywords_create(box, keywords, &kw, TRUE) < 0)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschmailbox_keywords_create_from_indexes(struct mailbox *box,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch return box->v.keywords_create_from_indexes(box, idx);
639bb36b12b9f9bb54c8bb1be50eac623622f8a0Timo Sirainenvoid mailbox_keywords_ref(struct mailbox *box, struct mail_keywords *keywords)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid mailbox_keywords_unref(struct mailbox *box,
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Boschbool mailbox_keyword_is_valid(struct mailbox *box, const char *keyword,
4c8646ca7a1bfe3e5a43f1f3e329f8ff8c24d851Stephan Bosch const char **error_r)
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch return box->v.keyword_is_valid(box, keyword, error_r);
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Boschvoid mailbox_get_seq_range(struct mailbox *box, uint32_t uid1, uint32_t uid2,
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch box->v.get_seq_range(box, uid1, uid2, seq1_r, seq2_r);
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Boschvoid mailbox_get_uid_range(struct mailbox *box,
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Boschbool mailbox_get_expunges(struct mailbox *box, uint64_t prev_modseq,
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Boschbool mailbox_get_virtual_uid(struct mailbox *box, const char *backend_mailbox,
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch return box->v.get_virtual_uid(box, backend_mailbox, backend_uidvalidity,
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Boschvoid mailbox_get_virtual_backend_boxes(struct mailbox *box,
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch box->v.get_virtual_backend_boxes(box, mailboxes, only_with_msgs);
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Boschvoid mailbox_get_virtual_box_patterns(struct mailbox *box,
289ce1246b1c7511f8ceec02344316064ffbe546Phil Carmody ARRAY_TYPE(mailbox_virtual_patterns) *includes,
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch ARRAY_TYPE(mailbox_virtual_patterns) *excludes)
4d955db590c3d76a631dfc5d37bcdf578a43e55aStephan Bosch if (box->v.get_virtual_box_patterns == NULL) {
baf3e87e186453fda13bd21f7cbcb2efc8492e8bTimo Sirainen box->v.get_virtual_box_patterns(box, includes, excludes);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschmailbox_header_lookup_init(struct mailbox *box, const char *const headers[])
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch return box->v.header_lookup_init(box, headers);
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)
int ret;
if (ret < 0) {
int ret;
return ret;
int ret;
return ret;
int *fd_r)
int fd;