+ struct timeval tv_now;
+
+ gettimeofday (&tv_now, NULL);
+ elapsed = notmuch_time_elapsed (state->tv_start, tv_now);
+
+ if (state->processed_files) {
+ printf ("Processed %d %s in ", state->processed_files,
+ state->processed_files == 1 ? "file" : "total files");
+ notmuch_time_print_formatted_seconds (elapsed);
+ if (elapsed > 1)
+ printf (" (%d files/sec.)",
+ (int) (state->processed_files / elapsed));
+ printf (".%s\n", (state->output_is_a_tty) ? "\033[K" : "");
+ }
+
+ if (state->added_messages)
+ printf ("Added %d new %s to the database.", state->added_messages,
+ state->added_messages == 1 ? "message" : "messages");
+ else
+ printf ("No new mail.");
+
+ if (state->removed_messages)
+ printf (" Removed %d %s.", state->removed_messages,
+ state->removed_messages == 1 ? "message" : "messages");
+
+ if (state->renamed_messages)
+ printf (" Detected %d file %s.", state->renamed_messages,
+ state->renamed_messages == 1 ? "rename" : "renames");
+
+ printf ("\n");
+}
+
+static int
+_maybe_upgrade (notmuch_database_t *notmuch, add_files_state_t *state)
+{
+ if (notmuch_database_needs_upgrade (notmuch)) {
+ time_t now = time (NULL);
+ struct tm *gm_time = gmtime (&now);
+ int err;
+ notmuch_status_t status;
+ const char *backup_dir = notmuch_config_get (notmuch, NOTMUCH_CONFIG_BACKUP_DIR);
+ const char *backup_name;
+
+ err = mkdir (backup_dir, 0755);
+ if (err && errno != EEXIST) {
+ fprintf (stderr, "Failed to create %s: %s\n", backup_dir, strerror (errno));
+ return EXIT_FAILURE;
+ }
+
+ /* since dump files are written atomically, the amount of
+ * harm from overwriting one within a second seems
+ * relatively small. */
+ backup_name = talloc_asprintf (notmuch, "%s/dump-%04d%02d%02dT%02d%02d%02d.gz",
+ backup_dir,
+ 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 (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, DUMP_INCLUDE_DEFAULT, true)) {
+ fprintf (stderr, "Backup failed. Aborting upgrade.");
+ return EXIT_FAILURE;
+ }
+
+ gettimeofday (&state->tv_start, NULL);
+ status = notmuch_database_upgrade (
+ notmuch,
+ state->verbosity >= VERBOSITY_NORMAL ? upgrade_print_progress : NULL,
+ state);
+ if (status) {
+ printf ("Upgrade failed: %s\n",
+ notmuch_status_to_string (status));
+ notmuch_database_destroy (notmuch);
+ return EXIT_FAILURE;
+ }
+ if (state->verbosity >= VERBOSITY_NORMAL)
+ printf ("Your notmuch database has now been upgraded.\n");
+ }
+ return EXIT_SUCCESS;
+}
+
+int
+notmuch_new_command (notmuch_database_t *notmuch, int argc, char *argv[])
+{
+ add_files_state_t add_files_state = {
+ .verbosity = VERBOSITY_NORMAL,
+ .debug = false,
+ .full_scan = false,
+ .output_is_a_tty = isatty (fileno (stdout)),
+ };
+ struct timeval tv_start;