#include "sprinter.h"
static void
-show_reply_headers (GMimeMessage *message)
+show_reply_headers (GMimeStream *stream, GMimeMessage *message)
{
- GMimeStream *stream_stdout = NULL;
-
- stream_stdout = g_mime_stream_file_new (stdout);
- if (stream_stdout) {
- g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE);
- /* Output RFC 2822 formatted (and RFC 2047 encoded) headers. */
- g_mime_object_write_to_stream (GMIME_OBJECT(message), stream_stdout);
- g_object_unref(stream_stdout);
+ /* 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");
}
}
static void
-format_part_reply (mime_node_t *node)
+format_part_reply (GMimeStream *stream, mime_node_t *node)
{
int i;
if (node->envelope_file) {
- printf ("On %s, %s wrote:\n",
- notmuch_message_get_header (node->envelope_file, "date"),
- notmuch_message_get_header (node->envelope_file, "from"));
+ g_mime_stream_printf (stream, "On %s, %s wrote:\n",
+ notmuch_message_get_header (node->envelope_file, "date"),
+ notmuch_message_get_header (node->envelope_file, "from"));
} else if (GMIME_IS_MESSAGE (node->part)) {
GMimeMessage *message = GMIME_MESSAGE (node->part);
- InternetAddressList *recipients;
- const char *recipients_string;
+ 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);
+ g_mime_stream_printf (stream, "> From: %s\n", g_mime_message_get_from_string (message));
+ recipients_string = g_mime_message_get_address_string (message, GMIME_ADDRESS_TYPE_TO);
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);
+ g_mime_stream_printf (stream, "> To: %s\n",
+ recipients_string);
+ g_free (recipients_string);
+ recipients_string = g_mime_message_get_address_string (message, GMIME_ADDRESS_TYPE_CC);
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));
- printf (">\n");
+ g_mime_stream_printf (stream, "> Cc: %s\n",
+ recipients_string);
+ g_free (recipients_string);
+ g_mime_stream_printf (stream, "> Subject: %s\n", g_mime_message_get_subject (message));
+ g_mime_stream_printf (stream, "> Date: %s\n", g_mime_message_get_date_string (node, message));
+ g_mime_stream_printf (stream, ">\n");
} else if (GMIME_IS_PART (node->part)) {
GMimeContentType *content_type = g_mime_object_get_content_type (node->part);
GMimeContentDisposition *disposition = g_mime_object_get_content_disposition (node->part);
/* 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")) {
- GMimeStream *stream_stdout = g_mime_stream_file_new (stdout);
- g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE);
- show_text_part_content (node->part, stream_stdout, NOTMUCH_SHOW_TEXT_PART_REPLY);
- g_object_unref(stream_stdout);
+ 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));
- printf ("Attachment: %s (%s)\n", filename,
- g_mime_content_type_to_string (content_type));
+ g_mime_stream_printf (stream, "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));
+ g_mime_stream_printf (stream, "Non-text part: %s\n",
+ g_mime_content_type_to_string (content_type));
}
}
for (i = 0; i < node->nchildren; i++)
- format_part_reply (mime_node_child (node, i));
+ format_part_reply (stream, mime_node_child (node, i));
}
typedef enum {
static InternetAddressList *get_sender(GMimeMessage *message)
{
- const char *reply_to;
-
- reply_to = g_mime_message_get_reply_to (message);
- if (reply_to && *reply_to) {
- InternetAddressList *reply_to_list;
+ 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
* to the list. Note that the address in the Reply-To header
* will always appear in the reply if reply_all is true.
*/
- reply_to_list = internet_address_list_parse_string (reply_to);
if (! reply_to_header_is_redundant (message, reply_to_list))
return reply_to_list;
- g_object_unref (G_OBJECT (reply_to_list));
+ g_mime_2_6_unref (G_OBJECT (reply_to_list));
}
- return internet_address_list_parse_string (
- g_mime_message_get_sender (message));
+ return g_mime_message_get_from (message);
}
static InternetAddressList *get_to(GMimeMessage *message)
{
- return g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_TO);
+ return g_mime_message_get_addresses (message, GMIME_ADDRESS_TYPE_TO);
}
static InternetAddressList *get_cc(GMimeMessage *message)
{
- return g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_CC);
+ return g_mime_message_get_addresses (message, GMIME_ADDRESS_TYPE_CC);
}
static InternetAddressList *get_bcc(GMimeMessage *message)
{
- return g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_BCC);
+ return g_mime_message_get_addresses (message, GMIME_ADDRESS_TYPE_BCC);
}
/* Augment the recipients of 'reply' from the "Reply-to:", "From:",
GMimeMessage *message,
notmuch_bool_t 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;
} reply_to_map[] = {
- { get_sender, GMIME_RECIPIENT_TYPE_TO },
- { get_to, GMIME_RECIPIENT_TYPE_TO },
- { get_cc, GMIME_RECIPIENT_TYPE_CC },
- { get_bcc, GMIME_RECIPIENT_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;
return 1;
if (count != 1) {
- fprintf (stderr, "Error: search term did not match precisely one message (matched %d messages).\n", count);
+ fprintf (stderr, "Error: search term did not match precisely one message (matched %u messages).\n", count);
return 1;
}
/* Start the original */
sp->map_key (sp, "original");
- format_part_sprinter (config, sp, node, TRUE, TRUE, FALSE);
+ format_part_sprinter (config, sp, node, TRUE, FALSE);
/* End */
sp->end (sp);
} else {
- show_reply_headers (reply);
- if (format == FORMAT_DEFAULT)
- format_part_reply (node);
+ GMimeStream *stream_stdout = stream_stdout = g_mime_stream_stdout_new ();
+ if (stream_stdout) {
+ show_reply_headers (stream_stdout, reply);
+ if (format == FORMAT_DEFAULT)
+ format_part_reply (stream_stdout, node);
+ }
+ g_mime_stream_flush (stream_stdout);
+ g_object_unref(stream_stdout);
}
g_object_unref (G_OBJECT (reply));
int reply_all = TRUE;
notmuch_opt_desc_t options[] = {
- { NOTMUCH_OPT_KEYWORD, &format, "format", 'f',
+ { .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_OPT_INT, ¬much_format_version, "format-version", 0, 0 },
- { NOTMUCH_OPT_KEYWORD, &reply_all, "reply-to", 'r',
+ { .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 } } },
- { NOTMUCH_OPT_BOOLEAN, ¶ms.crypto.decrypt, "decrypt", 'd', 0 },
- { NOTMUCH_OPT_INHERIT, (void *) ¬much_shared_options, NULL, 0, 0 },
- { 0, 0, 0, 0, 0 }
+ { .opt_bool = ¶ms.crypto.decrypt, .name = "decrypt" },
+ { .opt_inherit = notmuch_shared_options },
+ { }
};
opt_index = parse_arguments (argc, argv, options, 1);
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))