bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2007-2018 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"
7a7d2aa11e46195e2d92d6c337d7e78052a5ce67Timo Sirainen#include "mailbox-list-private.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,
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen const char *vname, enum mailbox_flags flags)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct cydir_mailbox *mbox;
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
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen index_storage_mailbox_alloc(&mbox->box, vname, flags, MAIL_INDEX_PREFIX);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
a97fdf205b182250b0fe56c0f6f418bc22fb09a3Josef 'Jeff' Sipek mbox->storage = CYDIR_STORAGE(storage);
d22301419109ed4a38351715e6760011421dadecTimo Sirainen return &mbox->box;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenstatic int cydir_mailbox_open(struct mailbox *box)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen const char *box_path = mailbox_get_path(box);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct stat st;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo 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,
bdb026e2dc8a7c77585ed5ba489f0056df8074d4Timo Sirainen T_MAIL_ERR_MAILBOX_NOT_FOUND(box->vname));
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen return -1;
b42697a5749b85659a24316d97f1c208d469e4e8Timo Sirainen } else if (errno == EACCES) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mailbox_set_critical(box, "%s",
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen mail_error_eacces_msg("stat", box_path));
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen return -1;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen } else {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mailbox_set_critical(box, "stat(%s) failed: %m", box_path);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen return -1;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen if (index_storage_mailbox_open(box, FALSE) < 0)
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen return -1;
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen mail_index_set_fsync_mode(box->index,
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen box->storage->set->parsed_fsync_mode,
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen MAIL_INDEX_FSYNC_MASK_APPENDS |
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen MAIL_INDEX_FSYNC_MASK_EXPUNGES);
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen return 0;
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{
3d6fdafca17c073606b63745ca8638e035e871f4Timo Sirainen int ret;
3d6fdafca17c073606b63745ca8638e035e871f4Timo Sirainen
3d6fdafca17c073606b63745ca8638e035e871f4Timo Sirainen if ((ret = index_storage_mailbox_create(box, directory)) <= 0)
3d6fdafca17c073606b63745ca8638e035e871f4Timo Sirainen return ret;
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{
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen if (box->notify_callback == NULL)
7e2671b295927b461adc8b6c4ed6a1c4761fb323Timo Sirainen mailbox_watch_remove_all(box);
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen else
7e2671b295927b461adc8b6c4ed6a1c4761fb323Timo Sirainen mailbox_watch_add(box, mailbox_get_path(box));
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstruct mail_storage cydir_storage = {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .name = CYDIR_STORAGE_NAME,
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen .class_flags = MAIL_STORAGE_CLASS_FLAG_FILE_PER_MSG |
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen MAIL_STORAGE_CLASS_FLAG_BINARY_DATA,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .v = {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen NULL,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen cydir_storage_alloc,
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen NULL,
c6afd726060aae56b6622c6c52aec10231c4bf1cTimo Sirainen index_storage_destroy,
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen NULL,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen cydir_storage_get_list_settings,
1108376e39a19912e8394e64e19b1bc6f6691cf6Timo Sirainen NULL,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen cydir_mailbox_alloc,
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen NULL,
857c471c13ca215f4be9dd4b336b742b8d434e31Timo Sirainen NULL,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen};
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenstruct mailbox cydir_mailbox = {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .v = {
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_storage_is_readonly,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen index_storage_mailbox_enable,
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen index_storage_mailbox_exists,
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,
4b7cc6ef2e9d848f275965789165939649b6a4deTimo Sirainen index_mailbox_get_metadata,
6469cf211a57433335641725dc236ebb2b9fdd3bTimo Sirainen index_storage_set_subscribed,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_set,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_get,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_iter_init,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_iter_next,
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen index_storage_attribute_iter_deinit,
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen index_storage_list_index_has_changed,
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen index_storage_list_index_update_sync,
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,
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen NULL,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_mail_alloc,
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,
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen cydir_transaction_save_commit_pre,
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen cydir_transaction_save_commit_post,
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen cydir_transaction_save_rollback,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen index_storage_is_inconsistent
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen }
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen};