/* Any changes to the JSON or S-Expression format should be
* reflected in the file devel/schemata. */
- InternetAddressList *recipients;
char *recipients_string;
const char *reply_to_string;
- char *date_string;
+ void *local = talloc_new (sp);
sp->begin_map (sp);
sp->string (sp, g_mime_message_get_subject (message));
sp->map_key (sp, "From");
- sp->string (sp, g_mime_message_get_sender (message));
+ sp->string (sp, g_mime_message_get_from_string (message));
- recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_TO);
- recipients_string = internet_address_list_to_string (recipients, 0);
+ recipients_string = g_mime_message_get_address_string (message, GMIME_ADDRESS_TYPE_TO);
if (recipients_string) {
sp->map_key (sp, "To");
sp->string (sp, recipients_string);
g_free (recipients_string);
}
- recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_CC);
- recipients_string = internet_address_list_to_string (recipients, 0);
+ recipients_string = g_mime_message_get_address_string (message, GMIME_ADDRESS_TYPE_CC);
if (recipients_string) {
sp->map_key (sp, "Cc");
sp->string (sp, recipients_string);
g_free (recipients_string);
}
- recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_BCC);
- recipients_string = internet_address_list_to_string (recipients, 0);
+ recipients_string = g_mime_message_get_address_string (message, GMIME_ADDRESS_TYPE_BCC);
if (recipients_string) {
sp->map_key (sp, "Bcc");
sp->string (sp, recipients_string);
g_free (recipients_string);
}
- reply_to_string = g_mime_message_get_reply_to (message);
+ reply_to_string = g_mime_message_get_reply_to_string (local, message);
if (reply_to_string) {
sp->map_key (sp, "Reply-To");
sp->string (sp, reply_to_string);
sp->string (sp, g_mime_object_get_header (GMIME_OBJECT (message), "References"));
} else {
sp->map_key (sp, "Date");
- date_string = g_mime_message_get_date_as_string (message);
- sp->string (sp, date_string);
- g_free (date_string);
+ sp->string (sp, g_mime_message_get_date_string (sp, message));
}
sp->end (sp);
+ talloc_free (local);
}
/* Write a MIME text part out to the given stream.
g_object_unref(stream_filter);
}
-/* Get signature status string (GMime 2.6) */
static const char*
-signature_status_to_string (GMimeSignatureStatus x)
+signature_status_to_string (GMimeSignatureStatus status)
{
- switch (x) {
- case GMIME_SIGNATURE_STATUS_GOOD:
- return "good";
- case GMIME_SIGNATURE_STATUS_BAD:
+ if (g_mime_signature_status_bad (status))
return "bad";
- case GMIME_SIGNATURE_STATUS_ERROR:
+
+ if (g_mime_signature_status_error (status))
return "error";
- }
+
+ if (g_mime_signature_status_good (status))
+ return "good";
+
return "unknown";
}
+/* Print signature flags */
+struct key_map_struct {
+ GMimeSignatureError bit;
+ const char * string;
+};
+
+static void
+do_format_signature_errors (sprinter_t *sp, struct key_map_struct *key_map,
+ unsigned int array_map_len, GMimeSignatureError errors) {
+ sp->map_key (sp, "errors");
+ sp->begin_map (sp);
+
+ for (unsigned int i = 0; i < array_map_len; i++) {
+ if (errors & key_map[i].bit) {
+ sp->map_key (sp, key_map[i].string);
+ sp->boolean (sp, TRUE);
+ }
+ }
+
+ sp->end (sp);
+}
+
+#if (GMIME_MAJOR_VERSION < 3)
+static void
+format_signature_errors (sprinter_t *sp, GMimeSignature *signature)
+{
+ GMimeSignatureError errors = g_mime_signature_get_errors (signature);
+
+ if (errors == GMIME_SIGNATURE_ERROR_NONE)
+ return;
+
+ struct key_map_struct key_map[] = {
+ { GMIME_SIGNATURE_ERROR_EXPSIG, "sig-expired" },
+ { GMIME_SIGNATURE_ERROR_NO_PUBKEY, "key-missing"},
+ { GMIME_SIGNATURE_ERROR_EXPKEYSIG, "key-expired"},
+ { GMIME_SIGNATURE_ERROR_REVKEYSIG, "key-revoked"},
+ { GMIME_SIGNATURE_ERROR_UNSUPP_ALGO, "alg-unsupported"},
+ };
+
+ do_format_signature_errors (sp, key_map, ARRAY_SIZE(key_map), errors);
+}
+#else
+static void
+format_signature_errors (sprinter_t *sp, GMimeSignature *signature)
+{
+ GMimeSignatureError errors = g_mime_signature_get_errors (signature);
+
+ if (!(errors & GMIME_SIGNATURE_STATUS_ERROR_MASK))
+ return;
+
+ struct key_map_struct key_map[] = {
+ { GMIME_SIGNATURE_STATUS_KEY_REVOKED, "key-revoked"},
+ { GMIME_SIGNATURE_STATUS_KEY_EXPIRED, "key-expired"},
+ { GMIME_SIGNATURE_STATUS_SIG_EXPIRED, "sig-expired" },
+ { GMIME_SIGNATURE_STATUS_KEY_MISSING, "key-missing"},
+ { GMIME_SIGNATURE_STATUS_CRL_MISSING, "crl-missing"},
+ { GMIME_SIGNATURE_STATUS_CRL_TOO_OLD, "crl-too-old"},
+ { GMIME_SIGNATURE_STATUS_BAD_POLICY, "bad-policy"},
+ { GMIME_SIGNATURE_STATUS_SYS_ERROR, "sys-error"},
+ { GMIME_SIGNATURE_STATUS_TOFU_CONFLICT, "tofu-conflict"},
+ };
+
+ do_format_signature_errors (sp, key_map, ARRAY_SIZE(key_map), errors);
+}
+#endif
+
/* Signature status sprinter (GMime 2.6) */
static void
format_part_sigstatus_sprinter (sprinter_t *sp, mime_node_t *node)
sp->string (sp, signature_status_to_string (status));
GMimeCertificate *certificate = g_mime_signature_get_certificate (signature);
- if (status == GMIME_SIGNATURE_STATUS_GOOD) {
+ if (g_mime_signature_status_good (status)) {
if (certificate) {
sp->map_key (sp, "fingerprint");
sp->string (sp, g_mime_certificate_get_fingerprint (certificate));
/* note that gmime is using the term "trust" here, which
* is WRONG. It's actually user id "validity". */
if (certificate) {
- const char *name = g_mime_certificate_get_name (certificate);
+ const char *name = g_mime_certificate_get_uid (certificate);
GMimeCertificateTrust trust = g_mime_certificate_get_trust (certificate);
if (name && (trust == GMIME_CERTIFICATE_TRUST_FULLY || trust == GMIME_CERTIFICATE_TRUST_ULTIMATE)) {
sp->map_key (sp, "userid");
}
}
} else if (certificate) {
- const char *key_id = g_mime_certificate_get_key_id (certificate);
+ const char *key_id = g_mime_certificate_get_fpr16 (certificate);
if (key_id) {
sp->map_key (sp, "keyid");
sp->string (sp, key_id);
}
}
- GMimeSignatureError errors = g_mime_signature_get_errors (signature);
- if (errors != GMIME_SIGNATURE_ERROR_NONE) {
- sp->map_key (sp, "errors");
- sp->integer (sp, errors);
+ if (notmuch_format_version <= 3) {
+ GMimeSignatureError errors = g_mime_signature_get_errors (signature);
+ if (g_mime_signature_status_error (errors)) {
+ sp->map_key (sp, "errors");
+ sp->integer (sp, errors);
+ }
+ } else {
+ format_signature_errors (sp, signature);
}
sp->end (sp);
if (GMIME_IS_MESSAGE (node->part)) {
GMimeMessage *message = GMIME_MESSAGE (node->part);
- InternetAddressList *recipients;
char *recipients_string;
char *date_string;
if (node->envelope_file)
g_mime_stream_printf (stream, "%s\n", _get_one_line_summary (ctx, node->envelope_file));
g_mime_stream_printf (stream, "Subject: %s\n", g_mime_message_get_subject (message));
- g_mime_stream_printf (stream, "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)
g_mime_stream_printf (stream, "To: %s\n", recipients_string);
g_free (recipients_string);
- recipients = g_mime_message_get_recipients (message, GMIME_RECIPIENT_TYPE_CC);
- recipients_string = internet_address_list_to_string (recipients, 0);
+ recipients_string = g_mime_message_get_address_string (message, GMIME_ADDRESS_TYPE_CC);
if (recipients_string)
g_mime_stream_printf (stream, "Cc: %s\n", recipients_string);
g_free (recipients_string);
- date_string = g_mime_message_get_date_as_string (message);
+ date_string = g_mime_message_get_date_string (node, message);
g_mime_stream_printf (stream, "Date: %s\n", date_string);
- g_free (date_string);
g_mime_stream_printf (stream, "\fheader}\n");
g_mime_stream_printf (stream, "\fbody{\n");
void
format_part_sprinter (const void *ctx, sprinter_t *sp, mime_node_t *node,
- notmuch_bool_t first, notmuch_bool_t output_body,
+ notmuch_bool_t output_body,
notmuch_bool_t include_html)
{
/* Any changes to the JSON or S-Expression format should be
if (output_body) {
sp->map_key (sp, "body");
sp->begin_list (sp);
- format_part_sprinter (ctx, sp, mime_node_child (node, 0), first, TRUE, include_html);
+ format_part_sprinter (ctx, sp, mime_node_child (node, 0), TRUE, include_html);
sp->end (sp);
}
sp->end (sp);
}
for (i = 0; i < node->nchildren; i++)
- format_part_sprinter (ctx, sp, mime_node_child (node, i), i == 0, TRUE, include_html);
+ format_part_sprinter (ctx, sp, mime_node_child (node, i), TRUE, include_html);
/* Close content structures */
for (i = 0; i < nclose; i++)
mime_node_t *node, unused (int indent),
const notmuch_show_params_t *params)
{
- format_part_sprinter (ctx, sp, node, TRUE, params->output_body, params->include_html);
+ format_part_sprinter (ctx, sp, node, params->output_body, params->include_html);
return NOTMUCH_STATUS_SUCCESS;
}
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;
}
[NOTMUCH_FORMAT_RAW] = &format_raw,
};
-enum {
- ENTIRE_THREAD_DEFAULT = -1,
- ENTIRE_THREAD_FALSE = FALSE,
- ENTIRE_THREAD_TRUE = TRUE,
-};
-
-/* The following is to allow future options to be added more easily */
-enum {
- EXCLUDE_TRUE,
- EXCLUDE_FALSE,
-};
-
int
notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
{
.output_body = TRUE,
};
int format = NOTMUCH_FORMAT_NOT_SPECIFIED;
- int exclude = EXCLUDE_TRUE;
- int entire_thread = ENTIRE_THREAD_DEFAULT;
+ int exclude = TRUE;
+
+ /* This value corresponds to neither true nor false being passed
+ * on the command line */
+ int entire_thread = -1;
notmuch_bool_t single_message;
notmuch_opt_desc_t options[] = {
{ "raw", NOTMUCH_FORMAT_RAW },
{ 0, 0 } } },
{ NOTMUCH_OPT_INT, ¬much_format_version, "format-version", 0, 0 },
- { NOTMUCH_OPT_KEYWORD, &exclude, "exclude", 'x',
- (notmuch_keyword_t []){ { "true", EXCLUDE_TRUE },
- { "false", EXCLUDE_FALSE },
- { 0, 0 } } },
- { NOTMUCH_OPT_KEYWORD, &entire_thread, "entire-thread", 't',
- (notmuch_keyword_t []){ { "true", ENTIRE_THREAD_TRUE },
- { "false", ENTIRE_THREAD_FALSE },
- { "", ENTIRE_THREAD_TRUE },
- { 0, 0 } } },
+ { NOTMUCH_OPT_BOOLEAN, &exclude, "exclude", 'x', 0 },
+ { NOTMUCH_OPT_BOOLEAN, &entire_thread, "entire-thread", 't', 0 },
{ NOTMUCH_OPT_INT, ¶ms.part, "part", 'p', 0 },
{ NOTMUCH_OPT_BOOLEAN, ¶ms.crypto.decrypt, "decrypt", 'd', 0 },
{ NOTMUCH_OPT_BOOLEAN, ¶ms.crypto.verify, "verify", 'v', 0 },
/* Default is entire-thread = FALSE except for format=json and
* format=sexp. */
- if (entire_thread == ENTIRE_THREAD_DEFAULT) {
+ if (entire_thread != FALSE && entire_thread != TRUE) {
if (format == NOTMUCH_FORMAT_JSON || format == NOTMUCH_FORMAT_SEXP)
params.entire_thread = TRUE;
else
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))
}
}
- if (exclude == EXCLUDE_FALSE) {
+ if (exclude == FALSE) {
notmuch_query_set_omit_excluded (query, FALSE);
params.omit_excluded = FALSE;
}