]> git.notmuchmail.org Git - notmuch/blobdiff - notmuch-new.c
notmuch new: Print counts of deleted and renamed messages.
[notmuch] / notmuch-new.c
index b2b6043a5de051598051c418bfd7d3a46745e597..ab1d12a6fd7dd8ea1a800fc30c4686c096ba62fe 100644 (file)
 
 #include <unistd.h>
 
+typedef struct _filename_node {
+    char *filename;
+    struct _filename_node *next;
+} _filename_node_t;
+
+typedef struct _filename_list {
+    _filename_node_t *head;
+    _filename_node_t **tail;
+} _filename_list_t;
+
 typedef struct {
     int output_is_a_tty;
     int verbose;
@@ -30,6 +40,9 @@ typedef struct {
     int processed_files;
     int added_messages;
     struct timeval tv_start;
+
+    _filename_list_t *removed_files;
+    _filename_list_t *removed_directories;
 } add_files_state_t;
 
 static volatile sig_atomic_t do_add_files_print_progress = 0;
@@ -52,6 +65,34 @@ handle_sigint (unused (int sig))
     interrupted = 1;
 }
 
+static _filename_list_t *
+_filename_list_create (const void *ctx)
+{
+    _filename_list_t *list;
+
+    list = talloc (ctx, _filename_list_t);
+    if (list == NULL)
+       return NULL;
+
+    list->head = NULL;
+    list->tail = &list->head;
+
+    return list;
+}
+
+static void
+_filename_list_add (_filename_list_t *list,
+                   const char *filename)
+{
+    _filename_node_t *node = talloc (list, _filename_node_t);
+
+    node->filename = talloc_strdup (list, filename);
+    node->next = NULL;
+
+    *(list->tail) = node;
+    list->tail = &node->next;
+}
+
 static void
 tag_inbox_and_unread (notmuch_message_t *message)
 {
@@ -267,8 +308,11 @@ add_files_recursive (notmuch_database_t *notmuch,
        while (notmuch_filenames_has_more (db_files) &&
               strcmp (notmuch_filenames_get (db_files), entry->d_name) < 0)
        {
-           printf ("Detected deleted file %s/%s\n", path,
-                   notmuch_filenames_get (db_files));
+           char *absolute = talloc_asprintf (state->removed_files,
+                                             "%s/%s", path,
+                                             notmuch_filenames_get (db_files));
+
+           _filename_list_add (state->removed_files, absolute);
 
            notmuch_filenames_advance (db_files);
        }
@@ -276,9 +320,15 @@ add_files_recursive (notmuch_database_t *notmuch,
        while (notmuch_filenames_has_more (db_subdirs) &&
               strcmp (notmuch_filenames_get (db_subdirs), entry->d_name) <= 0)
        {
-           if (strcmp (notmuch_filenames_get (db_subdirs), entry->d_name) < 0)
-               printf ("Detected deleted directory %s/%s", path,
-                       notmuch_filenames_get (db_subdirs));
+           const char *filename = notmuch_filenames_get (db_subdirs);
+
+           if (strcmp (filename, entry->d_name) < 0)
+           {
+               char *absolute = talloc_asprintf (state->removed_directories,
+                                                 "%s/%s", path, filename);
+
+               _filename_list_add (state->removed_directories, absolute);
+           }
 
            notmuch_filenames_advance (db_subdirs);
        }
@@ -516,6 +566,9 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
     const char *db_path;
     char *dot_notmuch_path;
     struct sigaction action;
+    _filename_node_t *f;
+    int renamed_files, removed_files;
+    notmuch_status_t status;
     int i;
 
     add_files_state.verbose = 0;
@@ -572,11 +625,53 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
     add_files_state.added_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);
+
     ret = add_files (notmuch, db_path, &add_files_state);
 
+    removed_files = 0;
+    renamed_files = 0;
+    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_directories->head; f; f = f->next) {
+       notmuch_directory_t *directory;
+       notmuch_filenames_t *files;
+
+       directory = notmuch_database_get_directory (notmuch, f->filename);
+
+       for (files = notmuch_directory_get_child_files (directory);
+            notmuch_filenames_has_more (files);
+            notmuch_filenames_advance (files))
+       {
+           char *absolute;
+
+           absolute = talloc_asprintf (ctx, "%s/%s", f->filename,
+                                       notmuch_filenames_get (files));
+           status = notmuch_database_remove_message (notmuch, absolute);
+           if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID)
+               renamed_files++;
+           else
+               removed_files++;
+           talloc_free (absolute);
+       }
+
+       notmuch_directory_destroy (directory);
+    }
+
+    talloc_free (add_files_state.removed_files);
+    talloc_free (add_files_state.removed_directories);
+
     gettimeofday (&tv_now, NULL);
     elapsed = notmuch_time_elapsed (add_files_state.tv_start,
                                    tv_now);
+
     if (add_files_state.processed_files) {
        printf ("Processed %d %s in ", add_files_state.processed_files,
                add_files_state.processed_files == 1 ?
@@ -589,15 +684,30 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
            printf (".                    \n");
        }
     }
+
     if (add_files_state.added_messages) {
-       printf ("Added %d new %s to the database.\n",
+       printf ("Added %d new %s to the database.",
                add_files_state.added_messages,
                add_files_state.added_messages == 1 ?
                "message" : "messages");
     } else {
-       printf ("No new mail.\n");
+       printf ("No new mail.");
     }
 
+    if (removed_files) {
+       printf (" Removed %d %s.",
+               removed_files,
+               removed_files == 1 ? "message" : "messages");
+    }
+
+    if (renamed_files) {
+       printf (" Detected %d file %s.",
+               renamed_files,
+               renamed_files == 1 ? "rename" : "renames");
+    }
+
+    printf ("\n");
+
     if (ret) {
        printf ("\nNote: At least one error was encountered: %s\n",
                notmuch_status_to_string (ret));