aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Bremner <bremner@debian.org>2012-04-04 23:27:01 -0300
committerDavid Bremner <bremner@debian.org>2012-04-04 23:27:01 -0300
commit4adefd4c497a1977db36317ed34c406565fb201d (patch)
tree1d1d7c6cea688d8ef71f70a9a022165f60be3140 /lib
parent954cf155718a5a7576a7a578d836b76e15d312a4 (diff)
parent331f0cac61802606e0103c35453656d2299cbfe3 (diff)
Merge tag 'debian/0.12-1' into squeeze-backports
notmuch Debian 0.12-1 upload (same as 0.12 + debian changelog fix) Conflicts: debian/changelog
Diffstat (limited to 'lib')
-rw-r--r--lib/database.cc34
-rw-r--r--lib/index.cc19
-rw-r--r--lib/messages.c6
-rw-r--r--lib/notmuch-private.h2
-rw-r--r--lib/notmuch.h6
-rw-r--r--lib/query.cc35
6 files changed, 88 insertions, 14 deletions
diff --git a/lib/database.cc b/lib/database.cc
index 8103bd96..16c4354f 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -582,15 +582,15 @@ notmuch_database_t *
notmuch_database_open (const char *path,
notmuch_database_mode_t mode)
{
+ void *local = talloc_new (NULL);
notmuch_database_t *notmuch = NULL;
- char *notmuch_path = NULL, *xapian_path = NULL;
+ char *notmuch_path, *xapian_path;
struct stat st;
int err;
unsigned int i, version;
static int initialized = 0;
- if (asprintf (&notmuch_path, "%s/%s", path, ".notmuch") == -1) {
- notmuch_path = NULL;
+ if (! (notmuch_path = talloc_asprintf (local, "%s/%s", path, ".notmuch"))) {
fprintf (stderr, "Out of memory\n");
goto DONE;
}
@@ -602,8 +602,7 @@ notmuch_database_open (const char *path,
goto DONE;
}
- if (asprintf (&xapian_path, "%s/%s", notmuch_path, "xapian") == -1) {
- xapian_path = NULL;
+ if (! (xapian_path = talloc_asprintf (local, "%s/%s", notmuch_path, "xapian"))) {
fprintf (stderr, "Out of memory\n");
goto DONE;
}
@@ -617,7 +616,7 @@ notmuch_database_open (const char *path,
initialized = 1;
}
- notmuch = talloc (NULL, notmuch_database_t);
+ notmuch = talloc_zero (NULL, notmuch_database_t);
notmuch->exception_reported = FALSE;
notmuch->path = talloc_strdup (notmuch, path);
@@ -703,14 +702,12 @@ notmuch_database_open (const char *path,
} catch (const Xapian::Error &error) {
fprintf (stderr, "A Xapian exception occurred opening database: %s\n",
error.get_msg().c_str());
+ notmuch_database_close (notmuch);
notmuch = NULL;
}
DONE:
- if (notmuch_path)
- free (notmuch_path);
- if (xapian_path)
- free (xapian_path);
+ talloc_free (local);
return notmuch;
}
@@ -719,7 +716,8 @@ void
notmuch_database_close (notmuch_database_t *notmuch)
{
try {
- if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE)
+ if (notmuch->xapian_db != NULL &&
+ notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE)
(static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db))->flush ();
} catch (const Xapian::Error &error) {
if (! notmuch->exception_reported) {
@@ -728,6 +726,17 @@ notmuch_database_close (notmuch_database_t *notmuch)
}
}
+ /* Many Xapian objects (and thus notmuch objects) hold references to
+ * the database, so merely deleting the database may not suffice to
+ * close it. Thus, we explicitly close it here. */
+ if (notmuch->xapian_db != NULL) {
+ try {
+ notmuch->xapian_db->close();
+ } catch (const Xapian::Error &error) {
+ /* do nothing */
+ }
+ }
+
delete notmuch->term_gen;
delete notmuch->query_parser;
delete notmuch->xapian_db;
@@ -1816,6 +1825,9 @@ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,
if (message_ret == NULL)
return NOTMUCH_STATUS_NULL_POINTER;
+ /* return NULL on any failure */
+ *message_ret = NULL;
+
local = talloc_new (notmuch);
try {
diff --git a/lib/index.cc b/lib/index.cc
index e8e9922b..e3777322 100644
--- a/lib/index.cc
+++ b/lib/index.cc
@@ -315,6 +315,7 @@ _index_mime_part (notmuch_message_t *message,
GByteArray *byte_array;
GMimeContentDisposition *disposition;
char *body;
+ const char *charset;
if (! part) {
fprintf (stderr, "Warning: Not indexing empty mime part.\n");
@@ -339,6 +340,10 @@ _index_mime_part (notmuch_message_t *message,
if (i > 1)
fprintf (stderr, "Warning: Unexpected extra parts of multipart/signed. Indexing anyway.\n");
}
+ if (GMIME_IS_MULTIPART_ENCRYPTED (multipart)) {
+ /* Don't index encrypted parts. */
+ continue;
+ }
_index_mime_part (message,
g_mime_multipart_get_part (multipart, i));
}
@@ -386,6 +391,20 @@ _index_mime_part (notmuch_message_t *message,
g_mime_stream_filter_add (GMIME_STREAM_FILTER (filter),
discard_uuencode_filter);
+ charset = g_mime_object_get_content_type_parameter (part, "charset");
+ if (charset) {
+ GMimeFilter *charset_filter;
+ charset_filter = g_mime_filter_charset_new (charset, "UTF-8");
+ /* This result can be NULL for things like "unknown-8bit".
+ * Don't set a NULL filter as that makes GMime print
+ * annoying assertion-failure messages on stderr. */
+ if (charset_filter) {
+ g_mime_stream_filter_add (GMIME_STREAM_FILTER (filter),
+ charset_filter);
+ g_object_unref (charset_filter);
+ }
+ }
+
wrapper = g_mime_part_get_content_object (GMIME_PART (part));
if (wrapper)
g_mime_data_wrapper_write_to_stream (wrapper, filter);
diff --git a/lib/messages.c b/lib/messages.c
index 7bcd1abf..11218648 100644
--- a/lib/messages.c
+++ b/lib/messages.c
@@ -127,8 +127,10 @@ notmuch_messages_get (notmuch_messages_t *messages)
void
notmuch_messages_move_to_next (notmuch_messages_t *messages)
{
- if (! messages->is_of_list_type)
- return _notmuch_mset_messages_move_to_next (messages);
+ if (! messages->is_of_list_type) {
+ _notmuch_mset_messages_move_to_next (messages);
+ return;
+ }
if (messages->iterator == NULL)
return;
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 60a932fc..7bf153e0 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -458,7 +458,7 @@ typedef struct _notmuch_string_node {
struct _notmuch_string_node *next;
} notmuch_string_node_t;
-typedef struct _notmuch_string_list {
+typedef struct visible _notmuch_string_list {
int length;
notmuch_string_node_t *head;
notmuch_string_node_t **tail;
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 9f23a106..7929fe72 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -457,6 +457,12 @@ notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort);
notmuch_sort_t
notmuch_query_get_sort (notmuch_query_t *query);
+/* Add a tag that will be excluded from the query results by default.
+ * This exclusion will be overridden if this tag appears explicitly in
+ * the query. */
+void
+notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag);
+
/* Execute a query for threads, returning a notmuch_threads_t object
* which can be used to iterate over the results. The returned threads
* object is owned by the query and as such, will only be valid until
diff --git a/lib/query.cc b/lib/query.cc
index b6c0f12d..0b366025 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -27,6 +27,7 @@ struct _notmuch_query {
notmuch_database_t *notmuch;
const char *query_string;
notmuch_sort_t sort;
+ notmuch_string_list_t *exclude_terms;
};
typedef struct _notmuch_mset_messages {
@@ -76,6 +77,8 @@ notmuch_query_create (notmuch_database_t *notmuch,
query->sort = NOTMUCH_SORT_NEWEST_FIRST;
+ query->exclude_terms = _notmuch_string_list_create (query);
+
return query;
}
@@ -97,6 +100,13 @@ notmuch_query_get_sort (notmuch_query_t *query)
return query->sort;
}
+void
+notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag)
+{
+ char *term = talloc_asprintf (query, "%s%s", _find_prefix ("tag"), tag);
+ _notmuch_string_list_append (query->exclude_terms, term);
+}
+
/* We end up having to call the destructors explicitly because we had
* to use "placement new" in order to initialize C++ objects within a
* block that we allocated with talloc. So C++ is making talloc
@@ -112,6 +122,27 @@ _notmuch_messages_destructor (notmuch_mset_messages_t *messages)
return 0;
}
+/* Return a query that does not match messages with the excluded tags
+ * registered with the query. Any tags that explicitly appear in
+ * xquery will not be excluded. */
+static Xapian::Query
+_notmuch_exclude_tags (notmuch_query_t *query, Xapian::Query xquery)
+{
+ for (notmuch_string_node_t *term = query->exclude_terms->head; term;
+ term = term->next) {
+ Xapian::TermIterator it = xquery.get_terms_begin ();
+ Xapian::TermIterator end = xquery.get_terms_end ();
+ for (; it != end; it++) {
+ if ((*it).compare (term->string) == 0)
+ break;
+ }
+ if (it == end)
+ xquery = Xapian::Query (Xapian::Query::OP_AND_NOT,
+ xquery, Xapian::Query (term->string));
+ }
+ return xquery;
+}
+
notmuch_messages_t *
notmuch_query_search_messages (notmuch_query_t *query)
{
@@ -157,6 +188,8 @@ notmuch_query_search_messages (notmuch_query_t *query)
mail_query, string_query);
}
+ final_query = _notmuch_exclude_tags (query, final_query);
+
enquire.set_weighting_scheme (Xapian::BoolWeight());
switch (query->sort) {
@@ -436,6 +469,8 @@ notmuch_query_count_messages (notmuch_query_t *query)
mail_query, string_query);
}
+ final_query = _notmuch_exclude_tags (query, final_query);
+
enquire.set_weighting_scheme(Xapian::BoolWeight());
enquire.set_docid_order(Xapian::Enquire::ASCENDING);