raw-storage.c revision 744543d840a229fe893843046d143186971560e2
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2007-2012 Dovecot authors, see the included COPYING file */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "lib.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "ioloop.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "istream.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "index-mail.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "mail-copy.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "mailbox-list-private.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "raw-sync.h"
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainen#include "raw-storage.h"
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenextern struct mail_storage raw_storage;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenextern struct mailbox raw_mailbox;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstruct mail_user *
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenraw_storage_create_from_set(const struct setting_parser_info *set_info,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const struct mail_user_settings *set)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct mail_user *user;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct mail_namespace *ns;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct mail_namespace_settings *ns_set;
da7f1a07f583df8905684a7b78469960afd7c78dPhil Carmody const char *error;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen user = mail_user_alloc("raw mail user", set_info, set);
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen user->autocreated = TRUE;
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen mail_user_set_home(user, "/");
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen if (mail_user_init(user, &error) < 0)
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen i_fatal("Raw user initialization failed: %s", error);
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen ns_set = p_new(user->pool, struct mail_namespace_settings, 1);
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen ns_set->name = "raw-storage";
da7f1a07f583df8905684a7b78469960afd7c78dPhil Carmody ns_set->location = ":LAYOUT=none";
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen ns_set->separator = "/";
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ns = mail_namespaces_init_empty(user);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* raw storage doesn't have INBOX. We especially don't want LIST to
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return INBOX. */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ns->flags &= ~NAMESPACE_FLAG_INBOX_USER;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ns->flags |= NAMESPACE_FLAG_NOQUOTA | NAMESPACE_FLAG_NOACL;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ns->set = ns_set;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (mail_storage_create(ns, "raw", 0, &error) < 0)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_fatal("Couldn't create internal raw storage: %s", error);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return user;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
263fa7b43fb222f9805b80f62090907fe3f9ec13Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic int ATTR_NULL(2, 3)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenraw_mailbox_alloc_common(struct mail_user *user, struct istream *input,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *path, time_t received_time,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *envelope_sender, struct mailbox **box_r)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct mail_namespace *ns = user->namespaces;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct mailbox *box;
8ae72ad7d0c69e972cfa65d1e2ce4e3e9a8b765cTimo Sirainen struct raw_mailbox *raw_box;
f7f25f9e1a38678d0e97d2e609beac16285fac6bTimo Sirainen const char *name;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen name = path != NULL ? path : i_stream_get_name(input);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen box = *box_r = mailbox_alloc(ns->list, name,
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen MAILBOX_FLAG_NO_INDEX_FILES);
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen if (input != NULL) {
35fcdde46a71ac151c2518d48c841019f1181bb2Timo Sirainen if (mailbox_open_stream(box, input) < 0)
35fcdde46a71ac151c2518d48c841019f1181bb2Timo Sirainen return -1;
35fcdde46a71ac151c2518d48c841019f1181bb2Timo Sirainen } else {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (mailbox_open(box) < 0)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return -1;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (mailbox_sync(box, 0) < 0)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return -1;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_assert(strcmp(box->storage->name, RAW_STORAGE_NAME) == 0);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen raw_box = (struct raw_mailbox *)box;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen raw_box->envelope_sender = envelope_sender;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen raw_box->mtime = received_time;
5733207dc3ec10e6e5a6e0a8b30fbd1b061062b9Timo Sirainen return 0;
cf7857bce68a33cdabe88bb15568e21921eb5ac7Aki Tuomi}
2adcf55dd8b0380cb2f1d2fd53accf448053d5d3Timo Sirainen
2adcf55dd8b0380cb2f1d2fd53accf448053d5d3Timo Sirainenint raw_mailbox_alloc_stream(struct mail_user *user, struct istream *input,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen time_t received_time, const char *envelope_sender,
3e10cd470988298dc2b37f548ad03da4d7c11ffaTimo Sirainen struct mailbox **box_r)
b97e952db93a681968777dfda9728cc92ff0d7c4Timo Sirainen{
b97e952db93a681968777dfda9728cc92ff0d7c4Timo Sirainen return raw_mailbox_alloc_common(user, input, NULL, received_time,
311cf367b949f360c9a90822f06f39df31ec69e3Timo Sirainen envelope_sender, box_r);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenint raw_mailbox_alloc_path(struct mail_user *user, const char *path,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen time_t received_time, const char *envelope_sender,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct mailbox **box_r)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return raw_mailbox_alloc_common(user, NULL, path, received_time,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen envelope_sender, box_r);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
df27aa70a3f0250767eb8a154981cd7f5dadcc91Timo Sirainen
cf7857bce68a33cdabe88bb15568e21921eb5ac7Aki Tuomistatic struct mail_storage *raw_storage_alloc(void)
2adcf55dd8b0380cb2f1d2fd53accf448053d5d3Timo Sirainen{
2adcf55dd8b0380cb2f1d2fd53accf448053d5d3Timo Sirainen struct raw_storage *storage;
861f53be0cc2fa5665f3c107a7576e2a53bb2eb0Timo Sirainen pool_t pool;
3e10cd470988298dc2b37f548ad03da4d7c11ffaTimo Sirainen
74c369c0587c5f6bb13d730675d8bc455c5c3f8eTimo Sirainen pool = pool_alloconly_create("raw storage", 512+256);
74c369c0587c5f6bb13d730675d8bc455c5c3f8eTimo Sirainen storage = p_new(pool, struct raw_storage, 1);
311cf367b949f360c9a90822f06f39df31ec69e3Timo Sirainen storage->storage = raw_storage;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen storage->storage.pool = pool;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return &storage->storage;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenraw_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct mailbox_list_settings *set)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (set->layout == NULL)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen set->layout = MAILBOX_LIST_NAME_FS;
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainen if (set->subscription_fname == NULL)
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainen set->subscription_fname = RAW_SUBSCRIPTION_FILE_NAME;
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainenstatic struct mailbox *
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainenraw_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainen const char *vname, enum mailbox_flags flags)
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainen{
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainen struct raw_mailbox *mbox;
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainen pool_t pool;
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainen
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainen flags |= MAILBOX_FLAG_READONLY | MAILBOX_FLAG_NO_INDEX_FILES;
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainen
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainen pool = pool_alloconly_create("raw mailbox", 1024*3);
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainen mbox = p_new(pool, struct raw_mailbox, 1);
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainen mbox->box = raw_mailbox;
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainen mbox->box.pool = pool;
935960e45571872e38f730964f8ca1d116a1b532Timo Sirainen mbox->box.storage = storage;
mbox->box.list = list;
mbox->box.mail_vfuncs = &raw_mail_vfuncs;
index_storage_mailbox_alloc(&mbox->box, vname, flags, "dovecot.index");
mbox->mtime = mbox->ctime = (time_t)-1;
mbox->storage = (struct raw_storage *)storage;
mbox->size = (uoff_t)-1;
return &mbox->box;
}
static int raw_mailbox_open(struct mailbox *box)
{
struct raw_mailbox *mbox = (struct raw_mailbox *)box;
const char *path;
int fd;
if (box->input != NULL) {
mbox->mtime = mbox->ctime = ioloop_time;
return index_storage_mailbox_open(box, FALSE);
}
path = box->_path = box->name;
mbox->have_filename = TRUE;
fd = open(path, O_RDONLY);
if (fd == -1) {
if (ENOTFOUND(errno)) {
mail_storage_set_error(box->storage,
MAIL_ERROR_NOTFOUND,
T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name));
} else if (!mail_storage_set_error_from_errno(box->storage)) {
mail_storage_set_critical(box->storage,
"open(%s) failed: %m", path);
}
return -1;
}
box->input = i_stream_create_fd(fd, MAIL_READ_FULL_BLOCK_SIZE, TRUE);
i_stream_set_name(box->input, path);
i_stream_set_init_buffer_size(box->input, MAIL_READ_FULL_BLOCK_SIZE);
return index_storage_mailbox_open(box, FALSE);
}
static int
raw_mailbox_create(struct mailbox *box,
const struct mailbox_update *update ATTR_UNUSED,
bool directory ATTR_UNUSED)
{
mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
"Raw mailbox creation isn't supported");
return -1;
}
static int
raw_mailbox_update(struct mailbox *box,
const struct mailbox_update *update ATTR_UNUSED)
{
mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
"Raw mailbox update isn't supported");
return -1;
}
static void raw_notify_changes(struct mailbox *box ATTR_UNUSED)
{
}
struct mail_storage raw_storage = {
.name = RAW_STORAGE_NAME,
.class_flags = MAIL_STORAGE_CLASS_FLAG_MAILBOX_IS_FILE |
MAIL_STORAGE_CLASS_FLAG_OPEN_STREAMS,
.v = {
NULL,
raw_storage_alloc,
NULL,
NULL,
NULL,
raw_storage_get_list_settings,
NULL,
raw_mailbox_alloc,
NULL
}
};
struct mailbox raw_mailbox = {
.v = {
index_storage_is_readonly,
index_storage_mailbox_enable,
index_storage_mailbox_exists,
raw_mailbox_open,
index_storage_mailbox_close,
index_storage_mailbox_free,
raw_mailbox_create,
raw_mailbox_update,
index_storage_mailbox_delete,
index_storage_mailbox_rename,
index_storage_get_status,
index_mailbox_get_metadata,
index_storage_set_subscribed,
index_storage_attribute_set,
index_storage_attribute_get,
index_storage_attribute_iter_init,
index_storage_attribute_iter_next,
index_storage_attribute_iter_deinit,
index_storage_list_index_has_changed,
index_storage_list_index_update_sync,
raw_storage_sync_init,
index_mailbox_sync_next,
index_mailbox_sync_deinit,
NULL,
raw_notify_changes,
index_transaction_begin,
index_transaction_commit,
index_transaction_rollback,
NULL,
index_mail_alloc,
index_storage_search_init,
index_storage_search_deinit,
index_storage_search_next_nonblock,
index_storage_search_next_update_seq,
NULL,
NULL,
NULL,
NULL,
NULL,
mail_storage_copy,
NULL,
NULL,
NULL,
index_storage_is_inconsistent
}
};