* information is lost from the database).
*
* o Tell the database to update its time of 'path' to 'fs_mtime'
+ * if fs_mtime isn't the current wall-clock time.
*/
static notmuch_status_t
add_files_recursive (notmuch_database_t *notmuch,
notmuch_directory_t *directory;
notmuch_filenames_t *db_files = NULL;
notmuch_filenames_t *db_subdirs = NULL;
+ time_t stat_time;
struct stat st;
notmuch_bool_t is_maildir, new_directory;
const char **tag;
path, strerror (errno));
return NOTMUCH_STATUS_FILE_ERROR;
}
+ stat_time = time (NULL);
/* This is not an error since we may have recursed based on a
* symlink to a regular file, not a directory, and we don't know
new_directory = db_mtime ? FALSE : TRUE;
+ /* XXX This is a temporary workaround. If we don't update the
+ * database mtime until after processing messages in this
+ * directory, then a 0 mtime is *not* sufficient to indicate that
+ * this directory has no messages or subdirs in the database (for
+ * example, if an earlier run skipped the mtime update because
+ * fs_mtime == stat_time, or was interrupted before updating the
+ * mtime at the end). To address this, we record a (bogus)
+ * non-zero value before processing any child messages so that a
+ * later run won't mistake this for a new directory (and, for
+ * example, fail to detect removed files and subdirs).
+ *
+ * A better solution would be for notmuch_database_get_directory
+ * to indicate if it really created a new directory or not, either
+ * by a new out-argument, or by recording this information and
+ * providing an accessor.
+ */
+ if (new_directory)
+ notmuch_directory_set_mtime (directory, -1);
+
/* If the database knows about this directory, then we sort based
* on strcmp to match the database sorting. Otherwise, we can do
* inode-based sorting for faster filesystem operation. */
notmuch_filenames_move_to_next (db_subdirs);
}
- if (! interrupted) {
+ /* If the directory's mtime is the same as the wall-clock time
+ * when we stat'ed the directory, we skip updating the mtime in
+ * the database because a message could be delivered later in this
+ * same second. This may lead to unnecessary re-scans, but it
+ * avoids overlooking messages. */
+ if (! interrupted && fs_mtime != stat_time) {
status = notmuch_directory_set_mtime (directory, fs_mtime);
if (status && ret == NOTMUCH_STATUS_SUCCESS)
ret = status;