#include "gmime-filter-headers.h"
static void
-reply_part (GMimeObject *part,
- unused (int *part_count));
-
-static const notmuch_show_format_t format_reply = {
- NULL,
- NULL, NULL,
- NULL, NULL, NULL,
- NULL, reply_part, NULL, NULL, NULL,
- NULL, NULL,
- NULL
-};
+reply_headers_message_part (GMimeMessage *message);
static void
-reply_part_content (GMimeObject *part)
-{
- GMimeStream *stream_stdout = NULL, *stream_filter = NULL;
- GMimeDataWrapper *wrapper;
- const char *charset;
+reply_part_content (GMimeObject *part);
- 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 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)
}
static void
-reply_part (GMimeObject *part,
- unused (int *part_count))
+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));
+}
- 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));
+ }
}
}
* 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.
* 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)
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;
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);
}
}
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;
const char *subject, *from_addr = NULL;
const char *in_reply_to, *orig_references, *references;
const notmuch_show_format_t *format = &format_reply;
- notmuch_show_params_t params;
- params.part = -1;
for (messages = notmuch_query_search_messages (query);
notmuch_messages_valid (messages);
notmuch_message_get_header (message, "date"),
notmuch_message_get_header (message, "from"));
- show_message_body (notmuch_message_get_filename (message),
- format, ¶ms);
+ show_message_body (message, format, params);
notmuch_message_destroy (message);
}
/* 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;
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;
reply_format_func = notmuch_reply_format_default;
+ params.part = -1;
+ params.cryptoctx = NULL;
+
+ argc--; argv++; /* skip subcommand argument */
for (i = 0; i < argc && argv[i][0] == '-'; i++) {
if (strcmp (argv[i], "--") == 0) {
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
+ 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;
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;
}