]> git.notmuchmail.org Git - notmuch/blobdiff - notmuch-show.c
new: Defer updating directory mtimes until the end.
[notmuch] / notmuch-show.c
index b9a41cc653e4bab6f277e85d7d9d173a33711b7f..912999e1a65e645b7b893ac49d1df55ad197d51c 100644 (file)
@@ -28,6 +28,9 @@ static void
 format_headers_text (const void *ctx,
                     notmuch_message_t *message);
 
+static void
+format_headers_message_part_text (GMimeMessage *message);
+
 static void
 format_part_start_text (GMimeObject *part,
                        int *part_count);
@@ -41,7 +44,7 @@ format_part_end_text (GMimeObject *part);
 static const notmuch_show_format_t format_text = {
     "",
        "\fmessage{ ", format_message_text,
-           "\fheader{\n", format_headers_text, "\fheader}\n",
+           "\fheader{\n", format_headers_text, format_headers_message_part_text, "\fheader}\n",
            "\fbody{\n",
                format_part_start_text,
                NULL,
@@ -62,6 +65,9 @@ static void
 format_headers_json (const void *ctx,
                     notmuch_message_t *message);
 
+static void
+format_headers_message_part_json (GMimeMessage *message);
+
 static void
 format_part_start_json (unused (GMimeObject *part),
                        int *part_count);
@@ -81,7 +87,7 @@ format_part_end_json (GMimeObject *part);
 static const notmuch_show_format_t format_json = {
     "[",
        "{", format_message_json,
-           ", \"headers\": {", format_headers_json, "}",
+           "\"headers\": {", format_headers_json, format_headers_message_part_json, "}",
            ", \"body\": [",
                format_part_start_json,
                format_part_encstatus_json,
@@ -102,7 +108,7 @@ format_message_mbox (const void *ctx,
 static const notmuch_show_format_t format_mbox = {
     "",
         "", format_message_mbox,
-            "", NULL, "",
+            "", NULL, NULL, "",
             "",
                 NULL,
                 NULL,
@@ -121,7 +127,7 @@ format_part_content_raw (GMimeObject *part);
 static const notmuch_show_format_t format_raw = {
     "",
        "", NULL,
-           "", NULL, "",
+           "", NULL, format_headers_message_part_text, "\n",
             "",
                 NULL,
                 NULL,
@@ -216,7 +222,7 @@ format_message_json (const void *ctx, notmuch_message_t *message, unused (int in
                json_quote_str (ctx_quote, notmuch_tags_get (tags)));
          first = 0;
     }
-    printf("]");
+    printf("]");
     talloc_free (ctx_quote);
 }
 
@@ -326,6 +332,7 @@ format_message_mbox (const void *ctx,
     fclose (file);
 }
 
+
 static void
 format_headers_text (const void *ctx, notmuch_message_t *message)
 {
@@ -345,6 +352,27 @@ format_headers_text (const void *ctx, notmuch_message_t *message)
     }
 }
 
+static void
+format_headers_message_part_text (GMimeMessage *message)
+{
+    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));
+}
+
 static void
 format_headers_json (const void *ctx, notmuch_message_t *message)
 {
@@ -374,6 +402,40 @@ format_headers_json (const void *ctx, notmuch_message_t *message)
     talloc_free (ctx_quote);
 }
 
+static void
+format_headers_message_part_json (GMimeMessage *message)
+{
+    void *ctx = talloc_new (NULL);
+    void *ctx_quote = talloc_new (ctx);
+    InternetAddressList *recipients;
+    const char *recipients_string;
+
+    printf ("%s: %s",
+           json_quote_str (ctx_quote, "From"),
+           json_quote_str (ctx_quote, 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 (", %s: %s",
+               json_quote_str (ctx_quote, "To"),
+               json_quote_str (ctx_quote, 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 (", %s: %s",
+               json_quote_str (ctx_quote, "Cc"),
+               json_quote_str (ctx_quote, recipients_string));
+    printf (", %s: %s",
+           json_quote_str (ctx_quote, "Subject"),
+           json_quote_str (ctx_quote, g_mime_message_get_subject (message)));
+    printf (", %s: %s",
+           json_quote_str (ctx_quote, "Date"),
+           json_quote_str (ctx_quote, g_mime_message_get_date_as_string (message)));
+
+    talloc_free (ctx_quote);
+    talloc_free (ctx);
+}
+
 /* Write a MIME text part out to the given stream.
  *
  * Both line-ending conversion (CRLF->LF) and charset conversion ( ->
@@ -420,7 +482,7 @@ show_text_part_content (GMimeObject *part, GMimeStream *stream_out)
 }
 
 static const char*
-signerstatustostring (GMimeSignerStatus x)
+signer_status_to_string (GMimeSignerStatus x)
 {
     switch (x) {
     case GMIME_SIGNER_STATUS_NONE:
@@ -454,23 +516,25 @@ format_part_start_text (GMimeObject *part, int *part_count)
 static void
 format_part_content_text (GMimeObject *part)
 {
-    GMimeContentDisposition *disposition = g_mime_object_get_content_disposition (part);
+    const char *cid = g_mime_object_get_content_id (part);
     GMimeContentType *content_type = g_mime_object_get_content_type (GMIME_OBJECT (part));
-    GMimeStream *stream_stdout = g_mime_stream_file_new (stdout);
 
-    printf (", Content-type: %s\n", g_mime_content_type_to_string (content_type));
-
-    if (disposition &&
-       strcmp (disposition->disposition, GMIME_DISPOSITION_ATTACHMENT) == 0)
+    if (GMIME_IS_PART (part))
     {
        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));
+       if (filename)
+           printf (", Filename: %s", filename);
     }
 
+    if (cid)
+       printf (", Content-id: %s", cid);
+
+    printf (", Content-type: %s\n", g_mime_content_type_to_string (content_type));
+
     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 (part, stream_stdout);
        g_object_unref(stream_stdout);
@@ -546,7 +610,9 @@ format_part_sigstatus_json (const GMimeSignatureValidity* validity)
        printf ("{");
 
        /* status */
-       printf ("\"status\": %s", json_quote_str (ctx_quote, signerstatustostring(signer->status)));
+       printf ("\"status\": %s",
+               json_quote_str (ctx_quote,
+                               signer_status_to_string (signer->status)));
 
        if (signer->status == GMIME_SIGNER_STATUS_GOOD)
        {
@@ -589,7 +655,6 @@ format_part_content_json (GMimeObject *part)
     GMimeStream *stream_memory = g_mime_stream_mem_new ();
     const char *cid = g_mime_object_get_content_id (part);
     void *ctx = talloc_new (NULL);
-    GMimeContentDisposition *disposition = g_mime_object_get_content_disposition (part);
     GByteArray *part_content;
 
     printf (", \"content-type\": %s",
@@ -598,12 +663,11 @@ format_part_content_json (GMimeObject *part)
     if (cid != NULL)
            printf(", \"content-id\": %s", json_quote_str (ctx, cid));
 
-    if (disposition &&
-       strcmp (disposition->disposition, GMIME_DISPOSITION_ATTACHMENT) == 0)
+    if (GMIME_IS_PART (part))
     {
        const char *filename = g_mime_part_get_filename (GMIME_PART (part));
-
-       printf (", \"filename\": %s", json_quote_str (ctx, filename));
+       if (filename)
+           printf (", \"filename\": %s", json_quote_str (ctx, filename));
     }
 
     if (g_mime_content_type_is_type (content_type, "text", "*") &&
@@ -614,11 +678,14 @@ format_part_content_json (GMimeObject *part)
 
        printf (", \"content\": %s", json_quote_chararray (ctx, (char *) part_content->data, part_content->len));
     }
-    else if (g_mime_content_type_is_type (content_type, "multipart", "*") ||
-            g_mime_content_type_is_type (content_type, "message", "rfc822"))
+    else if (g_mime_content_type_is_type (content_type, "multipart", "*"))
     {
        printf (", \"content\": [");
     }
+    else if (g_mime_content_type_is_type (content_type, "message", "rfc822"))
+    {
+       printf (", \"content\": [{");
+    }
 
     talloc_free (ctx);
     if (stream_memory)
@@ -628,13 +695,12 @@ format_part_content_json (GMimeObject *part)
 static void
 format_part_end_json (GMimeObject *part)
 {
-    GMimeContentType *content_type;
-
-    content_type = g_mime_object_get_content_type (GMIME_OBJECT (part));
+    GMimeContentType *content_type = g_mime_object_get_content_type (GMIME_OBJECT (part));
 
-    if (g_mime_content_type_is_type (content_type, "multipart", "*") ||
-       g_mime_content_type_is_type (content_type, "message", "rfc822"))
+    if (g_mime_content_type_is_type (content_type, "multipart", "*"))
        printf ("]");
+    else if (g_mime_content_type_is_type (content_type, "message", "rfc822"))
+       printf ("}]");
 
     printf ("}");
 }
@@ -642,6 +708,9 @@ format_part_end_json (GMimeObject *part)
 static void
 format_part_content_raw (GMimeObject *part)
 {
+    if (! GMIME_IS_PART (part))
+       return;
+
     GMimeStream *stream_stdout;
     GMimeStream *stream_filter = NULL;
     GMimeDataWrapper *wrapper;
@@ -897,7 +966,7 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
        } else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) ||
                   (STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {
            if (params.cryptoctx == NULL) {
-               GMimeSession* session = g_object_new(notmuch_gmime_session_get_type(), 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