From: Timo Sirainen Date: Fri, 9 Oct 2009 00:10:49 +0000 (-0400) Subject: lib-index: Take MAIL_INDEX_OPEN_FLAG_READONLY more seriously. X-Git-Tag: 2.0.alpha1~46 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6bc0f424bcdb9119d8159874cf98adfa53eefd9a;p=thirdparty%2Fdovecot%2Fcore.git lib-index: Take MAIL_INDEX_OPEN_FLAG_READONLY more seriously. Don't do any filesystem changes to the index when it's set, even if corrupted index files are detected. --HG-- branch : HEAD --- diff --git a/src/lib-index/mail-cache.c b/src/lib-index/mail-cache.c index 4b9a26127d..b3b510d159 100644 --- a/src/lib-index/mail-cache.c +++ b/src/lib-index/mail-cache.c @@ -29,11 +29,17 @@ void mail_cache_set_syscall_error(struct mail_cache *cache, function, cache->filepath); } +static void mail_cache_unlink(struct mail_cache *cache) +{ + if (!cache->index->readonly) + (void)unlink(cache->filepath); +} + void mail_cache_set_corrupted(struct mail_cache *cache, const char *fmt, ...) { va_list va; - (void)unlink(cache->filepath); + mail_cache_unlink(cache); /* mark the cache as unusable */ cache->hdr = NULL; @@ -225,18 +231,18 @@ static bool mail_cache_verify_header(struct mail_cache *cache) if (hdr->version != MAIL_CACHE_VERSION) { /* version changed - upgrade silently */ - (void)unlink(cache->filepath); + mail_cache_unlink(cache); return FALSE; } if (hdr->compat_sizeof_uoff_t != sizeof(uoff_t)) { /* architecture change - handle silently(?) */ - (void)unlink(cache->filepath); + mail_cache_unlink(cache); return FALSE; } if (hdr->indexid != cache->index->indexid) { /* index id changed - handle silently */ - (void)unlink(cache->filepath); + mail_cache_unlink(cache); return FALSE; } if (hdr->file_seq == 0) { diff --git a/src/lib-index/mail-index-map-read.c b/src/lib-index/mail-index-map-read.c index 811f4d4e89..64f587f8bb 100644 --- a/src/lib-index/mail-index-map-read.c +++ b/src/lib-index/mail-index-map-read.c @@ -433,7 +433,7 @@ int mail_index_map(struct mail_index *index, ret = mail_index_sync_map(&index->map, type, TRUE); } - } else if (ret == 0) { + } else if (ret == 0 && index->readonly) { /* make sure we don't try to open the file again */ if (unlink(index->filepath) < 0 && errno != ENOENT) mail_index_set_syscall_error(index, "unlink()"); diff --git a/src/lib-index/mail-index-write.c b/src/lib-index/mail-index-write.c index 84c8c908b7..d1c947d407 100644 --- a/src/lib-index/mail-index-write.c +++ b/src/lib-index/mail-index-write.c @@ -188,7 +188,7 @@ void mail_index_write(struct mail_index *index, bool want_rotate) i_assert(index->log_locked); - if (!mail_index_map_has_changed(map)) + if (!mail_index_map_has_changed(map) || index->readonly) return; if (hdr->base_header_size < sizeof(*hdr)) { diff --git a/src/lib-index/mail-index.c b/src/lib-index/mail-index.c index 39a3d2e3bd..1e5ec5e0e3 100644 --- a/src/lib-index/mail-index.c +++ b/src/lib-index/mail-index.c @@ -580,7 +580,7 @@ int mail_index_unlink(struct mail_index *index) const char *path; int last_errno = 0; - if (MAIL_INDEX_IS_IN_MEMORY(index)) + if (MAIL_INDEX_IS_IN_MEMORY(index) || index->readonly) return 0; /* main index */ @@ -737,8 +737,11 @@ void mail_index_mark_corrupted(struct mail_index *index) index->indexid = 0; index->map->hdr.flags |= MAIL_INDEX_HDR_FLAG_CORRUPTED; - if (unlink(index->filepath) < 0 && errno != ENOENT && errno != ESTALE) - mail_index_set_syscall_error(index, "unlink()"); + if (!index->readonly) { + if (unlink(index->filepath) < 0 && + errno != ENOENT && errno != ESTALE) + mail_index_set_syscall_error(index, "unlink()"); + } } void mail_index_fchown(struct mail_index *index, int fd, const char *path) diff --git a/src/lib-index/mail-transaction-log-file.c b/src/lib-index/mail-transaction-log-file.c index 7b2e77d05e..a20d40cd15 100644 --- a/src/lib-index/mail-transaction-log-file.c +++ b/src/lib-index/mail-transaction-log-file.c @@ -31,7 +31,8 @@ mail_transaction_log_file_set_corrupted(struct mail_transaction_log_file *file, file->corrupted = TRUE; file->hdr.indexid = 0; - if (!MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) { + if (!MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file) && + !file->log->index->readonly) { /* indexid=0 marks the log file as corrupted */ unsigned int offset = offsetof(struct mail_transaction_log_header, indexid); @@ -354,8 +355,7 @@ void mail_transaction_log_file_unlock(struct mail_transaction_log_file *file) static ssize_t mail_transaction_log_file_read_header(struct mail_transaction_log_file *file) { - ssize_t pos; - int ret; + ssize_t pos, ret; memset(&file->hdr, 0, sizeof(file->hdr)); @@ -643,6 +643,13 @@ int mail_transaction_log_file_create(struct mail_transaction_log_file *file, i_assert(!MAIL_INDEX_IS_IN_MEMORY(index)); + if (file->log->index->readonly) { + mail_index_set_error(index, + "Can't create log file %s: Index is read-only", + file->filepath); + return -1; + } + /* With dotlocking we might already have path.lock created, so this filename has to be different. */ old_mask = umask(index->mode ^ 0666); @@ -697,7 +704,10 @@ int mail_transaction_log_file_open(struct mail_transaction_log_file *file, if (ret == 0) { /* corrupted */ - if (unlink(file->filepath) < 0 && errno != ENOENT) { + if (file->log->index->readonly) { + /* don't delete */ + } else if (unlink(file->filepath) < 0 && + errno != ENOENT) { mail_index_set_error(file->log->index, "unlink(%s) failed: %m", file->filepath); diff --git a/src/lib-index/mail-transaction-log.c b/src/lib-index/mail-transaction-log.c index 0361e519bf..ca7e436c45 100644 --- a/src/lib-index/mail-transaction-log.c +++ b/src/lib-index/mail-transaction-log.c @@ -58,7 +58,8 @@ static void mail_transaction_log_2_unlink_old(struct mail_transaction_log *log) return; } - if (st.st_mtime + MAIL_TRANSACTION_LOG2_STALE_SECS <= ioloop_time) { + if (st.st_mtime + MAIL_TRANSACTION_LOG2_STALE_SECS <= ioloop_time && + !log->index->readonly) { if (unlink(log->filepath2) < 0 && errno != ENOENT) { mail_index_set_error(log->index, "unlink(%s) failed: %m", log->filepath2); diff --git a/src/lib-index/mailbox-list-index.c b/src/lib-index/mailbox-list-index.c index ba8762910a..465e051e19 100644 --- a/src/lib-index/mailbox-list-index.c +++ b/src/lib-index/mailbox-list-index.c @@ -88,7 +88,8 @@ void mailbox_list_index_file_close(struct mailbox_list_index *index) int mailbox_list_index_set_corrupted(struct mailbox_list_index *index, const char *str) { - (void)unlink(index->filepath); + if (!index->mail_index->readonly) + (void)unlink(index->filepath); mailbox_list_index_file_close(index); i_error("Corrupted mailbox list index file %s: %s",