X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=notmuch-reply.c;h=2c30f6f9c798ea33f20b5ef0c5fab3091ffc165d;hp=2c7cc4eba674c7cd761a5532ccb67dd55ad8a2b9;hb=33382c2b5ba2537952a60ea378feff36961e4713;hpb=88f2a72ef1dcfce149bbac776652ea04e564726d diff --git a/notmuch-reply.c b/notmuch-reply.c index 2c7cc4eb..2c30f6f9 100644 --- a/notmuch-reply.c +++ b/notmuch-reply.c @@ -28,8 +28,8 @@ static void show_reply_headers (GMimeStream *stream, GMimeMessage *message) { /* Output RFC 2822 formatted (and RFC 2047 encoded) headers. */ - if (g_mime_object_write_to_stream (GMIME_OBJECT(message), stream) < 0) { - INTERNAL_ERROR("failed to write headers to stdout\n"); + if (g_mime_object_write_to_stream (GMIME_OBJECT (message), NULL, stream) < 0) { + INTERNAL_ERROR ("failed to write headers to stdout\n"); } } @@ -68,17 +68,17 @@ format_part_reply (GMimeStream *stream, mime_node_t *node) 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")) { + ! g_mime_content_type_is_type (content_type, "text", "html")) { show_text_part_content (node->part, stream, NOTMUCH_SHOW_TEXT_PART_REPLY); } else if (disposition && strcasecmp (g_mime_content_disposition_get_disposition (disposition), GMIME_DISPOSITION_ATTACHMENT) == 0) { const char *filename = g_mime_part_get_filename (GMIME_PART (node->part)); g_mime_stream_printf (stream, "Attachment: %s (%s)\n", filename, - g_mime_content_type_to_string (content_type)); + g_mime_content_type_get_mime_type (content_type)); } else { g_mime_stream_printf (stream, "Non-text part: %s\n", - g_mime_content_type_to_string (content_type)); + g_mime_content_type_get_mime_type (content_type)); } } @@ -117,7 +117,7 @@ address_match (const char *str, notmuch_config_t *config, address_match_t mode) const char **other; size_t i, other_len; - if (!str || *str == '\0') + if (! str || *str == '\0') return NULL; primary = notmuch_config_get_user_primary_email (config); @@ -176,7 +176,7 @@ static unsigned int scan_address_list (InternetAddressList *list, notmuch_config_t *config, GMimeMessage *message, - GMimeRecipientType type, + GMimeAddressType type, const char **user_from) { InternetAddress *address; @@ -209,7 +209,7 @@ scan_address_list (InternetAddressList *list, if (user_from && *user_from == NULL) *user_from = addr; } else if (message) { - g_mime_message_add_recipient (message, type, name, addr); + g_mime_message_add_mailbox (message, type, name, addr); n++; } } @@ -263,14 +263,15 @@ reply_to_header_is_redundant (GMimeMessage *message, return ret; } -static InternetAddressList *get_sender(GMimeMessage *message) +static InternetAddressList * +get_sender (GMimeMessage *message) { InternetAddressList *reply_to_list; reply_to_list = g_mime_message_get_reply_to_list (message); if (reply_to_list && internet_address_list_length (reply_to_list) > 0) { - /* + /* * Some mailing lists munge the Reply-To header despite it * being A Bad Thing, see * http://marc.merlins.org/netrants/reply-to-harmful.html @@ -285,24 +286,25 @@ static InternetAddressList *get_sender(GMimeMessage *message) */ if (! reply_to_header_is_redundant (message, reply_to_list)) return reply_to_list; - - g_mime_2_6_unref (G_OBJECT (reply_to_list)); } return g_mime_message_get_from (message); } -static InternetAddressList *get_to(GMimeMessage *message) +static InternetAddressList * +get_to (GMimeMessage *message) { return g_mime_message_get_addresses (message, GMIME_ADDRESS_TYPE_TO); } -static InternetAddressList *get_cc(GMimeMessage *message) +static InternetAddressList * +get_cc (GMimeMessage *message) { return g_mime_message_get_addresses (message, GMIME_ADDRESS_TYPE_CC); } -static InternetAddressList *get_bcc(GMimeMessage *message) +static InternetAddressList * +get_bcc (GMimeMessage *message) { return g_mime_message_get_addresses (message, GMIME_ADDRESS_TYPE_BCC); } @@ -325,20 +327,14 @@ add_recipients_from_message (GMimeMessage *reply, GMimeMessage *message, bool reply_all) { - - /* There is a memory leak here with gmime-2.6 because get_sender - * returns a newly allocated list, while the others return - * references to libgmime owned data. This leak will be fixed with - * the transition to gmime-3.0. - */ struct { InternetAddressList * (*get_header)(GMimeMessage *message); - GMimeRecipientType recipient_type; + GMimeAddressType recipient_type; } reply_to_map[] = { - { get_sender, GMIME_ADDRESS_TYPE_TO }, - { get_to, GMIME_ADDRESS_TYPE_TO }, - { get_cc, GMIME_ADDRESS_TYPE_CC }, - { get_bcc, GMIME_ADDRESS_TYPE_BCC }, + { get_sender, GMIME_ADDRESS_TYPE_TO }, + { get_to, GMIME_ADDRESS_TYPE_TO }, + { get_cc, GMIME_ADDRESS_TYPE_CC }, + { get_bcc, GMIME_ADDRESS_TYPE_BCC }, }; const char *from_addr = NULL; unsigned int i; @@ -352,7 +348,7 @@ add_recipients_from_message (GMimeMessage *reply, n += scan_address_list (recipients, config, reply, reply_to_map[i].recipient_type, &from_addr); - if (!reply_all && n) { + if (! reply_all && n) { /* Stop adding new recipients in reply-to-sender mode if * we have added some recipient(s) above. * @@ -369,6 +365,14 @@ add_recipients_from_message (GMimeMessage *reply, } } + /* If no recipients were added but we found one of the user's + * addresses to use as a from address then the message is from the + * user to the user - add the discovered from address to the list + * of recipients so that the reply goes back to the user. + */ + if (n == 0 && from_addr) + g_mime_message_add_mailbox (reply, GMIME_ADDRESS_TYPE_TO, NULL, from_addr); + return from_addr; } @@ -414,7 +418,7 @@ guess_from_in_received_by (notmuch_config_t *config, const char *received) if (*by == '\0') break; mta = xstrdup (by); - token = strtok(mta," \t"); + token = strtok (mta, " \t"); if (token == NULL) { free (mta); break; @@ -518,12 +522,12 @@ get_from_in_to_headers (notmuch_config_t *config, notmuch_message_t *message) } static GMimeMessage * -create_reply_message(void *ctx, - notmuch_config_t *config, - notmuch_message_t *message, - GMimeMessage *mime_message, - bool reply_all, - bool limited) +create_reply_message (void *ctx, + notmuch_config_t *config, + notmuch_message_t *message, + GMimeMessage *mime_message, + bool reply_all, + bool limited) { const char *subject, *from_addr = NULL; const char *in_reply_to, *orig_references, *references; @@ -533,6 +537,7 @@ create_reply_message(void *ctx, * otherwise. */ GMimeMessage *reply = g_mime_message_new (limited ? 0 : 1); + if (reply == NULL) { fprintf (stderr, "Out of memory\n"); return NULL; @@ -541,7 +546,7 @@ create_reply_message(void *ctx, in_reply_to = talloc_asprintf (ctx, "<%s>", notmuch_message_get_message_id (message)); - g_mime_object_set_header (GMIME_OBJECT (reply), "In-Reply-To", in_reply_to); + g_mime_object_set_header (GMIME_OBJECT (reply), "In-Reply-To", in_reply_to, NULL); orig_references = notmuch_message_get_header (message, "references"); if (orig_references && *orig_references) @@ -550,7 +555,7 @@ create_reply_message(void *ctx, else references = talloc_strdup (ctx, in_reply_to); - g_mime_object_set_header (GMIME_OBJECT (reply), "References", references); + g_mime_object_set_header (GMIME_OBJECT (reply), "References", references, NULL); from_addr = add_recipients_from_message (reply, config, mime_message, reply_all); @@ -589,13 +594,13 @@ create_reply_message(void *ctx, from_addr = talloc_asprintf (ctx, "%s <%s>", notmuch_config_get_user_name (config), from_addr); - g_mime_object_set_header (GMIME_OBJECT (reply), "From", from_addr); + g_mime_object_set_header (GMIME_OBJECT (reply), "From", from_addr, NULL); - subject = notmuch_message_get_header (message, "subject"); + subject = g_mime_message_get_subject (mime_message); if (subject) { if (strncasecmp (subject, "Re:", 3)) subject = talloc_asprintf (ctx, "Re: %s", subject); - g_mime_message_set_subject (reply, subject); + g_mime_message_set_subject (reply, subject, NULL); } return reply; @@ -608,11 +613,12 @@ enum { FORMAT_HEADERS_ONLY, }; -static int do_reply(notmuch_config_t *config, - notmuch_query_t *query, - notmuch_show_params_t *params, - int format, - bool reply_all) +static int +do_reply (notmuch_config_t *config, + notmuch_query_t *query, + notmuch_show_params_t *params, + int format, + bool reply_all) { GMimeMessage *reply; mime_node_t *node; @@ -645,8 +651,7 @@ static int do_reply(notmuch_config_t *config, for (; notmuch_messages_valid (messages); - notmuch_messages_move_to_next (messages)) - { + notmuch_messages_move_to_next (messages)) { message = notmuch_messages_get (messages); if (mime_node_open (config, message, ¶ms->crypto, &node)) @@ -655,7 +660,7 @@ static int do_reply(notmuch_config_t *config, reply = create_reply_message (config, config, message, GMIME_MESSAGE (node->part), reply_all, format == FORMAT_HEADERS_ONLY); - if (!reply) + if (! reply) return 1; if (format == FORMAT_JSON || format == FORMAT_SEXP) { @@ -663,7 +668,9 @@ static int do_reply(notmuch_config_t *config, /* The headers of the reply message we've created */ sp->map_key (sp, "reply-headers"); - format_headers_sprinter (sp, reply, true); + /* FIXME: send msg_crypto here to avoid killing the + * subject line on reply to encrypted messages! */ + format_headers_sprinter (sp, reply, true, NULL); /* Start the original */ sp->map_key (sp, "original"); @@ -679,7 +686,7 @@ static int do_reply(notmuch_config_t *config, format_part_reply (stream_stdout, node); } g_mime_stream_flush (stream_stdout); - g_object_unref(stream_stdout); + g_object_unref (stream_stdout); } g_object_unref (G_OBJECT (reply)); @@ -700,23 +707,29 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[]) int opt_index; notmuch_show_params_t params = { .part = -1, + .crypto = { .decrypt = NOTMUCH_DECRYPT_AUTO }, }; int format = FORMAT_DEFAULT; int reply_all = true; notmuch_opt_desc_t options[] = { { .opt_keyword = &format, .name = "format", .keywords = - (notmuch_keyword_t []){ { "default", FORMAT_DEFAULT }, - { "json", FORMAT_JSON }, - { "sexp", FORMAT_SEXP }, - { "headers-only", FORMAT_HEADERS_ONLY }, - { 0, 0 } } }, + (notmuch_keyword_t []){ { "default", FORMAT_DEFAULT }, + { "json", FORMAT_JSON }, + { "sexp", FORMAT_SEXP }, + { "headers-only", FORMAT_HEADERS_ONLY }, + { 0, 0 } } }, { .opt_int = ¬much_format_version, .name = "format-version" }, { .opt_keyword = &reply_all, .name = "reply-to", .keywords = - (notmuch_keyword_t []){ { "all", true }, - { "sender", false }, - { 0, 0 } } }, - { .opt_bool = ¶ms.crypto.decrypt, .name = "decrypt" }, + (notmuch_keyword_t []){ { "all", true }, + { "sender", false }, + { 0, 0 } } }, + { .opt_keyword = (int *) (¶ms.crypto.decrypt), .name = "decrypt", + .keyword_no_arg_value = "true", .keywords = + (notmuch_keyword_t []){ { "false", NOTMUCH_DECRYPT_FALSE }, + { "auto", NOTMUCH_DECRYPT_AUTO }, + { "true", NOTMUCH_DECRYPT_NOSTASH }, + { 0, 0 } } }, { .opt_inherit = notmuch_shared_options }, { } }; @@ -729,7 +742,7 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[]) notmuch_exit_if_unsupported_format (); - query_string = query_string_from_args (config, argc-opt_index, argv+opt_index); + query_string = query_string_from_args (config, argc - opt_index, argv + opt_index); if (query_string == NULL) { fprintf (stderr, "Out of memory\n"); return EXIT_FAILURE; @@ -740,10 +753,6 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[]) return EXIT_FAILURE; } -#if (GMIME_MAJOR_VERSION < 3) - params.crypto.gpgpath = notmuch_config_get_crypto_gpg_path (config); -#endif - if (notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much)) return EXIT_FAILURE;