Add support for indexing and searching the message's List-ID header. This is useful when matching all the messages belonging to a particular mailing list. Signed-off-by: Pablo Oliveira <pablo@sifflez.org> --- lib/database.cc | 3 ++- lib/index.cc | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- notmuch.1 | 2 ++ notmuch.c | 1 + 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/lib/database.cc b/lib/database.cc index b6c4d07..f5d695c 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -124,7 +124,8 @@ prefix_t PROBABILISTIC_PREFIX[]= { { "from", "XFROM" }, { "to", "XTO" }, { "attachment", "XATTACHMENT" }, - { "subject", "XSUBJECT"} + { "subject", "XSUBJECT"}, + { "listid", "XLISTID"} }; int diff --git a/lib/index.cc b/lib/index.cc index 125fa6c..b27a1dc 100644 --- a/lib/index.cc +++ b/lib/index.cc @@ -254,6 +254,50 @@ _index_mime_part (notmuch_message_t *message, free (body); } +static void +_index_listid (notmuch_message_t *message, + const char *list_id_header) +{ + const char *begin_list_id, *end_list_id; + + if (list_id_header == NULL) + return; + + /* RFC2919 says that the list-id is found at the end of the header + * and enclosed between angle brackets. If we cannot find a + * matching pair of brackets containing at least one character, + * we ignore the list id header. */ + + begin_list_id = strrchr (list_id_header, '<'); + if (!begin_list_id) + return; + + end_list_id = strrchr(begin_list_id, '>'); + if (!end_list_id || (end_list_id - begin_list_id < 2)) + return; + + void *local = talloc_new (NULL); + + /* We extract the list id between the angle brackets */ + const char *list_id = talloc_strndup(local, begin_list_id + 1, + end_list_id - begin_list_id - 1); + + /* All the text before is the description of the list */ + const char *description = talloc_strndup(local, list_id_header, + begin_list_id - list_id_header); + + /* Description may be RFC2047 encoded */ + char *decoded_desc = g_mime_utils_header_decode_phrase(description); + + _notmuch_message_gen_terms(message, "listid", list_id); + + if (decoded_desc) + _notmuch_message_gen_terms(message, "listid", decoded_desc); + + free(decoded_desc); + talloc_free (local); +} + notmuch_status_t _notmuch_message_index_file (notmuch_message_t *message, const char *filename) @@ -263,7 +307,7 @@ _notmuch_message_index_file (notmuch_message_t *message, GMimeMessage *mime_message = NULL; InternetAddressList *addresses; FILE *file = NULL; - const char *from, *subject; + const char *from, *subject, *listid; notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS; static int initialized = 0; @@ -298,6 +342,9 @@ _notmuch_message_index_file (notmuch_message_t *message, subject = skip_re_in_subject (subject); _notmuch_message_gen_terms (message, "subject", subject); + listid = g_mime_object_get_header (GMIME_OBJECT(mime_message), "List-Id"); + _index_listid (message, listid); + _index_mime_part (message, g_mime_message_get_mime_part (mime_message)); DONE: diff --git a/notmuch.1 b/notmuch.1 index 369ecba..2be7056 100644 --- a/notmuch.1 +++ b/notmuch.1 @@ -362,6 +362,8 @@ terms to match against specific portions of an email, (where thread:<thread-id> + listid:<list-id> + The .B from: prefix is used to match the name or address of the sender of an email diff --git a/notmuch.c b/notmuch.c index 2ac8a59..cc9233b 100644 --- a/notmuch.c +++ b/notmuch.c @@ -55,6 +55,7 @@ static const char search_terms_help[] = "\t\t\ttag:<tag>\n" "\t\t\tid:<message-id>\n" "\t\t\tthread:<thread-id>\n" + "\t\t\tlistid:<list-id>\n" "\n" "\t\tThe from: prefix is used to match the name or address of\n" "\t\tthe sender of an email message.\n" -- 1.6.3.3