From: Timo Sirainen Date: Tue, 18 Jul 2017 11:42:23 +0000 (+0300) Subject: lib-index: Fix mail_index_get_modification_time() to work when index isn't open. X-Git-Tag: 2.3.0.rc1~1249 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bb444f746dc6c15a8d0af67ef81bfa48c28471d0;p=thirdparty%2Fdovecot%2Fcore.git 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) --- diff --git a/src/lib-index/mail-index.c b/src/lib-index/mail-index.c index 6665c293de..8f19a6fd92 100644 --- a/src/lib-index/mail-index.c +++ b/src/lib-index/mail-index.c @@ -875,17 +875,27 @@ bool mail_index_is_deleted(struct mail_index *index) 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; } diff --git a/src/lib-index/mail-index.h b/src/lib-index/mail-index.h index 64810144b4..a5d740d0a4 100644 --- a/src/lib-index/mail-index.h +++ b/src/lib-index/mail-index.h @@ -545,7 +545,8 @@ void mail_index_set_undeleted(struct mail_index_transaction *t); /* 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. */ diff --git a/src/lib-index/mail-transaction-log.c b/src/lib-index/mail-transaction-log.c index b03d6ed7c8..5c0c34ee3f 100644 --- a/src/lib-index/mail-transaction-log.c +++ b/src/lib-index/mail-transaction-log.c @@ -595,24 +595,6 @@ bool mail_transaction_log_is_head_prev(struct mail_transaction_log *log, 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 && diff --git a/src/lib-index/mail-transaction-log.h b/src/lib-index/mail-transaction-log.h index 18281695f1..88ab95b064 100644 --- a/src/lib-index/mail-transaction-log.h +++ b/src/lib-index/mail-transaction-log.h @@ -307,10 +307,6 @@ bool mail_transaction_log_is_head_prev(struct mail_transaction_log *log, /* Move currently opened log head file to memory (called by mail_index_move_to_memory()) */ int 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);