X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=lib%2Fopen.cc;h=54d1faf30127c8a72f3c96e838cf9d4edba7e70a;hb=3f5809bf28becbddfed9ff33d6f1242346904c23;hp=4e5d25451aa7a6bb31b190556fe1de9cdcc2043f;hpb=fd0edeb561e5593d8a834fcc74602b2d8c637123;p=notmuch diff --git a/lib/open.cc b/lib/open.cc index 4e5d2545..54d1faf3 100644 --- a/lib/open.cc +++ b/lib/open.cc @@ -3,6 +3,7 @@ #include "database-private.h" #include "parse-time-vrp.h" +#include "lastmod-fp.h" #include "path-util.h" #if HAVE_XAPIAN_DB_RETRY_LOCK @@ -190,9 +191,10 @@ _choose_database_path (notmuch_database_t *notmuch, const char *profile, GKeyFile *key_file, const char **database_path, - bool *split, char **message) { + notmuch_status_t status; + if (! *database_path) { *database_path = getenv ("NOTMUCH_DATABASE"); } @@ -208,14 +210,12 @@ _choose_database_path (notmuch_database_t *notmuch, } } if (! *database_path) { - notmuch_status_t status; - *database_path = _xdg_dir (notmuch, "XDG_DATA_HOME", ".local/share", profile); status = _db_dir_exists (*database_path, message); if (status) { *database_path = NULL; } else { - *split = true; + notmuch->params |= NOTMUCH_PARAM_SPLIT; } } @@ -224,8 +224,6 @@ _choose_database_path (notmuch_database_t *notmuch, } if (! *database_path) { - notmuch_status_t status; - *database_path = talloc_asprintf (notmuch, "%s/mail", getenv ("HOME")); status = _db_dir_exists (*database_path, message); if (status) { @@ -242,6 +240,66 @@ _choose_database_path (notmuch_database_t *notmuch, *message = strdup ("Error: Database path must be absolute.\n"); return NOTMUCH_STATUS_PATH_ERROR; } + + status = _db_dir_exists (*database_path, message); + if (status) { + IGNORE_RESULT (asprintf (message, + "Error: database path '%s' does not exist or is not a directory.\n", + *database_path)); + return NOTMUCH_STATUS_NO_DATABASE; + } + + return NOTMUCH_STATUS_SUCCESS; +} + +static notmuch_status_t +_mkdir (const char *path, char **message) +{ + if (g_mkdir_with_parents (path, 0755)) { + IGNORE_RESULT (asprintf (message, "Error: Cannot create directory %s: %s.\n", + path, strerror (errno))); + return NOTMUCH_STATUS_FILE_ERROR; + } + return NOTMUCH_STATUS_SUCCESS; +} + +static notmuch_status_t +_create_database_path (notmuch_database_t *notmuch, + const char *profile, + GKeyFile *key_file, + const char **database_path, + char **message) +{ + notmuch_status_t status; + + if (! *database_path) { + *database_path = getenv ("NOTMUCH_DATABASE"); + } + + if (! *database_path && key_file) { + char *path = g_key_file_get_string (key_file, "database", "path", NULL); + if (path) { + if (path[0] == '/') + *database_path = talloc_strdup (notmuch, path); + else + *database_path = talloc_asprintf (notmuch, "%s/%s", getenv ("HOME"), path); + g_free (path); + } + } + + if (! *database_path) { + *database_path = _xdg_dir (notmuch, "XDG_DATA_HOME", ".local/share", profile); + notmuch->params |= NOTMUCH_PARAM_SPLIT; + } + + if (*database_path[0] != '/') { + *message = strdup ("Error: Database path must be absolute.\n"); + return NOTMUCH_STATUS_PATH_ERROR; + } + + if ((status = _mkdir (*database_path, message))) + return status; + return NOTMUCH_STATUS_SUCCESS; } @@ -262,6 +320,8 @@ _alloc_notmuch (const char *database_path, const char *config_path, const char * notmuch->transaction_count = 0; notmuch->transaction_threshold = 0; notmuch->view = 1; + notmuch->index_as_text = NULL; + notmuch->index_as_text_length = 0; notmuch->params = NOTMUCH_PARAM_NONE; if (database_path) @@ -369,6 +429,53 @@ _load_database_state (notmuch_database_t *notmuch) notmuch, notmuch->xapian_db->get_uuid ().c_str ()); } +/* XXX This should really be done lazily, but the error reporting path in the indexing code + * would need to be redone to report any errors. + */ +notmuch_status_t +_ensure_index_as_text (notmuch_database_t *notmuch, char **message) +{ + int nregex = 0; + regex_t *regexv = NULL; + + if (notmuch->index_as_text) + return NOTMUCH_STATUS_SUCCESS; + + for (notmuch_config_values_t *list = notmuch_config_get_values (notmuch, + NOTMUCH_CONFIG_INDEX_AS_TEXT); + notmuch_config_values_valid (list); + notmuch_config_values_move_to_next (list)) { + regex_t *new_regex; + int rerr; + const char *str = notmuch_config_values_get (list); + size_t len = strlen (str); + + /* str must be non-empty, because n_c_get_values skips empty + * strings */ + assert (len > 0); + + regexv = talloc_realloc (notmuch, regexv, regex_t, nregex + 1); + new_regex = ®exv[nregex]; + + rerr = regcomp (new_regex, str, REG_EXTENDED | REG_NOSUB); + if (rerr) { + size_t error_size = regerror (rerr, new_regex, NULL, 0); + char *error = (char *) talloc_size (str, error_size); + + regerror (rerr, new_regex, error, error_size); + IGNORE_RESULT (asprintf (message, "Error in index.as_text: %s: %s\n", error, str)); + + return NOTMUCH_STATUS_ILLEGAL_ARGUMENT; + } + nregex++; + } + + notmuch->index_as_text = regexv; + notmuch->index_as_text_length = nregex; + + return NOTMUCH_STATUS_SUCCESS; +} + static notmuch_status_t _finish_open (notmuch_database_t *notmuch, const char *profile, @@ -432,8 +539,7 @@ _finish_open (notmuch_database_t *notmuch, notmuch->value_range_processor = new Xapian::NumberRangeProcessor (NOTMUCH_VALUE_TIMESTAMP); notmuch->date_range_processor = new ParseTimeRangeProcessor (NOTMUCH_VALUE_TIMESTAMP, "date:"); - notmuch->last_mod_range_processor = new Xapian::NumberRangeProcessor (NOTMUCH_VALUE_LAST_MOD, - "lastmod:"); + notmuch->last_mod_range_processor = new LastModRangeProcessor (notmuch, "lastmod:"); notmuch->query_parser->set_default_op (Xapian::Query::OP_AND); notmuch->query_parser->set_database (*notmuch->xapian_db); notmuch->stemmer = new Xapian::Stem ("english"); @@ -474,6 +580,10 @@ _finish_open (notmuch_database_t *notmuch, if (status) goto DONE; + status = _ensure_index_as_text (notmuch, &message); + if (status) + goto DONE; + autocommit_str = notmuch_config_get (notmuch, NOTMUCH_CONFIG_AUTOCOMMIT); if (unlikely (! autocommit_str)) { INTERNAL_ERROR ("missing configuration for autocommit"); @@ -513,7 +623,6 @@ notmuch_database_open_with_config (const char *database_path, notmuch_database_t *notmuch = NULL; char *message = NULL; GKeyFile *key_file = NULL; - bool split = false; _notmuch_init (); @@ -530,7 +639,7 @@ notmuch_database_open_with_config (const char *database_path, } if ((status = _choose_database_path (notmuch, profile, key_file, - &database_path, &split, + &database_path, &message))) goto DONE; @@ -609,8 +718,6 @@ notmuch_database_create_with_config (const char *database_path, const char *notmuch_path = NULL; char *message = NULL; GKeyFile *key_file = NULL; - int err; - bool split = false; _notmuch_init (); @@ -626,28 +733,35 @@ notmuch_database_create_with_config (const char *database_path, goto DONE; } - if ((status = _choose_database_path (notmuch, profile, key_file, - &database_path, &split, &message))) - goto DONE; - - status = _db_dir_exists (database_path, &message); - if (status) + status = _choose_database_path (notmuch, profile, key_file, + &database_path, &message); + switch (status) { + case NOTMUCH_STATUS_SUCCESS: + break; + case NOTMUCH_STATUS_NO_DATABASE: + if ((status = _create_database_path (notmuch, profile, key_file, + &database_path, &message))) + goto DONE; + break; + default: goto DONE; + } _set_database_path (notmuch, database_path); - if (key_file && ! split) { + if (key_file && ! (notmuch->params & NOTMUCH_PARAM_SPLIT)) { char *mail_root = notmuch_canonicalize_file_name ( g_key_file_get_string (key_file, "database", "mail_root", NULL)); char *db_path = notmuch_canonicalize_file_name (database_path); - split = (mail_root && (0 != strcmp (mail_root, db_path))); + if (mail_root && (0 != strcmp (mail_root, db_path))) + notmuch->params |= NOTMUCH_PARAM_SPLIT; free (mail_root); free (db_path); } - if (split) { + if (notmuch->params & NOTMUCH_PARAM_SPLIT) { notmuch_path = database_path; } else { if (! (notmuch_path = talloc_asprintf (notmuch, "%s/%s", database_path, ".notmuch"))) { @@ -655,15 +769,9 @@ notmuch_database_create_with_config (const char *database_path, goto DONE; } - err = mkdir (notmuch_path, 0755); - if (err) { - if (errno != EEXIST) { - IGNORE_RESULT (asprintf (&message, "Error: Cannot create directory %s: %s.\n", - notmuch_path, strerror (errno))); - status = NOTMUCH_STATUS_FILE_ERROR; - goto DONE; - } - } + status = _mkdir (notmuch_path, &message); + if (status) + goto DONE; } if (! (notmuch->xapian_path = talloc_asprintf (notmuch, "%s/%s", notmuch_path, "xapian"))) { @@ -805,7 +913,6 @@ notmuch_database_load_config (const char *database_path, notmuch_database_t *notmuch = NULL; char *message = NULL; GKeyFile *key_file = NULL; - bool split = false; _notmuch_init (); @@ -828,7 +935,7 @@ notmuch_database_load_config (const char *database_path, } status = _choose_database_path (notmuch, profile, key_file, - &database_path, &split, &message); + &database_path, &message); switch (status) { case NOTMUCH_STATUS_NO_DATABASE: case NOTMUCH_STATUS_SUCCESS: