typedef struct _filename_node {
char *filename;
+ time_t mtime;
struct _filename_node *next;
} _filename_node_t;
int total_files;
int processed_files;
- int added_messages;
+ int added_messages, removed_messages, renamed_messages;
struct timeval tv_start;
_filename_list_t *removed_files;
_filename_list_t *removed_directories;
+ _filename_list_t *directory_mtimes;
notmuch_bool_t synchronize_flags;
_filename_list_t *message_ids_to_sync;
return list;
}
-static void
+static _filename_node_t *
_filename_list_add (_filename_list_t *list,
const char *filename)
{
*(list->tail) = node;
list->tail = &node->next;
+
+ return node;
}
static void
case NOTMUCH_STATUS_NULL_POINTER:
case NOTMUCH_STATUS_TAG_TOO_LONG:
case NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW:
+ case NOTMUCH_STATUS_UNBALANCED_ATOMIC:
case NOTMUCH_STATUS_LAST_STATUS:
INTERNAL_ERROR ("add_message returned unexpected value: %d", status);
goto DONE;
* 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;
- }
+ if (fs_mtime != stat_time)
+ _filename_list_add (state->directory_mtimes, path)->mtime = fs_mtime;
DONE:
if (next)
fflush (stdout);
}
+/* Remove one message filename from the database. */
+static notmuch_status_t
+remove_filename (notmuch_database_t *notmuch,
+ const char *path,
+ add_files_state_t *add_files_state)
+{
+ notmuch_status_t status;
+ status = notmuch_database_remove_message (notmuch, path);
+ if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID)
+ add_files_state->renamed_messages++;
+ else
+ add_files_state->removed_messages++;
+ return status;
+}
+
/* Recursively remove all filenames from the database referring to
* 'path' (or to any of its children). */
static void
_remove_directory (void *ctx,
notmuch_database_t *notmuch,
const char *path,
- int *renamed_files,
- int *removed_files)
+ add_files_state_t *add_files_state)
{
notmuch_directory_t *directory;
notmuch_filenames_t *files, *subdirs;
- notmuch_status_t status;
char *absolute;
directory = notmuch_database_get_directory (notmuch, path);
{
absolute = talloc_asprintf (ctx, "%s/%s", path,
notmuch_filenames_get (files));
- status = notmuch_database_remove_message (notmuch, absolute);
- if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID)
- *renamed_files = *renamed_files + 1;
- else
- *removed_files = *removed_files + 1;
+ remove_filename (notmuch, absolute, add_files_state);
talloc_free (absolute);
}
{
absolute = talloc_asprintf (ctx, "%s/%s", path,
notmuch_filenames_get (subdirs));
- _remove_directory (ctx, notmuch, absolute, renamed_files, removed_files);
+ _remove_directory (ctx, notmuch, absolute, add_files_state);
talloc_free (absolute);
}
char *dot_notmuch_path;
struct sigaction action;
_filename_node_t *f;
- int renamed_files, removed_files;
- notmuch_status_t status;
int i;
notmuch_bool_t timer_is_active = FALSE;
add_files_state.processed_files = 0;
add_files_state.added_messages = 0;
+ add_files_state.removed_messages = add_files_state.renamed_messages = 0;
gettimeofday (&add_files_state.tv_start, NULL);
add_files_state.removed_files = _filename_list_create (ctx);
add_files_state.removed_directories = _filename_list_create (ctx);
+ add_files_state.directory_mtimes = _filename_list_create (ctx);
if (! debugger_is_active () && add_files_state.output_is_a_tty
&& ! add_files_state.verbose) {
ret = add_files (notmuch, db_path, &add_files_state);
- removed_files = 0;
- renamed_files = 0;
gettimeofday (&tv_start, NULL);
- for (f = add_files_state.removed_files->head; f; f = f->next) {
- status = notmuch_database_remove_message (notmuch, f->filename);
- if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID)
- renamed_files++;
- else
- removed_files++;
+ for (f = add_files_state.removed_files->head; f && !interrupted; f = f->next) {
+ remove_filename (notmuch, f->filename, &add_files_state);
if (do_print_progress) {
do_print_progress = 0;
generic_print_progress ("Cleaned up", "messages",
- tv_start, removed_files + renamed_files,
+ tv_start, add_files_state.removed_messages + add_files_state.renamed_messages,
add_files_state.removed_files->count);
}
}
gettimeofday (&tv_start, NULL);
- for (f = add_files_state.removed_directories->head, i = 0; f; f = f->next, i++) {
- _remove_directory (ctx, notmuch, f->filename,
- &renamed_files, &removed_files);
+ for (f = add_files_state.removed_directories->head, i = 0; f && !interrupted; f = f->next, i++) {
+ _remove_directory (ctx, notmuch, f->filename, &add_files_state);
if (do_print_progress) {
do_print_progress = 0;
generic_print_progress ("Cleaned up", "directories",
}
}
+ for (f = add_files_state.directory_mtimes->head; f && !interrupted; f = f->next) {
+ notmuch_directory_t *directory;
+ directory = notmuch_database_get_directory (notmuch, f->filename);
+ if (directory) {
+ notmuch_directory_set_mtime (directory, f->mtime);
+ notmuch_directory_destroy (directory);
+ }
+ }
+
talloc_free (add_files_state.removed_files);
talloc_free (add_files_state.removed_directories);
+ talloc_free (add_files_state.directory_mtimes);
/* Now that removals are done (hence the database is aware of all
* renames), we can synchronize maildir_flags to tags for all
printf ("No new mail.");
}
- if (removed_files) {
+ if (add_files_state.removed_messages) {
printf (" Removed %d %s.",
- removed_files,
- removed_files == 1 ? "message" : "messages");
+ add_files_state.removed_messages,
+ add_files_state.removed_messages == 1 ? "message" : "messages");
}
- if (renamed_files) {
+ if (add_files_state.renamed_messages) {
printf (" Detected %d file %s.",
- renamed_files,
- renamed_files == 1 ? "rename" : "renames");
+ add_files_state.renamed_messages,
+ add_files_state.renamed_messages == 1 ? "rename" : "renames");
}
printf ("\n");