Mercurial > dovecot > core-2.2
changeset 3245:6491dab63e54 HEAD
Added input stream parameter to mailbox_open(). With mbox it now allows
opening a read-only mbox using a stream.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 29 Mar 2005 16:33:07 +0300 |
parents | f104e4197ac1 |
children | 3957eece913f |
files | src/imap/cmd-append.c src/imap/cmd-copy.c src/imap/cmd-select.c src/imap/cmd-status.c src/lib-storage/index/maildir/maildir-storage.c src/lib-storage/index/mbox/mbox-file.c src/lib-storage/index/mbox/mbox-lock.c src/lib-storage/index/mbox/mbox-save.c src/lib-storage/index/mbox/mbox-storage.c src/lib-storage/index/mbox/mbox-sync.c src/lib-storage/mail-storage-private.h src/lib-storage/mail-storage.c src/lib-storage/mail-storage.h src/pop3/client.c |
diffstat | 14 files changed, 164 insertions(+), 65 deletions(-) [+] |
line wrap: on
line diff
--- a/src/imap/cmd-append.c Tue Mar 29 16:30:55 2005 +0300 +++ b/src/imap/cmd-append.c Tue Mar 29 16:33:07 2005 +0300 @@ -360,7 +360,7 @@ mailbox_equals(cmd->client->mailbox, storage, name)) return cmd->client->mailbox; - box = mailbox_open(storage, name, MAILBOX_OPEN_FAST | + box = mailbox_open(storage, name, NULL, MAILBOX_OPEN_FAST | MAILBOX_OPEN_KEEP_RECENT); if (box == NULL) { client_send_storage_error(cmd, storage);
--- a/src/imap/cmd-copy.c Tue Mar 29 16:30:55 2005 +0300 +++ b/src/imap/cmd-copy.c Tue Mar 29 16:33:07 2005 +0300 @@ -74,7 +74,8 @@ if (mailbox_equals(client->mailbox, storage, mailbox)) destbox = client->mailbox; else { - destbox = mailbox_open(storage, mailbox, MAILBOX_OPEN_FAST | + destbox = mailbox_open(storage, mailbox, NULL, + MAILBOX_OPEN_FAST | MAILBOX_OPEN_KEEP_RECENT); if (destbox == NULL) { client_send_storage_error(cmd, storage);
--- a/src/imap/cmd-select.c Tue Mar 29 16:30:55 2005 +0300 +++ b/src/imap/cmd-select.c Tue Mar 29 16:33:07 2005 +0300 @@ -29,7 +29,7 @@ if (storage == NULL) return TRUE; - box = mailbox_open(storage, mailbox, !readonly ? 0 : + box = mailbox_open(storage, mailbox, NULL, !readonly ? 0 : (MAILBOX_OPEN_READONLY | MAILBOX_OPEN_KEEP_RECENT)); if (box == NULL) { client_send_storage_error(cmd, storage);
--- a/src/imap/cmd-status.c Tue Mar 29 16:30:55 2005 +0300 +++ b/src/imap/cmd-status.c Tue Mar 29 16:33:07 2005 +0300 @@ -58,7 +58,7 @@ box = client->mailbox; } else { /* open the mailbox */ - box = mailbox_open(storage, mailbox, MAILBOX_OPEN_FAST | + box = mailbox_open(storage, mailbox, NULL, MAILBOX_OPEN_FAST | MAILBOX_OPEN_READONLY | MAILBOX_OPEN_KEEP_RECENT); if (box == NULL)
--- a/src/lib-storage/index/maildir/maildir-storage.c Tue Mar 29 16:30:55 2005 +0300 +++ b/src/lib-storage/index/maildir/maildir-storage.c Tue Mar 29 16:33:07 2005 +0300 @@ -446,8 +446,8 @@ } static struct mailbox * -maildir_mailbox_open(struct mail_storage *_storage, - const char *name, enum mailbox_open_flags flags) +maildir_mailbox_open(struct mail_storage *_storage, const char *name, + struct istream *input, enum mailbox_open_flags flags) { struct index_storage *storage = (struct index_storage *)_storage; const char *path; @@ -455,6 +455,12 @@ mail_storage_clear_error(_storage); + if (input != NULL) { + mail_storage_set_critical(_storage, + "Maildir doesn't support streamed mailboxes"); + return NULL; + } + if (strcmp(name, "INBOX") == 0) { if (verify_inbox(storage) < 0) return NULL;
--- a/src/lib-storage/index/mbox/mbox-file.c Tue Mar 29 16:30:55 2005 +0300 +++ b/src/lib-storage/index/mbox/mbox-file.c Tue Mar 29 16:33:07 2005 +0300 @@ -16,6 +16,12 @@ i_assert(ibox->mbox_fd == -1); + if (ibox->mbox_file_stream != NULL) { + /* read-only mbox stream */ + i_assert(ibox->mbox_readonly); + return 0; + } + fd = open(ibox->path, ibox->mbox_readonly ? O_RDONLY : O_RDWR); if (fd == -1 && errno == EACCES && !ibox->mbox_readonly) { ibox->mbox_readonly = TRUE; @@ -56,7 +62,15 @@ if (ibox->mbox_stream != NULL) return 0; - i_assert(ibox->mbox_file_stream == NULL); + if (ibox->mbox_file_stream != NULL) { + /* read-only mbox stream */ + i_assert(ibox->mbox_fd == -1 && ibox->mbox_readonly); + + ibox->mbox_stream = + i_stream_create_raw_mbox(default_pool, + ibox->mbox_file_stream); + return 0; + } if (ibox->mbox_fd == -1) { if (mbox_file_open(ibox) < 0) @@ -85,13 +99,20 @@ void mbox_file_close_stream(struct index_mailbox *ibox) { if (ibox->mbox_stream != NULL) { - i_stream_close(ibox->mbox_file_stream); - i_stream_unref(ibox->mbox_file_stream); - ibox->mbox_file_stream = NULL; - i_stream_unref(ibox->mbox_stream); ibox->mbox_stream = NULL; } + + if (ibox->mbox_file_stream != NULL) { + if (ibox->mbox_fd == -1) { + /* read-only mbox stream */ + i_assert(ibox->mbox_readonly); + } else { + i_stream_close(ibox->mbox_file_stream); + i_stream_unref(ibox->mbox_file_stream); + ibox->mbox_file_stream = NULL; + } + } } int mbox_file_seek(struct index_mailbox *ibox, struct mail_index_view *view,
--- a/src/lib-storage/index/mbox/mbox-lock.c Tue Mar 29 16:30:55 2005 +0300 +++ b/src/lib-storage/index/mbox/mbox-lock.c Tue Mar 29 16:33:07 2005 +0300 @@ -455,6 +455,13 @@ if (!lock_settings_initialized) mbox_init_lock_settings(); + if (ibox->mbox_fd == -1 && ibox->mbox_file_stream != NULL) { + /* read-only mbox stream. no need to lock. */ + i_assert(ibox->mbox_readonly); + ibox->mbox_lock_type = lock_type; + return TRUE; + } + max_wait_time = time(NULL) + lock_timeout; memset(&ctx, 0, sizeof(ctx));
--- a/src/lib-storage/index/mbox/mbox-save.c Tue Mar 29 16:30:55 2005 +0300 +++ b/src/lib-storage/index/mbox/mbox-save.c Tue Mar 29 16:33:07 2005 +0300 @@ -251,6 +251,12 @@ struct index_mailbox *ibox = ctx->ibox; int ret; + if (ctx->ibox->mbox_readonly || ctx->ibox->readonly) { + mail_storage_set_error(&ctx->ibox->storage->storage, + "Read-only mbox"); + return -1; + } + if (ctx->append_offset == (uoff_t)-1) { /* first appended mail in this transaction */ if (ibox->mbox_lock_type != F_WRLCK) {
--- a/src/lib-storage/index/mbox/mbox-storage.c Tue Mar 29 16:30:55 2005 +0300 +++ b/src/lib-storage/index/mbox/mbox-storage.c Tue Mar 29 16:33:07 2005 +0300 @@ -2,6 +2,7 @@ #include "lib.h" #include "buffer.h" +#include "istream.h" #include "home-expand.h" #include "mkdir-parents.h" #include "unlink-directory.h" @@ -478,6 +479,43 @@ return FALSE; } +static struct index_mailbox * +mbox_alloc(struct index_storage *storage, struct mail_index *index, + const char *name, enum mailbox_open_flags flags) +{ + struct index_mailbox *ibox; + pool_t pool; + + pool = pool_alloconly_create("mailbox", 256); + ibox = p_new(pool, struct index_mailbox, 1); + ibox->box = mbox_mailbox; + ibox->box.pool = pool; + ibox->storage = storage; + + if (index_storage_mailbox_init(ibox, index, name, flags) < 0) { + /* the memory is already freed here, no need to deinit */ + return NULL; + } + + ibox->mbox_fd = -1; + ibox->mbox_lock_type = F_UNLCK; + ibox->mbox_ext_idx = + mail_index_ext_register(index, "mbox", 0, + sizeof(uint64_t), sizeof(uint64_t)); + + ibox->is_recent = mbox_mail_is_recent; + ibox->mail_vfuncs = &mbox_mail_vfuncs; + ibox->mbox_very_dirty_syncs = getenv("MBOX_VERY_DIRTY_SYNCS") != NULL; + ibox->mbox_do_dirty_syncs = ibox->mbox_very_dirty_syncs || + getenv("MBOX_DIRTY_SYNCS") != NULL; + + ibox->md5hdr_ext_idx = + mail_index_ext_register(ibox->index, "header-md5", 0, 16, 1); + if ((flags & MAILBOX_OPEN_KEEP_HEADER_MD5) != 0) + ibox->mbox_save_md5 = TRUE; + return ibox; +} + static struct mailbox * mbox_open(struct index_storage *storage, const char *name, enum mailbox_open_flags flags) @@ -485,8 +523,6 @@ struct index_mailbox *ibox; struct mail_index *index; const char *path, *index_dir; - uint32_t mbox_ext_idx; - pool_t pool; if (strcmp(name, "INBOX") == 0) { /* name = "INBOX" @@ -503,36 +539,11 @@ } index = index_storage_alloc(index_dir, path, MBOX_INDEX_PREFIX); - mbox_ext_idx = mail_index_ext_register(index, "mbox", 0, - sizeof(uint64_t), - sizeof(uint64_t)); - - pool = pool_alloconly_create("mailbox", 256); - ibox = p_new(pool, struct index_mailbox, 1); - ibox->box = mbox_mailbox; - ibox->box.pool = pool; - ibox->storage = storage; - - if (index_storage_mailbox_init(ibox, index, name, flags) < 0) { - /* the memory was already freed */ + ibox = mbox_alloc(storage, index, name, flags); + if (ibox == NULL) return NULL; - } - ibox->path = p_strdup(pool, path); - ibox->mbox_fd = -1; - ibox->mbox_lock_type = F_UNLCK; - ibox->mbox_ext_idx = mbox_ext_idx; - - ibox->is_recent = mbox_mail_is_recent; - ibox->mail_vfuncs = &mbox_mail_vfuncs; - ibox->mbox_very_dirty_syncs = getenv("MBOX_VERY_DIRTY_SYNCS") != NULL; - ibox->mbox_do_dirty_syncs = ibox->mbox_very_dirty_syncs || - getenv("MBOX_DIRTY_SYNCS") != NULL; - - ibox->md5hdr_ext_idx = - mail_index_ext_register(ibox->index, "header-md5", 0, 16, 1); - if ((flags & MAILBOX_OPEN_KEEP_HEADER_MD5) != 0) - ibox->mbox_save_md5 = TRUE; + ibox->path = p_strdup(ibox->box.pool, path); if (access(path, R_OK|W_OK) < 0) { if (errno < EACCES) @@ -547,8 +558,30 @@ } static struct mailbox * -mbox_mailbox_open(struct mail_storage *_storage, - const char *name, enum mailbox_open_flags flags) +mbox_mailbox_open_stream(struct index_storage *storage, const char *name, + struct istream *input, enum mailbox_open_flags flags) +{ + struct mail_index *index; + struct index_mailbox *ibox; + + flags |= MAILBOX_OPEN_READONLY; + + index = mail_index_alloc(NULL, NULL); + ibox = mbox_alloc(storage, index, name, flags); + if (ibox == NULL) + return NULL; + + i_stream_ref(input); + ibox->mbox_file_stream = input; + ibox->mbox_readonly = TRUE; + + ibox->path = "(read-only mbox stream)"; + return &ibox->box; +} + +static struct mailbox * +mbox_mailbox_open(struct mail_storage *_storage, const char *name, + struct istream *input, enum mailbox_open_flags flags) { struct index_storage *storage = (struct index_storage *)_storage; const char *path; @@ -556,6 +589,9 @@ mail_storage_clear_error(_storage); + if (input != NULL) + return mbox_mailbox_open_stream(storage, name, input, flags); + if (strcmp(name, "INBOX") == 0) { /* make sure INBOX exists */ if (verify_inbox(storage) < 0) @@ -916,7 +952,11 @@ } mbox_file_close(ibox); - index_storage_mailbox_free(box); + if (ibox->mbox_file_stream != NULL) { + i_stream_unref(ibox->mbox_file_stream); + ibox->mbox_file_stream = NULL; + } + index_storage_mailbox_free(box); return ret; }
--- a/src/lib-storage/index/mbox/mbox-sync.c Tue Mar 29 16:30:55 2005 +0300 +++ b/src/lib-storage/index/mbox/mbox-sync.c Tue Mar 29 16:33:07 2005 +0300 @@ -1257,17 +1257,28 @@ int mbox_sync_has_changed(struct index_mailbox *ibox, int leave_dirty) { const struct mail_index_header *hdr; - struct stat st; + const struct stat *st; + struct stat statbuf; + + if (ibox->mbox_file_stream != NULL && ibox->mbox_fd == -1) { + /* read-only stream */ + st = i_stream_stat(ibox->mbox_file_stream); + if (st == NULL) { + mbox_set_syscall_error(ibox, "i_stream_stat()"); + return -1; + } + } else { + if (stat(ibox->path, &statbuf) < 0) { + mbox_set_syscall_error(ibox, "stat()"); + return -1; + } + st = &statbuf; + } hdr = mail_index_get_header(ibox->view); - if (stat(ibox->path, &st) < 0) { - mbox_set_syscall_error(ibox, "stat()"); - return -1; - } - - if ((uint32_t)st.st_mtime == hdr->sync_stamp && - (uint64_t)st.st_size == hdr->sync_size) { + if ((uint32_t)st->st_mtime == hdr->sync_stamp && + (uint64_t)st->st_size == hdr->sync_size) { /* fully synced */ ibox->mbox_sync_dirty = FALSE; return 0; @@ -1276,8 +1287,8 @@ if (!ibox->mbox_sync_dirty || !leave_dirty) return 1; - return st.st_mtime != ibox->mbox_dirty_stamp || - st.st_size != ibox->mbox_dirty_size; + return st->st_mtime != ibox->mbox_dirty_stamp || + st->st_size != ibox->mbox_dirty_size; } static int mbox_sync_update_imap_base(struct mbox_sync_context *sync_ctx)
--- a/src/lib-storage/mail-storage-private.h Tue Mar 29 16:30:55 2005 +0300 +++ b/src/lib-storage/mail-storage-private.h Tue Mar 29 16:33:07 2005 +0300 @@ -20,6 +20,7 @@ struct mailbox *(*mailbox_open)(struct mail_storage *storage, const char *name, + struct istream *input, enum mailbox_open_flags flags); int (*mailbox_create)(struct mail_storage *storage, const char *name,
--- a/src/lib-storage/mail-storage.c Tue Mar 29 16:30:55 2005 +0300 +++ b/src/lib-storage/mail-storage.c Tue Mar 29 16:33:07 2005 +0300 @@ -288,10 +288,11 @@ return storage->v.get_last_error(storage, syntax_error_r); } -struct mailbox *mailbox_open(struct mail_storage *storage, - const char *name, enum mailbox_open_flags flags) +struct mailbox *mailbox_open(struct mail_storage *storage, const char *name, + struct istream *input, + enum mailbox_open_flags flags) { - return storage->v.mailbox_open(storage, name, flags); + return storage->v.mailbox_open(storage, name, input, flags); } int mailbox_close(struct mailbox *box)
--- a/src/lib-storage/mail-storage.h Tue Mar 29 16:30:55 2005 +0300 +++ b/src/lib-storage/mail-storage.h Tue Mar 29 16:33:07 2005 +0300 @@ -13,10 +13,15 @@ }; enum mailbox_open_flags { + /* Mailbox must not be modified even if asked */ MAILBOX_OPEN_READONLY = 0x01, + /* Any extra time consuming operations shouldn't be performed + (eg. when opening mailbox just for STATUS). */ MAILBOX_OPEN_FAST = 0x02, + /* Don't reset MAIL_RECENT flags when syncing */ MAILBOX_OPEN_KEEP_RECENT = 0x04, - MAILBOX_OPEN_KEEP_HEADER_MD5 = 0x04 + /* Remember message headers' MD5 sum */ + MAILBOX_OPEN_KEEP_HEADER_MD5 = 0x08 }; enum mailbox_list_flags { @@ -266,15 +271,15 @@ const char *mail_storage_get_last_error(struct mail_storage *storage, int *syntax_error_r); -/* Open a mailbox. If readonly is TRUE, mailbox must not be - modified in any way even when it's asked. If fast is TRUE, - any extra time consuming operations shouldn't be performed - (eg. when opening mailbox just for STATUS). +/* Open a mailbox. If input stream is given, mailbox is opened read-only + using it as a backend. If storage doesn't support stream backends and its + tried to be used, NULL is returned. Note that append and copy may open the selected mailbox again with possibly different readonly-state. */ -struct mailbox *mailbox_open(struct mail_storage *storage, - const char *name, enum mailbox_open_flags flags); +struct mailbox *mailbox_open(struct mail_storage *storage, const char *name, + struct istream *input, + enum mailbox_open_flags flags); /* Close the box. Returns FALSE if some cleanup errors occured, but the mailbox was closed anyway. */ int mailbox_close(struct mailbox *box);
--- a/src/pop3/client.c Tue Mar 29 16:30:55 2005 +0300 +++ b/src/pop3/client.c Tue Mar 29 16:33:07 2005 +0300 @@ -153,7 +153,7 @@ flags |= MAILBOX_OPEN_KEEP_RECENT; if ((uidl_keymask & UIDL_MD5) != 0) flags |= MAILBOX_OPEN_KEEP_HEADER_MD5; - client->mailbox = mailbox_open(storage, "INBOX", flags); + client->mailbox = mailbox_open(storage, "INBOX", NULL, flags); if (client->mailbox == NULL) { i_error("Couldn't open INBOX: %s", mail_storage_get_last_error(storage, &syntax_error));