]> git.notmuchmail.org Git - notmuch/blobdiff - notmuch-show.c
emacs: add notmuch-search-edit-search and notmuch-tree-edit-search
[notmuch] / notmuch-show.c
index 667fbee822a8d8a71e14213d1c3c6fef8a0137c3..ee9efa7448d78c171ec618d561bb1fa450576864 100644 (file)
 #include "sprinter.h"
 #include "zlib-extra.h"
 
+static const char *
+_get_filename (notmuch_message_t *message, int index)
+{
+    notmuch_filenames_t *filenames = notmuch_message_get_filenames (message);
+    int i = 1;
+
+    for (;
+        notmuch_filenames_valid (filenames);
+        notmuch_filenames_move_to_next (filenames), i++) {
+       if (i >= index)
+           return notmuch_filenames_get (filenames);
+    }
+    return NULL;
+}
+
 static const char *
 _get_tags_as_string (const void *ctx, notmuch_message_t *message)
 {
@@ -209,6 +224,30 @@ _is_from_line (const char *line)
        return 0;
 }
 
+/* Output extra headers if configured with the `show.extra_headers'
+ * configuration option
+ */
+static void
+format_extra_headers_sprinter (sprinter_t *sp, GMimeMessage *message)
+{
+    GMimeHeaderList *header_list = g_mime_object_get_header_list (GMIME_OBJECT (message));
+
+    for (notmuch_config_values_t *extra_headers = notmuch_config_get_values (
+            sp->notmuch, NOTMUCH_CONFIG_EXTRA_HEADERS);
+        notmuch_config_values_valid (extra_headers);
+        notmuch_config_values_move_to_next (extra_headers)) {
+       GMimeHeader *header;
+       const char *header_name = notmuch_config_values_get (extra_headers);
+
+       header = g_mime_header_list_get_header (header_list, header_name);
+       if (header == NULL)
+           continue;
+
+       sp->map_key (sp, g_mime_header_get_name (header));
+       sp->string (sp, g_mime_header_get_value (header));
+    }
+}
+
 void
 format_headers_sprinter (sprinter_t *sp, GMimeMessage *message,
                         bool reply, const _notmuch_message_crypto_t *msg_crypto)
@@ -269,6 +308,9 @@ format_headers_sprinter (sprinter_t *sp, GMimeMessage *message,
        sp->string (sp, g_mime_message_get_date_string (sp, message));
     }
 
+    /* Output extra headers the user has configured, if any */
+    if (! reply)
+       format_extra_headers_sprinter (sp, message);
     sp->end (sp);
     talloc_free (local);
 }
@@ -631,6 +673,7 @@ format_omitted_part_meta_sprinter (sprinter_t *sp, GMimeObject *meta, GMimePart
 
 void
 format_part_sprinter (const void *ctx, sprinter_t *sp, mime_node_t *node,
+                     int duplicate,
                      bool output_body,
                      bool include_html)
 {
@@ -642,10 +685,13 @@ format_part_sprinter (const void *ctx, sprinter_t *sp, mime_node_t *node,
        sp->begin_map (sp);
        format_message_sprinter (sp, node->envelope_file);
 
+       sp->map_key (sp, "duplicate");
+       sp->integer (sp, duplicate > 0 ? duplicate : 1);
+
        if (output_body) {
            sp->map_key (sp, "body");
            sp->begin_list (sp);
-           format_part_sprinter (ctx, sp, mime_node_child (node, 0), true, include_html);
+           format_part_sprinter (ctx, sp, mime_node_child (node, 0), -1, true, include_html);
            sp->end (sp);
        }
 
@@ -809,7 +855,7 @@ format_part_sprinter (const void *ctx, sprinter_t *sp, mime_node_t *node,
     }
 
     for (i = 0; i < node->nchildren; i++)
-       format_part_sprinter (ctx, sp, mime_node_child (node, i), true, include_html);
+       format_part_sprinter (ctx, sp, mime_node_child (node, i), -1, true, include_html);
 
     /* Close content structures */
     for (i = 0; i < nclose; i++)
@@ -823,7 +869,8 @@ format_part_sprinter_entry (const void *ctx, sprinter_t *sp,
                            mime_node_t *node, unused (int indent),
                            const notmuch_show_params_t *params)
 {
-    format_part_sprinter (ctx, sp, node, params->output_body, params->include_html);
+    format_part_sprinter (ctx, sp, node, params->duplicate, params->output_body,
+                         params->include_html);
 
     return NOTMUCH_STATUS_SUCCESS;
 }
@@ -898,7 +945,7 @@ format_part_raw (unused (const void *ctx), unused (sprinter_t *sp),
        char buf[4096];
        notmuch_status_t ret = NOTMUCH_STATUS_FILE_ERROR;
 
-       filename = notmuch_message_get_filename (node->envelope_file);
+       filename = _get_filename (node->envelope_file, params->duplicate);
        if (filename == NULL) {
            fprintf (stderr, "Error: Cannot get message filename.\n");
            goto DONE;
@@ -977,7 +1024,7 @@ show_message (void *ctx,
        session_key_count_error = notmuch_message_count_properties (message, "session-key",
                                                                    &session_keys);
 
-    status = mime_node_open (local, message, &(params->crypto), &root);
+    status = mime_node_open (local, message, params->duplicate, &(params->crypto), &root);
     if (status)
        goto DONE;
     part = mime_node_seek_dfs (root, (params->part < 0 ? 0 : params->part));
@@ -1239,6 +1286,7 @@ notmuch_show_command (notmuch_database_t *notmuch, int argc, char *argv[])
     sprinter_t *sprinter;
     notmuch_show_params_t params = {
        .part = -1,
+       .duplicate = 0,
        .omit_excluded = true,
        .output_body = true,
        .crypto = { .decrypt = NOTMUCH_DECRYPT_AUTO },
@@ -1279,6 +1327,7 @@ notmuch_show_command (notmuch_database_t *notmuch, int argc, char *argv[])
        { .opt_bool = &params.crypto.verify, .name = "verify" },
        { .opt_bool = &params.output_body, .name = "body" },
        { .opt_bool = &params.include_html, .name = "include-html" },
+       { .opt_int = &params.duplicate, .name = "duplicate" },
        { .opt_inherit = notmuch_shared_options },
        { }
     };
@@ -1297,6 +1346,9 @@ notmuch_show_command (notmuch_database_t *notmuch, int argc, char *argv[])
     /* specifying a part implies single message display */
     single_message = params.part >= 0;
 
+    /* specifying a duplicate also implies single message display */
+    single_message = single_message || (params.duplicate > 0);
+
     if (format == NOTMUCH_FORMAT_NOT_SPECIFIED) {
        /* if part was requested and format was not specified, use format=raw */
        if (params.part >= 0)
@@ -1364,11 +1416,11 @@ notmuch_show_command (notmuch_database_t *notmuch, int argc, char *argv[])
        return EXIT_FAILURE;
     }
 
-    query = notmuch_query_create (notmuch, query_string);
-    if (query == NULL) {
-       fprintf (stderr, "Out of memory\n");
+    status = notmuch_query_create_with_syntax (notmuch, query_string,
+                                              shared_option_query_syntax (),
+                                              &query);
+    if (print_status_database ("notmuch show", notmuch, status))
        return EXIT_FAILURE;
-    }
 
     notmuch_query_set_sort (query, sort);