changeset 22362:5e665ab8487c

lib-index: Fix mail_index_get_modification_time() to work when index isn't open. index->filepath may be NULL after a failed index open, and it's a bit unsafe to trust that index->log->filepath isn't NULL either. So just build the full path from elements that are definitely non-NULL. Also stat() only dovecot.index.log, because it's always supposed to exist. If it doesn't, something's broken and stat()ing dovecot.index doesn't make much sense. This commit removes mail_transaction_log_get_mtime(), which is no longer needed. Fixes: Panic: file mail-index.c: line 931 (mail_index_file_set_syscall_error): assertion failed: (filepath != NULL)
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Tue, 18 Jul 2017 14:42:23 +0300
parents 73479718bc0b
children dba5febb1752
files src/lib-index/mail-index.c src/lib-index/mail-index.h src/lib-index/mail-transaction-log.c src/lib-index/mail-transaction-log.h
diffstat 4 files changed, 19 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-index.c	Tue Jul 18 14:37:53 2017 +0300
+++ b/src/lib-index/mail-index.c	Tue Jul 18 14:42:23 2017 +0300
@@ -870,17 +870,27 @@
 int mail_index_get_modification_time(struct mail_index *index, time_t *mtime_r)
 {
 	struct stat st;
+	const char *path;
 
-	if (mail_transaction_log_get_mtime(index->log, mtime_r) < 0)
-		return -1;
+	*mtime_r = 0;
+	if (MAIL_INDEX_IS_IN_MEMORY(index)) {
+		/* this function doesn't make sense for in-memory indexes */
+		return 0;
+	}
 
-	if (*mtime_r == 0) {
-		if (stat(index->filepath, &st) < 0) {
-			mail_index_set_syscall_error(index, "stat()");
-			return -1;
+	/* index may not be open, so index->filepath may be NULL */
+	path = t_strconcat(index->dir, "/", index->prefix,
+			   MAIL_TRANSACTION_LOG_SUFFIX, NULL);
+	if (stat(path, &st) < 0) {
+		if (errno == ENOENT) {
+			/* .log is always supposed to exist - don't bother
+			   trying to stat(dovecot.index) */
+			return 0;
 		}
-		*mtime_r = st.st_mtime;
+		mail_index_file_set_syscall_error(index, path, "stat()");
+		return -1;
 	}
+	*mtime_r = st.st_mtime;
 	return 0;
 }
 
--- a/src/lib-index/mail-index.h	Tue Jul 18 14:37:53 2017 +0300
+++ b/src/lib-index/mail-index.h	Tue Jul 18 14:42:23 2017 +0300
@@ -545,7 +545,8 @@
 /* Returns TRUE if index has been set deleted. This gets set only after
    index has been opened/refreshed and the transaction has been seen. */
 bool mail_index_is_deleted(struct mail_index *index);
-/* Returns the last time mailbox was modified. */
+/* Returns the last time the index was modified. This can be called even if the
+   index isn't open. If the index doesn't exist, sets mtime to 0. */
 int mail_index_get_modification_time(struct mail_index *index, time_t *mtime_r);
 
 /* Lookup a keyword, returns TRUE if found, FALSE if not. */
--- a/src/lib-index/mail-transaction-log.c	Tue Jul 18 14:37:53 2017 +0300
+++ b/src/lib-index/mail-transaction-log.c	Tue Jul 18 14:42:23 2017 +0300
@@ -594,24 +594,6 @@
 		log->head->hdr.prev_file_offset == file_offset;
 }
 
-int mail_transaction_log_get_mtime(struct mail_transaction_log *log,
-				   time_t *mtime_r)
-{
-	struct stat st;
-
-	*mtime_r = 0;
-	if (stat(log->filepath, &st) < 0) {
-		if (errno == ENOENT)
-			return 0;
-
-		mail_index_file_set_syscall_error(log->index, log->filepath,
-						  "stat()");
-		return -1;
-	}
-	*mtime_r = st.st_mtime;
-	return 0;
-}
-
 int mail_transaction_log_unlink(struct mail_transaction_log *log)
 {
 	if (unlink(log->filepath) < 0 &&
--- a/src/lib-index/mail-transaction-log.h	Tue Jul 18 14:37:53 2017 +0300
+++ b/src/lib-index/mail-transaction-log.h	Tue Jul 18 14:42:23 2017 +0300
@@ -307,10 +307,6 @@
 /* Move currently opened log head file to memory (called by
    mail_index_move_to_memory()) */
 void mail_transaction_log_move_to_memory(struct mail_transaction_log *log);
-/* Returns mtime of the transaction log head file.
-   If it doesn't exist, mtime_r is set to 0. */
-int mail_transaction_log_get_mtime(struct mail_transaction_log *log,
-				   time_t *mtime_r);
 /* Unlink transaction log files */
 int mail_transaction_log_unlink(struct mail_transaction_log *log);