]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-index: Take MAIL_INDEX_OPEN_FLAG_READONLY more seriously.
authorTimo Sirainen <tss@iki.fi>
Fri, 9 Oct 2009 00:10:49 +0000 (20:10 -0400)
committerTimo Sirainen <tss@iki.fi>
Fri, 9 Oct 2009 00:10:49 +0000 (20:10 -0400)
Don't do any filesystem changes to the index when it's set, even if
corrupted index files are detected.

--HG--
branch : HEAD

src/lib-index/mail-cache.c
src/lib-index/mail-index-map-read.c
src/lib-index/mail-index-write.c
src/lib-index/mail-index.c
src/lib-index/mail-transaction-log-file.c
src/lib-index/mail-transaction-log.c
src/lib-index/mailbox-list-index.c

index 4b9a26127da3b34eee6ab52ba6b085cc348fa348..b3b510d159c7c65f9f33581617f81705a12d27d4 100644 (file)
@@ -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) {
index 811f4d4e8958ddac74c7f327a37a265ce0724236..64f587f8bba1561fece876e8648f986241fbaee5 100644 (file)
@@ -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()");
index 84c8c908b765ea740ba907352f318996ef87571c..d1c947d40782f900cc7b823ade570b783c76ea98 100644 (file)
@@ -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)) {
index 39a3d2e3bd79732edc8981b8532c619e1f274be7..1e5ec5e0e36c28bb9cf06f20b44ab85f7253604d 100644 (file)
@@ -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)
index 7b2e77d05ea3eb5a1cd4666ef638f154d373dab1..a20d40cd1595ff98352b541a1f519f824e0c21ae 100644 (file)
@@ -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);
index 0361e519bfb5ad22511a3ce938eb9684da9959ca..ca7e436c45b6b58f69d5be58c8d2ac3af526a10f 100644 (file)
@@ -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);
index ba8762910a4a61a0af276eff3c456e2751e0bb6b..465e051e1918c8d5962e84ace67b38587720214c 100644 (file)
@@ -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",