cydir-storage.c revision 3b32bc12710240f86465a00fbb2bd1ef030e6c40
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "lib.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "mail-copy.h"
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen#include "index-mail.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "cydir-sync.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "cydir-storage.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include <sys/stat.h>
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenextern struct mail_storage cydir_storage;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenextern struct mailbox cydir_mailbox;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstatic struct mail_storage *cydir_storage_alloc(void)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct cydir_storage *storage;
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen pool_t pool;
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen pool = pool_alloconly_create("cydir storage", 512+256);
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen storage = p_new(pool, struct cydir_storage, 1);
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen storage->storage = cydir_storage;
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen storage->storage.pool = pool;
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen return &storage->storage;
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen}
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstatic void
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainencydir_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct mailbox_list_settings *set)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen{
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (set->layout == NULL)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen set->layout = MAILBOX_LIST_NAME_FS;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (set->subscription_fname == NULL)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen set->subscription_fname = CYDIR_SUBSCRIPTION_FILE_NAME;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen}
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstatic struct mailbox *
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainencydir_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen const char *name, enum mailbox_flags flags)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct cydir_mailbox *mbox;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen struct index_mailbox_context *ibox;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen pool_t pool;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen /* cydir can't work without index files */
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen flags &= ~MAILBOX_FLAG_NO_INDEX_FILES;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
3b32bc12710240f86465a00fbb2bd1ef030e6c40Timo Sirainen pool = pool_alloconly_create("cydir mailbox", 1024*3);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen mbox = p_new(pool, struct cydir_mailbox, 1);
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mbox->box = cydir_mailbox;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mbox->box.pool = pool;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mbox->box.storage = storage;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mbox->box.list = list;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mbox->box.mail_vfuncs = &cydir_mail_vfuncs;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen index_storage_mailbox_alloc(&mbox->box, name, flags,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen CYDIR_INDEX_PREFIX);
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mail_index_set_fsync_types(mbox->box.index,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen MAIL_INDEX_SYNC_TYPE_APPEND |
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen MAIL_INDEX_SYNC_TYPE_EXPUNGE);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
d22301419109ed4a38351715e6760011421dadecTimo Sirainen ibox = INDEX_STORAGE_CONTEXT(&mbox->box);
d22301419109ed4a38351715e6760011421dadecTimo Sirainen ibox->save_commit_pre = cydir_transaction_save_commit_pre;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen ibox->save_commit_post = cydir_transaction_save_commit_post;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen ibox->save_rollback = cydir_transaction_save_rollback;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen mbox->storage = (struct cydir_storage *)storage;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen return &mbox->box;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenstatic int cydir_mailbox_open(struct mailbox *box)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct stat st;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen if (stat(box->path, &st) == 0) {
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen /* exists, open it */
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen } else if (errno == ENOENT) {
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name));
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen return -1;
b42697a5749b85659a24316d97f1c208d469e4e8Timo Sirainen } else if (errno == EACCES) {
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen mail_storage_set_critical(box->storage, "%s",
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen mail_error_eacces_msg("stat", box->path));
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen return -1;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen } else {
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen mail_storage_set_critical(box->storage, "stat(%s) failed: %m",
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen box->path);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen return -1;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
d22301419109ed4a38351715e6760011421dadecTimo Sirainen return index_storage_mailbox_open(box, FALSE);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainenstatic int
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainencydir_mailbox_create(struct mailbox *box, const struct mailbox_update *update,
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen bool directory)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen if (directory &&
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen (box->list->props & MAILBOX_LIST_PROP_NO_NOSELECT) == 0)
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen return 0;
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen return update == NULL ? 0 :
9ffdc9d18870acef2e4dde99715d8528ff4b080dTimo Sirainen index_storage_mailbox_update(box, update);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainenstatic void cydir_notify_changes(struct mailbox *box)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct cydir_mailbox *mbox = (struct cydir_mailbox *)box;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen if (box->notify_callback == NULL)
d22301419109ed4a38351715e6760011421dadecTimo Sirainen index_mailbox_check_remove_all(&mbox->box);
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen else
d22301419109ed4a38351715e6760011421dadecTimo Sirainen index_mailbox_check_add(&mbox->box, mbox->box.path);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstruct mail_storage cydir_storage = {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .name = CYDIR_STORAGE_NAME,
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .class_flags = 0,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .v = {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen NULL,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen cydir_storage_alloc,
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen NULL,
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen NULL,
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen NULL,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen cydir_storage_get_list_settings,
1108376e39a19912e8394e64e19b1bc6f6691cf6Timo Sirainen NULL,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen cydir_mailbox_alloc,
3e564425db51f3921ce4de11859777135fdedd15Timo Sirainen NULL
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen};
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstruct mailbox cydir_mailbox = {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .v = {
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_storage_is_readonly,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_storage_allow_new_keywords,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen index_storage_mailbox_enable,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen cydir_mailbox_open,
09c08fad8e7cc694a6c8d1711e67839acd3a2f04Timo Sirainen index_storage_mailbox_close,
438f12d7a776da695019114884b48188d94613efTimo Sirainen index_storage_mailbox_free,
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen cydir_mailbox_create,
9ffdc9d18870acef2e4dde99715d8528ff4b080dTimo Sirainen index_storage_mailbox_update,
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen index_storage_mailbox_delete,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen index_storage_mailbox_rename,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_storage_get_status,
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen NULL,
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen NULL,
fbd918f47f591f8084fd52b207ef29515ddd11b9Timo Sirainen NULL,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cydir_storage_sync_init,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mailbox_sync_next,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mailbox_sync_deinit,
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen NULL,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cydir_notify_changes,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_transaction_begin,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_transaction_commit,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_transaction_rollback,
48270badadd82279bfe50ae3d187aea8b0b2b30eTimo Sirainen index_transaction_set_max_modseq,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_keywords_create,
14ab4610b6038da6c5d0814fecabc6b74bc81a6bTimo Sirainen index_keywords_create_from_indexes,
84ed9f8f3d0e5ed47607ef417618e49e4f865557Timo Sirainen index_keywords_ref,
84ed9f8f3d0e5ed47607ef417618e49e4f865557Timo Sirainen index_keywords_unref,
e3796bfd2bc0fd5ba664893d346df9334a5b3af0Timo Sirainen index_keyword_is_valid,
5afa8e2edf4f313cd56e5909f92f39c3b5b7b4d3Timo Sirainen index_storage_get_seq_range,
408e5be344c9131fdebe771718a5bf49f88cc51cTimo Sirainen index_storage_get_uid_range,
370b60cfccff7c50586fc30f4f591499a55301a8Timo Sirainen index_storage_get_expunges,
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen NULL,
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen NULL,
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen NULL,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_alloc,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_header_lookup_init,
de58be41126e5d68008d2ea706d62ccdc1f29337Timo Sirainen index_header_lookup_deinit,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_storage_search_init,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_storage_search_deinit,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_storage_search_next_nonblock,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_storage_search_next_update_seq,
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen cydir_save_alloc,
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen cydir_save_begin,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cydir_save_continue,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cydir_save_finish,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cydir_save_cancel,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen mail_storage_copy,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_storage_is_inconsistent
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen};