cydir-storage.c revision 4b7cc6ef2e9d848f275965789165939649b6a4de
bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "lib.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "mail-copy.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "index-mail.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "mailbox-list-private.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "cydir-sync.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "cydir-storage.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include <sys/stat.h>
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschextern struct mail_storage cydir_storage;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschextern struct mailbox cydir_mailbox;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic struct mail_storage *cydir_storage_alloc(void)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct cydir_storage *storage;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch pool_t pool;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch pool = pool_alloconly_create("cydir storage", 512+256);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch storage = p_new(pool, struct cydir_storage, 1);
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch storage->storage = cydir_storage;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch storage->storage.pool = pool;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return &storage->storage;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic void
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschcydir_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch struct mailbox_list_settings *set)
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch{
f883bf3eff62f5d27df5ee9ee664edc38a77937fStephan Bosch if (set->layout == NULL)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch set->layout = MAILBOX_LIST_NAME_FS;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (set->subscription_fname == NULL)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch set->subscription_fname = CYDIR_SUBSCRIPTION_FILE_NAME;
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch}
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Boschstatic struct mailbox *
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschcydir_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch const char *vname, enum mailbox_flags flags)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch struct cydir_mailbox *mbox;
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch pool_t pool;
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch /* cydir can't work without index files */
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch flags &= ~MAILBOX_FLAG_NO_INDEX_FILES;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch pool = pool_alloconly_create("cydir mailbox", 1024*3);
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch mbox = p_new(pool, struct cydir_mailbox, 1);
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch mbox->box = cydir_mailbox;
f883bf3eff62f5d27df5ee9ee664edc38a77937fStephan Bosch mbox->box.pool = pool;
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch mbox->box.storage = storage;
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch mbox->box.list = list;
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch mbox->box.mail_vfuncs = &cydir_mail_vfuncs;
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch index_storage_mailbox_alloc(&mbox->box, vname, flags, MAIL_INDEX_PREFIX);
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch mbox->storage = CYDIR_STORAGE(storage);
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch return &mbox->box;
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch}
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Boschstatic int cydir_mailbox_open(struct mailbox *box)
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch{
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch const char *box_path = mailbox_get_path(box);
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch struct stat st;
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch if (stat(box_path, &st) == 0) {
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch /* exists, open it */
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch } else if (errno == ENOENT) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname));
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return -1;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch } else if (errno == EACCES) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch mailbox_set_critical(box, "%s",
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch mail_error_eacces_msg("stat", box_path));
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return -1;
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody } else {
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody mailbox_set_critical(box, "stat(%s) failed: %m", box_path);
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody return -1;
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody }
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody if (index_storage_mailbox_open(box, FALSE) < 0)
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody return -1;
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody mail_index_set_fsync_mode(box->index,
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody box->storage->set->parsed_fsync_mode,
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody MAIL_INDEX_FSYNC_MASK_APPENDS |
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody MAIL_INDEX_FSYNC_MASK_EXPUNGES);
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody return 0;
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody}
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmodystatic int
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmodycydir_mailbox_create(struct mailbox *box, const struct mailbox_update *update,
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody bool directory)
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody{
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody int ret;
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody if ((ret = index_storage_mailbox_create(box, directory)) <= 0)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return ret;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch return update == NULL ? 0 :
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_storage_mailbox_update(box, update);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstatic void cydir_notify_changes(struct mailbox *box)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (box->notify_callback == NULL)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch mailbox_watch_remove_all(box);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch else
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch mailbox_watch_add(box, mailbox_get_path(box));
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschstruct mail_storage cydir_storage = {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch .name = CYDIR_STORAGE_NAME,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch .class_flags = MAIL_STORAGE_CLASS_FLAG_FILE_PER_MSG |
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch MAIL_STORAGE_CLASS_FLAG_BINARY_DATA,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch .v = {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch NULL,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch cydir_storage_alloc,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch NULL,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_storage_destroy,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch NULL,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch cydir_storage_get_list_settings,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch NULL,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch cydir_mailbox_alloc,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch NULL,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch NULL,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch};
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Boschstruct mailbox cydir_mailbox = {
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch .v = {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_storage_is_readonly,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_storage_mailbox_enable,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch index_storage_mailbox_exists,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch cydir_mailbox_open,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_storage_mailbox_close,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_storage_mailbox_free,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch cydir_mailbox_create,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch index_storage_mailbox_update,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_storage_mailbox_delete,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_storage_mailbox_rename,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch index_storage_get_status,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch index_mailbox_get_metadata,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_storage_set_subscribed,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_storage_attribute_set,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_storage_attribute_get,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch index_storage_attribute_iter_init,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch index_storage_attribute_iter_next,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_storage_attribute_iter_deinit,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_storage_list_index_has_changed,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_storage_list_index_update_sync,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch cydir_storage_sync_init,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch index_mailbox_sync_next,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch index_mailbox_sync_deinit,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch NULL,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch cydir_notify_changes,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_transaction_begin,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_transaction_commit,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch index_transaction_rollback,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch NULL,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_mail_alloc,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_storage_search_init,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch index_storage_search_deinit,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch index_storage_search_next_nonblock,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch index_storage_search_next_update_seq,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch cydir_save_alloc,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch cydir_save_begin,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch cydir_save_continue,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch cydir_save_finish,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch cydir_save_cancel,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch mail_storage_copy,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch cydir_transaction_save_commit_pre,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch cydir_transaction_save_commit_post,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch cydir_transaction_save_rollback,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch index_storage_is_inconsistent
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch};
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch