X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=notmuch-new.c;h=b734e5b972373d6b4941b8c711cf99f87056b097;hp=0fa2a3cb72ebcda4a3de4131d3106a0fa4a96704;hb=bdaee77e1b0853b0dab00565e4c5b6164248f85a;hpb=68a2c7a8b0f749cb33a8ce7cfa2aa7781d2529bb diff --git a/notmuch-new.c b/notmuch-new.c index 0fa2a3cb..b734e5b9 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -213,6 +213,7 @@ _entries_resemble_maildir (struct dirent **entries, int count) * 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, @@ -230,6 +231,7 @@ 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; @@ -239,6 +241,7 @@ add_files_recursive (notmuch_database_t *notmuch, 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 @@ -253,6 +256,25 @@ add_files_recursive (notmuch_database_t *notmuch, 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. */ @@ -509,7 +531,12 @@ add_files_recursive (notmuch_database_t *notmuch, 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; @@ -841,7 +868,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[]) removed_files = 0; renamed_files = 0; gettimeofday (&tv_start, NULL); - for (f = add_files_state.removed_files->head; f; f = f->next) { + for (f = add_files_state.removed_files->head; f && !interrupted; f = f->next) { status = notmuch_database_remove_message (notmuch, f->filename); if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) renamed_files++; @@ -856,7 +883,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[]) } gettimeofday (&tv_start, NULL); - for (f = add_files_state.removed_directories->head, i = 0; f; f = f->next, i++) { + for (f = add_files_state.removed_directories->head, i = 0; f && !interrupted; f = f->next, i++) { _remove_directory (ctx, notmuch, f->filename, &renamed_files, &removed_files); if (do_print_progress) {