typedef struct {
const char *db_path;
+ const char *mail_root;
+ notmuch_indexopts_t *indexopts;
int output_is_a_tty;
enum verbosity verbosity;
bool debug;
static void
handle_sigint (unused (int sig))
{
- static char msg[] = "Stopping... \n";
+ static const char msg[] = "Stopping... \n";
/* This write is "opportunistic", so it's okay to ignore the
* result. It is not required for correctness, and if it does
}
static char *
-_get_relative_path (const char *db_path, const char *dirpath, const char *entry)
+_get_relative_path (const char *mail_root, const char *dirpath, const char *entry)
{
- size_t db_path_len = strlen (db_path);
+ size_t mail_root_len = strlen (mail_root);
/* paranoia? */
- if (strncmp (dirpath, db_path, db_path_len) != 0) {
+ if (strncmp (dirpath, mail_root, mail_root_len) != 0) {
fprintf (stderr, "Warning: '%s' is not a subdirectory of '%s'\n",
- dirpath, db_path);
+ dirpath, mail_root);
return NULL;
}
- dirpath += db_path_len;
+ dirpath += mail_root_len;
while (*dirpath == '/')
dirpath++;
if (state->ignore_regex_length == 0)
return false;
- path = _get_relative_path (state->db_path, dirpath, entry);
+ path = _get_relative_path (state->mail_root, dirpath, entry);
if (! path)
return false;
if (status)
goto DONE;
- status = notmuch_database_index_file (notmuch, filename, indexing_cli_choices.opts, &message);
+ status = notmuch_database_index_file (notmuch, filename, state->indexopts, &message);
switch (status) {
/* Success. */
case NOTMUCH_STATUS_SUCCESS:
break;
/* Non-fatal issues (go on to next file). */
case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID:
- if (state->synchronize_flags)
- notmuch_message_maildir_flags_to_tags (message);
+ if (state->synchronize_flags) {
+ status = notmuch_message_maildir_flags_to_tags (message);
+ if (print_status_message ("add_file", message, status))
+ goto DONE;
+ }
break;
case NOTMUCH_STATUS_FILE_NOT_EMAIL:
fprintf (stderr, "Note: Ignoring non-mail file: %s\n", filename);
continue;
}
- /* Ignore the .notmuch directory and any "tmp" directory
+ /* Ignore any top level .notmuch directory and any "tmp" directory
* that appears within a maildir.
*/
if ((is_maildir && strcmp (entry->d_name, "tmp") == 0) ||
- strcmp (entry->d_name, ".notmuch") == 0)
+ (strcmp (entry->d_name, ".notmuch") == 0
+ && (strcmp (path, state->mail_root)) == 0))
continue;
next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name);
char *absolute = talloc_asprintf (state->removed_directories,
"%s/%s", path, filename);
if (state->debug)
- printf ("(D) add_files, pass 2: queuing passed directory %s for deletion from database\n",
- absolute);
+ printf (
+ "(D) add_files, pass 2: queuing passed directory %s for deletion from database\n",
+ absolute);
_filename_list_add (state->removed_directories, absolute);
}
notmuch_filenames_get (db_subdirs));
if (state->debug)
- printf ("(D) add_files, pass 3: queuing leftover directory %s for deletion from database\n",
- absolute);
+ printf (
+ "(D) add_files, pass 3: queuing leftover directory %s for deletion from database\n",
+ absolute);
_filename_list_add (state->removed_directories, absolute);
}
static int
-_maybe_upgrade (notmuch_database_t *notmuch, add_files_state_t *state) {
+_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;
- char *dot_notmuch_path = talloc_asprintf (notmuch, "%s/%s", state->db_path, ".notmuch");
+ 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. */
-
- 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);
+ 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");
}
int
-notmuch_new_command (unused(notmuch_config_t *config), notmuch_database_t *notmuch, int argc, char *argv[])
+notmuch_new_command (notmuch_database_t *notmuch, int argc, char *argv[])
{
add_files_state_t add_files_state = {
.verbosity = VERBOSITY_NORMAL,
};
struct timeval tv_start;
int ret = 0;
- const char *db_path;
- char *dot_notmuch_path;
+ const char *db_path, *mail_root;
struct sigaction action;
_filename_node_t *f;
int opt_index;
if (opt_index < 0)
return EXIT_FAILURE;
- notmuch_process_shared_options (argv[0]);
+ notmuch_process_shared_options (notmuch, argv[0]);
/* quiet trumps verbose */
if (quiet)
else if (verbose)
add_files_state.verbosity = VERBOSITY_VERBOSE;
+ add_files_state.indexopts = notmuch_database_get_default_indexopts (notmuch);
+
add_files_state.new_tags = notmuch_config_get_values (notmuch, NOTMUCH_CONFIG_NEW_TAGS);
if (print_status_database (
db_path = notmuch_config_get (notmuch, NOTMUCH_CONFIG_DATABASE_PATH);
add_files_state.db_path = db_path;
+ mail_root = notmuch_config_get (notmuch, NOTMUCH_CONFIG_MAIL_ROOT);
+ add_files_state.mail_root = mail_root;
+
if (! _setup_ignore (notmuch, &add_files_state))
return EXIT_FAILURE;
for (notmuch_config_values_start (add_files_state.new_tags);
notmuch_config_values_valid (add_files_state.new_tags);
notmuch_config_values_move_to_next (add_files_state.new_tags)) {
- const char *tag,*error_msg;
+ const char *tag, *error_msg;
tag = notmuch_config_values_get (add_files_state.new_tags);
error_msg = illegal_tag (tag, false);
}
if (hooks) {
- ret = notmuch_run_hook (db_path, "pre-new");
- if (ret)
+ /* Drop write lock to run hook */
+ status = notmuch_database_reopen (notmuch, NOTMUCH_DATABASE_MODE_READ_ONLY);
+ if (print_status_database ("notmuch new", notmuch, status))
return EXIT_FAILURE;
- }
- dot_notmuch_path = talloc_asprintf (notmuch, "%s/%s", db_path, ".notmuch");
+ ret = notmuch_run_hook (notmuch, "pre-new");
+ if (ret)
+ return EXIT_FAILURE;
- notmuch_exit_if_unmatched_db_uuid (notmuch);
+ /* acquire write lock again */
+ status = notmuch_database_reopen (notmuch, NOTMUCH_DATABASE_MODE_READ_WRITE);
+ if (print_status_database ("notmuch new", notmuch, status))
+ return EXIT_FAILURE;
+ }
if (notmuch_database_get_revision (notmuch, NULL) == 0) {
int count = 0;
- count_files (db_path, &count, &add_files_state);
+ count_files (mail_root, &count, &add_files_state);
if (interrupted)
return EXIT_FAILURE;
if (notmuch == NULL)
return EXIT_FAILURE;
- status = notmuch_process_shared_indexing_options (notmuch);
+ status = notmuch_process_shared_indexing_options (add_files_state.indexopts);
if (status != NOTMUCH_STATUS_SUCCESS) {
fprintf (stderr, "Error: Failed to process index options. (%s)\n",
notmuch_status_to_string (status));
action.sa_flags = SA_RESTART;
sigaction (SIGINT, &action, NULL);
- talloc_free (dot_notmuch_path);
- dot_notmuch_path = NULL;
-
gettimeofday (&add_files_state.tv_start, NULL);
add_files_state.removed_files = _filename_list_create (notmuch);
timer_is_active = true;
}
- ret = add_files (notmuch, db_path, &add_files_state);
+ ret = add_files (notmuch, mail_root, &add_files_state);
if (ret)
goto DONE;
if (do_print_progress) {
do_print_progress = 0;
generic_print_progress ("Cleaned up", "messages",
- tv_start, add_files_state.removed_messages + add_files_state.renamed_messages,
+ tv_start, add_files_state.removed_messages +
+ add_files_state.renamed_messages,
add_files_state.removed_files->count);
}
}
notmuch_database_close (notmuch);
if (hooks && ! ret && ! interrupted)
- ret = notmuch_run_hook (db_path, "post-new");
+ ret = notmuch_run_hook (notmuch, "post-new");
notmuch_database_destroy (notmuch);