X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=notmuch-reply.c;h=7242310a7ec5f376872ac065044cbfc0e7c1fedb;hp=71edb662e02edb35fcdc3441ec2e92e33d3d2674;hb=80ae1829c19f1fbe714232defcf12f18bc99ddb8;hpb=362ab047c264ae67ec3de041aec637979077db21 diff --git a/notmuch-reply.c b/notmuch-reply.c index 71edb662..7242310a 100644 --- a/notmuch-reply.c +++ b/notmuch-reply.c @@ -25,32 +25,26 @@ #include "gmime-filter-headers.h" static void -reply_part_content (GMimeObject *part) -{ - GMimeStream *stream_stdout = NULL, *stream_filter = NULL; - GMimeDataWrapper *wrapper; - const char *charset; +reply_headers_message_part (GMimeMessage *message); - charset = g_mime_object_get_content_type_parameter (part, "charset"); - stream_stdout = g_mime_stream_file_new (stdout); - if (stream_stdout) { - g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE); - stream_filter = g_mime_stream_filter_new(stream_stdout); - if (charset) { - g_mime_stream_filter_add(GMIME_STREAM_FILTER(stream_filter), - g_mime_filter_charset_new(charset, "UTF-8")); - } - } - g_mime_stream_filter_add(GMIME_STREAM_FILTER(stream_filter), - g_mime_filter_reply_new(TRUE)); - wrapper = g_mime_part_get_content_object (GMIME_PART (part)); - if (wrapper && stream_filter) - g_mime_data_wrapper_write_to_stream (wrapper, stream_filter); - if (stream_filter) - g_object_unref(stream_filter); - if (stream_stdout) - g_object_unref(stream_stdout); -} +static void +reply_part_content (GMimeObject *part); + +static const notmuch_show_format_t format_reply = { + "", + "", NULL, + "", NULL, reply_headers_message_part, ">\n", + "", + NULL, + NULL, + NULL, + reply_part_content, + NULL, + "", + "", + "", "", + "" +}; static void show_reply_headers (GMimeMessage *message) @@ -72,44 +66,84 @@ show_reply_headers (GMimeMessage *message) } static void -reply_part (GMimeObject *part, int *part_count, unused (int first)) +reply_headers_message_part (GMimeMessage *message) { - GMimeContentDisposition *disposition; - GMimeContentType *content_type; + InternetAddressList *recipients; + const char *recipients_string; + + printf ("> From: %s\n", g_mime_message_get_sender (message)); + recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_TO); + recipients_string = internet_address_list_to_string (recipients, 0); + if (recipients_string) + printf ("> To: %s\n", + recipients_string); + recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_CC); + recipients_string = internet_address_list_to_string (recipients, 0); + if (recipients_string) + printf ("> Cc: %s\n", + recipients_string); + printf ("> Subject: %s\n", g_mime_message_get_subject (message)); + printf ("> Date: %s\n", g_mime_message_get_date_as_string (message)); +} - (void) part_count; - disposition = g_mime_object_get_content_disposition (part); - if (disposition && - strcmp (disposition->disposition, GMIME_DISPOSITION_ATTACHMENT) == 0) - { - const char *filename = g_mime_part_get_filename (GMIME_PART (part)); - content_type = g_mime_object_get_content_type (GMIME_OBJECT (part)); - if (g_mime_content_type_is_type (content_type, "text", "*") && - !g_mime_content_type_is_type (content_type, "text", "html")) - { - reply_part_content (part); - } - else - { - printf ("Attachment: %s (%s)\n", filename, - g_mime_content_type_to_string (content_type)); - } +static void +reply_part_content (GMimeObject *part) +{ + GMimeContentType *content_type = g_mime_object_get_content_type (GMIME_OBJECT (part)); + GMimeContentDisposition *disposition = g_mime_object_get_content_disposition (part); - return; + if (g_mime_content_type_is_type (content_type, "multipart", "*") || + g_mime_content_type_is_type (content_type, "message", "rfc822")) + { + /* Output nothing, since multipart subparts will be handled individually. */ } - - content_type = g_mime_object_get_content_type (GMIME_OBJECT (part)); - - if (g_mime_content_type_is_type (content_type, "text", "*") && + else if (g_mime_content_type_is_type (content_type, "application", "pgp-encrypted") || + g_mime_content_type_is_type (content_type, "application", "pgp-signature")) + { + /* Ignore PGP/MIME cruft parts */ + } + else if (g_mime_content_type_is_type (content_type, "text", "*") && !g_mime_content_type_is_type (content_type, "text", "html")) { - reply_part_content (part); + GMimeStream *stream_stdout = NULL, *stream_filter = NULL; + GMimeDataWrapper *wrapper; + const char *charset; + + charset = g_mime_object_get_content_type_parameter (part, "charset"); + stream_stdout = g_mime_stream_file_new (stdout); + if (stream_stdout) { + g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE); + stream_filter = g_mime_stream_filter_new(stream_stdout); + if (charset) { + g_mime_stream_filter_add(GMIME_STREAM_FILTER(stream_filter), + g_mime_filter_charset_new(charset, "UTF-8")); + } + } + g_mime_stream_filter_add(GMIME_STREAM_FILTER(stream_filter), + g_mime_filter_reply_new(TRUE)); + wrapper = g_mime_part_get_content_object (GMIME_PART (part)); + if (wrapper && stream_filter) + g_mime_data_wrapper_write_to_stream (wrapper, stream_filter); + if (stream_filter) + g_object_unref(stream_filter); + if (stream_stdout) + g_object_unref(stream_stdout); } else { - printf ("Non-text part: %s\n", - g_mime_content_type_to_string (content_type)); + if (disposition && + strcmp (disposition->disposition, GMIME_DISPOSITION_ATTACHMENT) == 0) + { + const char *filename = g_mime_part_get_filename (GMIME_PART (part)); + printf ("Attachment: %s (%s)\n", filename, + g_mime_content_type_to_string (content_type)); + } + else + { + printf ("Non-text part: %s\n", + g_mime_content_type_to_string (content_type)); + } } } @@ -279,7 +313,7 @@ add_recipients_from_message (GMimeMessage *reply, * The munging is easy to detect, because it results in a * redundant reply-to header, (with an address that already exists * in either To or Cc). So in this case, we ignore the Reply-To - * field and use the From header. Thie ensures the original sender + * field and use the From header. This ensures the original sender * will get the reply even if not subscribed to the list. Note * that the address in the Reply-To header will always appear in * the reply. @@ -363,7 +397,7 @@ guess_from_received_header (notmuch_config_t *config, notmuch_message_t *message * them indications to which email address this message was * delivered. * The Received: header is special in our get_header function - * and is always concated. + * and is always concatenated. */ received = notmuch_message_get_header (message, "received"); if (received == NULL) @@ -402,11 +436,14 @@ guess_from_received_header (notmuch_config_t *config, notmuch_message_t *message break; mta = xstrdup (by); token = strtok(mta," \t"); - if (token == NULL) + if (token == NULL) { + free (mta); break; + } /* Now extract the last two components of the MTA host name * as domain and tld. */ + domain = tld = NULL; while ((ptr = strsep (&token, delim)) != NULL) { if (*ptr == '\0') continue; @@ -425,13 +462,13 @@ guess_from_received_header (notmuch_config_t *config, notmuch_message_t *message if (strcasestr(primary, domain)) { free(mta); - return primary; - } - for (i = 0; i < other_len; i++) - if (strcasestr (other[i],domain)) { - free(mta); - return other[i]; + return primary; } + for (i = 0; i < other_len; i++) + if (strcasestr (other[i],domain)) { + free(mta); + return other[i]; + } } free (mta); } @@ -440,13 +477,17 @@ guess_from_received_header (notmuch_config_t *config, notmuch_message_t *message } static int -notmuch_reply_format_default(void *ctx, notmuch_config_t *config, notmuch_query_t *query) +notmuch_reply_format_default(void *ctx, + notmuch_config_t *config, + notmuch_query_t *query, + notmuch_show_params_t *params) { GMimeMessage *reply; notmuch_messages_t *messages; notmuch_message_t *message; const char *subject, *from_addr = NULL; const char *in_reply_to, *orig_references, *references; + const notmuch_show_format_t *format = &format_reply; for (messages = notmuch_query_search_messages (query); notmuch_messages_valid (messages); @@ -506,7 +547,7 @@ notmuch_reply_format_default(void *ctx, notmuch_config_t *config, notmuch_query_ notmuch_message_get_header (message, "from")); show_message_body (notmuch_message_get_filename (message), - reply_part, NULL); + format, params); notmuch_message_destroy (message); } @@ -515,7 +556,10 @@ notmuch_reply_format_default(void *ctx, notmuch_config_t *config, notmuch_query_ /* This format is currently tuned for a git send-email --notmuch hook */ static int -notmuch_reply_format_headers_only(void *ctx, notmuch_config_t *config, notmuch_query_t *query) +notmuch_reply_format_headers_only(void *ctx, + notmuch_config_t *config, + notmuch_query_t *query, + unused (notmuch_show_params_t *params)) { GMimeMessage *reply; notmuch_messages_t *messages; @@ -577,10 +621,13 @@ notmuch_reply_command (void *ctx, int argc, char *argv[]) notmuch_query_t *query; char *opt, *query_string; int i, ret = 0; - int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query); + int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params); + notmuch_show_params_t params = { .part = -1 }; reply_format_func = notmuch_reply_format_default; + argc--; argv++; /* skip subcommand argument */ + for (i = 0; i < argc && argv[i][0] == '-'; i++) { if (strcmp (argv[i], "--") == 0) { i++; @@ -596,6 +643,18 @@ notmuch_reply_command (void *ctx, int argc, char *argv[]) fprintf (stderr, "Invalid value for --format: %s\n", opt); return 1; } + } else if ((STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) { + if (params.cryptoctx == NULL) { + GMimeSession* session = g_object_new(g_mime_session_get_type(), NULL); + if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, "gpg"))) { + fprintf (stderr, "Failed to construct gpg context.\n"); + } else { + params.decrypt = TRUE; + g_mime_gpg_context_set_always_trust((GMimeGpgContext*)params.cryptoctx, FALSE); + } + g_object_unref (session); + session = NULL; + } } else { fprintf (stderr, "Unrecognized option: %s\n", argv[i]); return 1; @@ -631,11 +690,14 @@ notmuch_reply_command (void *ctx, int argc, char *argv[]) return 1; } - if (reply_format_func (ctx, config, query) != 0) + if (reply_format_func (ctx, config, query, ¶ms) != 0) return 1; notmuch_query_destroy (query); notmuch_database_close (notmuch); + if (params.cryptoctx) + g_object_unref(params.cryptoctx); + return ret; }