+ notmuch_filenames_destroy (filenames);
+ sp->end (sp);
+ } else {
+ sp->string (sp, notmuch_message_get_filename (message));
+ }
+
+ sp->map_key (sp, "timestamp");
+ date = notmuch_message_get_date (message);
+ sp->integer (sp, date);
+
+ sp->map_key (sp, "date_relative");
+ relative_date = notmuch_time_relative_date (local, date);
+ sp->string (sp, relative_date);
+
+ sp->map_key (sp, "tags");
+ sp->begin_list (sp);
+ for (tags = notmuch_message_get_tags (message);
+ notmuch_tags_valid (tags);
+ notmuch_tags_move_to_next (tags))
+ sp->string (sp, notmuch_tags_get (tags));
+ sp->end (sp);
+
+ talloc_free (local);
+}
+
+/* Extract just the email address from the contents of a From:
+ * header. */
+static const char *
+_extract_email_address (const void *ctx, const char *from)
+{
+ InternetAddressList *addresses;
+ InternetAddress *address;
+ InternetAddressMailbox *mailbox;
+ const char *email = "MAILER-DAEMON";
+
+ addresses = internet_address_list_parse_string (from);
+
+ /* Bail if there is no address here. */
+ if (addresses == NULL || internet_address_list_length (addresses) < 1)
+ goto DONE;
+
+ /* Otherwise, just use the first address. */
+ address = internet_address_list_get_address (addresses, 0);
+
+ /* The From header should never contain an address group rather
+ * than a mailbox. So bail if it does. */
+ if (! INTERNET_ADDRESS_IS_MAILBOX (address))
+ goto DONE;
+
+ mailbox = INTERNET_ADDRESS_MAILBOX (address);
+ email = internet_address_mailbox_get_addr (mailbox);
+ email = talloc_strdup (ctx, email);
+
+ DONE:
+ if (addresses)
+ g_object_unref (addresses);
+
+ return email;
+ }
+
+/* Return 1 if 'line' is an mbox From_ line---that is, a line
+ * beginning with zero or more '>' characters followed by the
+ * characters 'F', 'r', 'o', 'm', and space.
+ *
+ * Any characters at all may appear after that in the line.
+ */
+static int
+_is_from_line (const char *line)
+{
+ const char *s = line;
+
+ if (line == NULL)
+ return 0;
+
+ while (*s == '>')
+ s++;
+
+ if (STRNCMP_LITERAL (s, "From ") == 0)
+ return 1;
+ else
+ return 0;
+}
+
+void
+format_headers_sprinter (sprinter_t *sp, GMimeMessage *message,
+ notmuch_bool_t reply)
+{
+ /* 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;
+
+ sp->begin_map (sp);
+
+ sp->map_key (sp, "Subject");
+ sp->string (sp, g_mime_message_get_subject (message));
+
+ sp->map_key (sp, "From");
+ sp->string (sp, 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) {
+ 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);
+ 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);
+ if (recipients_string) {
+ sp->map_key (sp, "Bcc");
+ sp->string (sp, recipients_string);
+ g_free (recipients_string);