X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=notmuch-new.c;h=33645349cd5fd8abdb5936e185b5f5c70d529c08;hp=8529fdd3eac7e4214c47ef24317bed961b2912b5;hb=acd66cdec075312944e527febd46382e54d99367;hpb=957fc2e1a7d00636c7eaaf487edae65e7a63dc8f diff --git a/notmuch-new.c b/notmuch-new.c index 8529fdd3..33645349 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -19,6 +19,7 @@ */ #include "notmuch-client.h" +#include "tag-util.h" #include @@ -527,6 +528,10 @@ add_files (notmuch_database_t *notmuch, "%s/%s", path, notmuch_filenames_get (db_files)); + if (state->debug) + printf ("(D) add_files_recursive, pass 2: queuing passed file %s for deletion from database\n", + absolute); + _filename_list_add (state->removed_files, absolute); notmuch_filenames_move_to_next (db_files); @@ -541,6 +546,9 @@ add_files (notmuch_database_t *notmuch, { char *absolute = talloc_asprintf (state->removed_directories, "%s/%s", path, filename); + if (state->debug) + printf ("(D) add_files_recursive, pass 2: queuing passed directory %s for deletion from database\n", + absolute); _filename_list_add (state->removed_directories, absolute); } @@ -609,6 +617,9 @@ add_files (notmuch_database_t *notmuch, char *absolute = talloc_asprintf (state->removed_files, "%s/%s", path, notmuch_filenames_get (db_files)); + if (state->debug) + printf ("(D) add_files_recursive, pass 3: queuing leftover file %s for deletion from database\n", + absolute); _filename_list_add (state->removed_files, absolute); @@ -621,6 +632,10 @@ add_files (notmuch_database_t *notmuch, "%s/%s", path, notmuch_filenames_get (db_subdirs)); + if (state->debug) + printf ("(D) add_files_recursive, pass 3: queuing leftover directory %s for deletion from database\n", + absolute); + _filename_list_add (state->removed_directories, absolute); notmuch_filenames_move_to_next (db_subdirs); @@ -661,7 +676,7 @@ setup_progress_printing_timer (void) struct sigaction action; struct itimerval timerval; - /* Setup our handler for SIGALRM */ + /* Set up our handler for SIGALRM */ memset (&action, 0, sizeof (struct sigaction)); action.sa_handler = handle_sigalrm; sigemptyset (&action.sa_mask); @@ -863,6 +878,15 @@ _remove_directory (void *ctx, goto DONE; } + /* + * XXX: The library does not have a function to remove a directory + * document for a path. Usually this doesn't matter except for a + * slight waste of space. However, if the directory gets added to + * the filesystem again, the old directory document is found with + * the old mtime. Reset the directory mtime to avoid problems. + */ + notmuch_directory_set_mtime (directory, 0); + DONE: notmuch_directory_destroy (directory); return status; @@ -918,10 +942,11 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[]) struct sigaction action; _filename_node_t *f; int opt_index; - int i; + unsigned int i; notmuch_bool_t timer_is_active = FALSE; notmuch_bool_t no_hooks = FALSE; notmuch_bool_t quiet = FALSE, verbose = FALSE; + notmuch_status_t status; add_files_state.verbosity = VERBOSITY_NORMAL; add_files_state.debug = FALSE; @@ -932,6 +957,7 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[]) { NOTMUCH_OPT_BOOLEAN, &verbose, "verbose", 'v', 0 }, { NOTMUCH_OPT_BOOLEAN, &add_files_state.debug, "debug", 'd', 0 }, { NOTMUCH_OPT_BOOLEAN, &no_hooks, "no-hooks", 'n', 0 }, + { NOTMUCH_OPT_INHERIT, (void *) ¬much_shared_options, NULL, 0, 0 }, { 0, 0, 0, 0, 0 } }; @@ -939,6 +965,8 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[]) if (opt_index < 0) return EXIT_FAILURE; + notmuch_process_shared_options (argv[0]); + /* quiet trumps verbose */ if (quiet) add_files_state.verbosity = VERBOSITY_QUIET; @@ -950,6 +978,17 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[]) add_files_state.synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config); db_path = notmuch_config_get_database_path (config); + for (i = 0; i < add_files_state.new_tags_length; i++) { + const char *error_msg; + + error_msg = illegal_tag (add_files_state.new_tags[i], FALSE); + if (error_msg) { + fprintf (stderr, "Error: tag '%s' in new.tags: %s\n", + add_files_state.new_tags[i], error_msg); + return EXIT_FAILURE; + } + } + if (!no_hooks) { ret = notmuch_run_hook (db_path, "pre-new"); if (ret) @@ -972,20 +1011,61 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[]) return EXIT_FAILURE; add_files_state.total_files = count; } else { - if (notmuch_database_open (db_path, NOTMUCH_DATABASE_MODE_READ_WRITE, - ¬much)) + char *status_string = NULL; + if (notmuch_database_open_verbose (db_path, NOTMUCH_DATABASE_MODE_READ_WRITE, + ¬much, &status_string)) { + if (status_string) { + fputs (status_string, stderr); + free (status_string); + } return EXIT_FAILURE; + } + + notmuch_exit_if_unmatched_db_uuid (notmuch); if (notmuch_database_needs_upgrade (notmuch)) { - if (add_files_state.verbosity >= VERBOSITY_NORMAL) + time_t now = time (NULL); + struct tm *gm_time = gmtime (&now); + + /* since dump files are written atomically, the amount of + * harm from overwriting one within a second seems + * relatively small. */ + + const char *backup_name = + talloc_asprintf (notmuch, "%s/dump-%04d%02d%02dT%02d%02d%02d.gz", + dot_notmuch_path, + gm_time->tm_year + 1900, + gm_time->tm_mon + 1, + gm_time->tm_mday, + gm_time->tm_hour, + gm_time->tm_min, + gm_time->tm_sec); + + if (add_files_state.verbosity >= VERBOSITY_NORMAL) { printf ("Welcome to a new version of notmuch! Your database will now be upgraded.\n"); + printf ("This process is safe to interrupt.\n"); + printf ("Backing up tags to %s...\n", backup_name); + } + + if (notmuch_database_dump (notmuch, backup_name, "", + DUMP_FORMAT_BATCH_TAG, TRUE)) { + fprintf (stderr, "Backup failed. Aborting upgrade."); + return EXIT_FAILURE; + } + gettimeofday (&add_files_state.tv_start, NULL); - notmuch_database_upgrade (notmuch, - add_files_state.verbosity >= VERBOSITY_NORMAL ? upgrade_print_progress : NULL, - &add_files_state); + status = notmuch_database_upgrade ( + notmuch, + add_files_state.verbosity >= VERBOSITY_NORMAL ? upgrade_print_progress : NULL, + &add_files_state); + if (status) { + printf ("Upgrade failed: %s\n", + notmuch_status_to_string (status)); + notmuch_database_destroy (notmuch); + return EXIT_FAILURE; + } if (add_files_state.verbosity >= VERBOSITY_NORMAL) - printf ("Your notmuch database has now been upgraded to database format version %u.\n", - notmuch_database_get_version (notmuch)); + printf ("Your notmuch database has now been upgraded.\n"); } add_files_state.total_files = 0; @@ -994,7 +1074,7 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[]) if (notmuch == NULL) return EXIT_FAILURE; - /* Setup our handler for SIGINT. We do this after having + /* Set up our handler for SIGINT. We do this after having * potentially done a database upgrade we this interrupt handler * won't support. */ memset (&action, 0, sizeof (struct sigaction)); @@ -1052,7 +1132,6 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[]) } for (f = add_files_state.directory_mtimes->head; f && !interrupted; f = f->next) { - notmuch_status_t status; notmuch_directory_t *directory; status = notmuch_database_get_directory (notmuch, f->filename, &directory); if (status == NOTMUCH_STATUS_SUCCESS && directory) {