sdbox-storage.c revision 7bafda1813454621e03615e83d55bccfa7cc56bd
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen MODULE_CONTEXT(obj, sdbox_mailbox_list_module)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenextern struct dbox_storage_vfuncs sdbox_dbox_storage_vfuncs;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(sdbox_mailbox_list_module,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic struct mail_storage *sdbox_storage_alloc(void)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen pool = pool_alloconly_create("dbox storage", 512+256);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen storage = p_new(pool, struct sdbox_storage, 1);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen storage->storage.v = sdbox_dbox_storage_vfuncs;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainensdbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* dbox can't work without index files */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen pool = pool_alloconly_create("dbox mailbox", 1024+512);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->ibox.save_commit_pre = sdbox_transaction_save_commit_pre;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->ibox.save_commit_post = sdbox_transaction_save_commit_post;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->ibox.save_rollback = sdbox_transaction_save_rollback;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_mailbox_alloc(&mbox->ibox, name, input, flags,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->ibox.index_flags |= MAIL_INDEX_OPEN_FLAG_KEEP_BACKUPS |
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mbox->storage = (struct sdbox_storage *)storage;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_ext_register(mbox->ibox.index, "dbox-hdr",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sizeof(struct sdbox_index_header), 0, 0);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint sdbox_read_header(struct sdbox_mailbox *mbox,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_get_header_ext(mbox->ibox.view, mbox->hdr_ext_id,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (data_size < SDBOX_INDEX_HEADER_MIN_SIZE &&
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_storage_set_critical(&mbox->storage->storage.storage,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "dbox %s: Invalid dbox header size",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr)));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid sdbox_update_header(struct sdbox_mailbox *mbox,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (update != NULL && !mail_guid_128_is_empty(update->mailbox_guid)) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen memcpy(new_hdr.mailbox_guid, update->mailbox_guid,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen } else if (mail_guid_128_is_empty(new_hdr.mailbox_guid)) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (memcmp(&hdr, &new_hdr, sizeof(hdr)) != 0) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_update_header_ext(trans, mbox->hdr_ext_id, 0,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic int sdbox_write_index_header(struct mailbox *box,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen trans = mail_index_transaction_begin(mbox->ibox.view, 0);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (update != NULL && update->uid_validity != 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* set uidvalidity */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen uid_validity = dbox_get_uidvalidity_next(box->list);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen offsetof(struct mail_index_header, uid_validity),
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (update != NULL && hdr->next_uid < update->min_next_uid) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (update != NULL && update->min_highest_modseq != 0 &&
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_modseq_get_highest(mbox->ibox.view) <
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (mail_index_transaction_commit(&trans) < 0) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_storage_set_internal_error(box->storage);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic int sdbox_mailbox_create_indexes(struct mailbox *box,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mailbox_list_get_dir_permissions(box->list, NULL, &mode, &gid, &origin);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (mkdir_parents_chgrp(box->path, mode, gid, origin) == 0) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* create indexes immediately with the dbox header */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (!mail_storage_set_error_from_errno(box->storage)) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void sdbox_storage_get_status_guid(struct mailbox *box,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (mail_guid_128_is_empty(hdr.mailbox_guid)) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* regenerate it */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (sdbox_write_index_header(box, NULL) < 0 ||
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen memcpy(status_r->mailbox_guid, hdr.mailbox_guid,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainendbox_storage_get_status(struct mailbox *box, enum mailbox_status_items items,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_storage_get_status(box, items, status_r);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainendbox_mailbox_update(struct mailbox *box, const struct mailbox_update *update)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainensdbox_list_delete_mailbox(struct mailbox_list *list, const char *name)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_mailbox_list *mlist = SDBOX_LIST_CONTEXT(list);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* Make sure the indexes are closed before trying to delete the
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen directory that contains them. It can still fail with some NFS
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen implementations if indexes are opened by another session, but
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen that can't really be helped. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* delete the index and control directories */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (mlist->module_ctx.super.delete_mailbox(list, name) < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if ((ret = dbox_list_delete_mailbox1(list, name, &trash_dest)) < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return dbox_list_delete_mailbox2(list, name, ret, trash_dest);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainensdbox_list_rename_mailbox(struct mailbox_list *oldlist, const char *oldname,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mailbox_list *newlist, const char *newname,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_mailbox_list *oldmlist = SDBOX_LIST_CONTEXT(oldlist);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen rename_mailbox(oldlist, oldname, newlist, newname,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen return dbox_list_rename_mailbox(oldlist, oldname, newlist, newname,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void sdbox_storage_add_list(struct mail_storage *storage ATTR_UNUSED,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mlist = p_new(list->pool, struct sdbox_mailbox_list, 1);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen list->v.iter_is_mailbox = dbox_list_iter_is_mailbox;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen list->v.delete_mailbox = sdbox_list_delete_mailbox;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen list->v.rename_mailbox = sdbox_list_rename_mailbox;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen list->v.rename_mailbox_pre = dbox_list_rename_mailbox_pre;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen MODULE_CONTEXT_SET(list, sdbox_mailbox_list_module, mlist);