]> git.notmuchmail.org Git - notmuch/blobdiff - lib/open.cc
lib/open: fix potential double-free, ensure *database=NULL on error
[notmuch] / lib / open.cc
index 1e9c86fee1e0542a37796879e1bf53b6bc9fa5e3..77f01f727b6bdae860e4f7c84ce22c6af99e3a91 100644 (file)
@@ -209,8 +209,29 @@ _choose_database_path (void *ctx,
        }
     }
     if (! *database_path) {
+       notmuch_status_t status;
+
        *database_path = _xdg_dir (ctx, "XDG_DATA_HOME", ".local/share", profile);
-       *split = true;
+       status = _db_dir_exists (*database_path, message);
+       if (status) {
+           *database_path = NULL;
+       } else {
+           *split = true;
+       }
+    }
+
+    if (! *database_path) {
+       *database_path = getenv ("MAILDIR");
+    }
+
+    if (! *database_path) {
+       notmuch_status_t status;
+
+       *database_path = talloc_asprintf (ctx, "%s/mail", getenv ("HOME"));
+       status = _db_dir_exists (*database_path, message);
+       if (status) {
+           *database_path = NULL;
+       }
     }
 
     if (*database_path == NULL) {
@@ -225,7 +246,7 @@ _choose_database_path (void *ctx,
     return NOTMUCH_STATUS_SUCCESS;
 }
 
-notmuch_database_t *
+static notmuch_database_t *
 _alloc_notmuch ()
 {
     notmuch_database_t *notmuch;
@@ -239,6 +260,8 @@ _alloc_notmuch ()
     notmuch->writable_xapian_db = NULL;
     notmuch->config_path = NULL;
     notmuch->atomic_nesting = 0;
+    notmuch->transaction_count = 0;
+    notmuch->transaction_threshold = 0;
     notmuch->view = 1;
     return notmuch;
 }
@@ -307,24 +330,6 @@ _set_database_path (notmuch_database_t *notmuch,
     _notmuch_config_cache (notmuch, NOTMUCH_CONFIG_DATABASE_PATH, path);
 }
 
-static void
-_init_libs ()
-{
-
-    static int initialized = 0;
-
-    /* Initialize the GLib type system and threads */
-#if ! GLIB_CHECK_VERSION (2, 35, 1)
-    g_type_init ();
-#endif
-
-    /* Initialize gmime */
-    if (! initialized) {
-       g_mime_init ();
-       initialized = 1;
-    }
-}
-
 static void
 _load_database_state (notmuch_database_t *notmuch)
 {
@@ -366,6 +371,8 @@ _finish_open (notmuch_database_t *notmuch,
     notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
     char *incompat_features;
     char *message = NULL;
+    const char *autocommit_str;
+    char *autocommit_end;
     unsigned int version;
     const char *database_path = notmuch_database_get_path (notmuch);
 
@@ -389,8 +396,6 @@ _finish_open (notmuch_database_t *notmuch,
                                     "       has a newer database format version (%u) than supported by this\n"
                                     "       version of notmuch (%u).\n",
                                     database_path, version, NOTMUCH_DATABASE_VERSION));
-           notmuch_database_destroy (notmuch);
-           notmuch = NULL;
            status = NOTMUCH_STATUS_FILE_ERROR;
            goto DONE;
        }
@@ -407,8 +412,6 @@ _finish_open (notmuch_database_t *notmuch,
                                     "       requires features (%s)\n"
                                     "       not supported by this version of notmuch.\n",
                                     database_path, incompat_features));
-           notmuch_database_destroy (notmuch);
-           notmuch = NULL;
            status = NOTMUCH_STATUS_FILE_ERROR;
            goto DONE;
        }
@@ -425,7 +428,8 @@ _finish_open (notmuch_database_t *notmuch,
                                                                              "lastmod:");
        notmuch->query_parser->set_default_op (Xapian::Query::OP_AND);
        notmuch->query_parser->set_database (*notmuch->xapian_db);
-       notmuch->query_parser->set_stemmer (Xapian::Stem ("english"));
+       notmuch->stemmer = new Xapian::Stem ("english");
+       notmuch->query_parser->set_stemmer (*notmuch->stemmer);
        notmuch->query_parser->set_stemming_strategy (Xapian::QueryParser::STEM_SOME);
        notmuch->query_parser->add_rangeprocessor (notmuch->value_range_processor);
        notmuch->query_parser->add_rangeprocessor (notmuch->date_range_processor);
@@ -462,6 +466,14 @@ _finish_open (notmuch_database_t *notmuch,
        if (status)
            goto DONE;
 
+       autocommit_str = notmuch_config_get (notmuch, NOTMUCH_CONFIG_AUTOCOMMIT);
+       if (unlikely (! autocommit_str)) {
+           INTERNAL_ERROR ("missing configuration for autocommit");
+       }
+       notmuch->transaction_threshold = strtoul (autocommit_str, &autocommit_end, 10);
+       if (*autocommit_end != '\0')
+           INTERNAL_ERROR ("Malformed database database.autocommit value: %s", autocommit_str);
+
        status = _notmuch_database_setup_standard_query_fields (notmuch);
        if (status)
            goto DONE;
@@ -473,8 +485,6 @@ _finish_open (notmuch_database_t *notmuch,
     } catch (const Xapian::Error &error) {
        IGNORE_RESULT (asprintf (&message, "A Xapian exception occurred opening database: %s\n",
                                 error.get_msg ().c_str ()));
-       notmuch_database_destroy (notmuch);
-       notmuch = NULL;
        status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
     }
   DONE:
@@ -498,7 +508,7 @@ notmuch_database_open_with_config (const char *database_path,
     GKeyFile *key_file = NULL;
     bool split = false;
 
-    _init_libs ();
+    _notmuch_init ();
 
     notmuch = _alloc_notmuch ();
     if (! notmuch) {
@@ -543,10 +553,13 @@ notmuch_database_open_with_config (const char *database_path,
            free (message);
     }
 
+    if (status && notmuch) {
+       notmuch_database_destroy (notmuch);
+       notmuch = NULL;
+    }
+
     if (database)
        *database = notmuch;
-    else
-       talloc_free (notmuch);
 
     if (notmuch)
        notmuch->open = true;
@@ -595,7 +608,7 @@ notmuch_database_create_with_config (const char *database_path,
     int err;
     bool split = false;
 
-    _init_libs ();
+    _notmuch_init ();
 
     notmuch = _alloc_notmuch ();
     if (! notmuch) {
@@ -756,7 +769,7 @@ notmuch_database_reopen (notmuch_database_t *notmuch,
     return NOTMUCH_STATUS_SUCCESS;
 }
 
-notmuch_status_t
+static notmuch_status_t
 _maybe_load_config_from_database (notmuch_database_t *notmuch,
                                  GKeyFile *key_file,
                                  const char *database_path,
@@ -791,7 +804,7 @@ notmuch_database_load_config (const char *database_path,
     GKeyFile *key_file = NULL;
     bool split = false;
 
-    _init_libs ();
+    _notmuch_init ();
 
     notmuch = _alloc_notmuch ();
     if (! notmuch) {