X-Git-Url: https://git.notmuchmail.org/git?a=blobdiff_plain;f=notmuch-show.c;h=4dfe9c1d9def25c6294e335f999d2b5891b33ebb;hb=0a2929c341b6d5f20210725facf37a6e2c3a19b4;hp=65167c2f7851b0aab3fb811be1294b65bbaf4e21;hpb=bbe3015b3ea503b2834811f6cdd7276f9742faa1;p=notmuch diff --git a/notmuch-show.c b/notmuch-show.c index 65167c2f..4dfe9c1d 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -21,6 +21,7 @@ #include "notmuch-client.h" #include "gmime-filter-reply.h" #include "sprinter.h" +#include "zlib-extra.h" static const char * _get_tags_as_string (const void *ctx, notmuch_message_t *message) @@ -196,7 +197,7 @@ _is_from_line (const char *line) void format_headers_sprinter (sprinter_t *sp, GMimeMessage *message, - bool reply) + bool reply, const _notmuch_message_crypto_t *msg_crypto) { /* Any changes to the JSON or S-Expression format should be * reflected in the file devel/schemata. */ @@ -208,7 +209,10 @@ format_headers_sprinter (sprinter_t *sp, GMimeMessage *message, sp->begin_map (sp); sp->map_key (sp, "Subject"); - sp->string (sp, g_mime_message_get_subject (message)); + if (msg_crypto && msg_crypto->payload_subject) { + sp->string (sp, msg_crypto->payload_subject); + } else + sp->string (sp, g_mime_message_get_subject (message)); sp->map_key (sp, "From"); sp->string (sp, g_mime_message_get_from_string (message)); @@ -615,18 +619,69 @@ format_part_sprinter (const void *ctx, sprinter_t *sp, mime_node_t *node, * reflected in the file devel/schemata. */ if (node->envelope_file) { + const _notmuch_message_crypto_t *msg_crypto = NULL; sp->begin_map (sp); format_message_sprinter (sp, node->envelope_file); - sp->map_key (sp, "headers"); - format_headers_sprinter (sp, GMIME_MESSAGE (node->part), false); - 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); sp->end (sp); } + + msg_crypto = mime_node_get_message_crypto_status (node); + if (notmuch_format_version >= 4) { + sp->map_key (sp, "crypto"); + sp->begin_map (sp); + if (msg_crypto->sig_list || + msg_crypto->decryption_status != NOTMUCH_MESSAGE_DECRYPTED_NONE) { + if (msg_crypto->sig_list) { + sp->map_key (sp, "signed"); + sp->begin_map (sp); + sp->map_key (sp, "status"); + format_part_sigstatus_sprinter (sp, msg_crypto->sig_list); + if (msg_crypto->signature_encrypted) { + sp->map_key (sp, "encrypted"); + sp->boolean (sp, msg_crypto->signature_encrypted); + } + if (msg_crypto->payload_subject) { + sp->map_key (sp, "headers"); + sp->begin_list (sp); + sp->string (sp, "Subject"); + sp->end (sp); + } + sp->end (sp); + } + if (msg_crypto->decryption_status != NOTMUCH_MESSAGE_DECRYPTED_NONE) { + sp->map_key (sp, "decrypted"); + sp->begin_map (sp); + sp->map_key (sp, "status"); + sp->string (sp, msg_crypto->decryption_status == NOTMUCH_MESSAGE_DECRYPTED_FULL ? "full" : "partial"); + + if (msg_crypto->payload_subject) { + const char *subject = g_mime_message_get_subject GMIME_MESSAGE (node->part); + if (subject == NULL || strcmp (subject, msg_crypto->payload_subject)) { + /* protected subject differs from the external header */ + sp->map_key (sp, "header-mask"); + sp->begin_map (sp); + sp->map_key (sp, "Subject"); + if (subject == NULL) + sp->null (sp); + else + sp->string (sp, subject); + sp->end (sp); + } + } + sp->end (sp); + } + } + sp->end (sp); + } + + sp->map_key (sp, "headers"); + format_headers_sprinter (sp, GMIME_MESSAGE (node->part), false, msg_crypto); + sp->end (sp); return; } @@ -718,7 +773,7 @@ format_part_sprinter (const void *ctx, sprinter_t *sp, mime_node_t *node, sp->begin_map (sp); sp->map_key (sp, "headers"); - format_headers_sprinter (sp, GMIME_MESSAGE (node->part), false); + format_headers_sprinter (sp, GMIME_MESSAGE (node->part), false, NULL); sp->map_key (sp, "body"); sp->begin_list (sp); @@ -758,7 +813,7 @@ format_part_mbox (const void *ctx, unused (sprinter_t *sp), mime_node_t *node, notmuch_message_t *message = node->envelope_file; const char *filename; - FILE *file; + gzFile file; const char *from; time_t date; @@ -766,14 +821,14 @@ format_part_mbox (const void *ctx, unused (sprinter_t *sp), mime_node_t *node, char date_asctime[26]; char *line = NULL; - size_t line_size; + ssize_t line_size; ssize_t line_len; if (!message) INTERNAL_ERROR ("format_part_mbox requires a root part"); filename = notmuch_message_get_filename (message); - file = fopen (filename, "r"); + file = gzopen (filename, "r"); if (file == NULL) { fprintf (stderr, "Failed to open %s: %s\n", filename, strerror (errno)); @@ -789,7 +844,7 @@ format_part_mbox (const void *ctx, unused (sprinter_t *sp), mime_node_t *node, printf ("From %s %s", from, date_asctime); - while ((line_len = getline (&line, &line_size, file)) != -1 ) { + while ((line_len = gz_getline (message, &line, &line_size, file)) != UTIL_EOF ) { if (_is_from_line (line)) putchar ('>'); printf ("%s", line); @@ -797,7 +852,7 @@ format_part_mbox (const void *ctx, unused (sprinter_t *sp), mime_node_t *node, printf ("\n"); - fclose (file); + gzclose (file); return NOTMUCH_STATUS_SUCCESS; } @@ -810,39 +865,44 @@ format_part_raw (unused (const void *ctx), unused (sprinter_t *sp), if (node->envelope_file) { /* Special case the entire message to avoid MIME parsing. */ const char *filename; - FILE *file; - size_t size; + GMimeStream *stream = NULL; + ssize_t ssize; char buf[4096]; + notmuch_status_t ret = NOTMUCH_STATUS_FILE_ERROR; filename = notmuch_message_get_filename (node->envelope_file); if (filename == NULL) { fprintf (stderr, "Error: Cannot get message filename.\n"); - return NOTMUCH_STATUS_FILE_ERROR; + goto DONE; } - file = fopen (filename, "r"); - if (file == NULL) { + stream = g_mime_stream_gzfile_open (filename); + if (stream == NULL) { fprintf (stderr, "Error: Cannot open file %s: %s\n", filename, strerror (errno)); - return NOTMUCH_STATUS_FILE_ERROR; + goto DONE; } - while (!feof (file)) { - size = fread (buf, 1, sizeof (buf), file); - if (ferror (file)) { + while (! g_mime_stream_eos (stream)) { + ssize = g_mime_stream_read (stream, buf, sizeof(buf)); + if (ssize < 0) { fprintf (stderr, "Error: Read failed from %s\n", filename); - fclose (file); - return NOTMUCH_STATUS_FILE_ERROR; + goto DONE; } - if (fwrite (buf, size, 1, stdout) != 1) { - fprintf (stderr, "Error: Write failed\n"); - fclose (file); - return NOTMUCH_STATUS_FILE_ERROR; + if (ssize > 0 && fwrite (buf, ssize, 1, stdout) != 1) { + fprintf (stderr, "Error: Write %ld chars to stdout failed\n", ssize); + goto DONE; } } - fclose (file); - return NOTMUCH_STATUS_SUCCESS; + ret = NOTMUCH_STATUS_SUCCESS; + + /* XXX This DONE is just for the special case of a node in a single file */ + DONE: + if (stream) + g_object_unref (stream); + + return ret; } GMimeStream *stream_filter = g_mime_stream_filter_new (params->out_stream);