+static notmuch_status_t
+format_part_raw (unused (const void *ctx), unused (sprinter_t *sp),
+ mime_node_t *node, unused (int indent),
+ const notmuch_show_params_t *params)
+{
+ if (node->envelope_file) {
+ /* Special case the entire message to avoid MIME parsing. */
+ const char *filename;
+ GMimeStream *stream = NULL;
+ ssize_t ssize;
+ char buf[4096];
+ notmuch_status_t ret = NOTMUCH_STATUS_FILE_ERROR;
+
+ filename = notmuch_message_get_filename (node->envelope_file);
+ if (filename == NULL) {
+ fprintf (stderr, "Error: Cannot get message filename.\n");
+ goto DONE;
+ }
+
+ stream = g_mime_stream_gzfile_open (filename);
+ if (stream == NULL) {
+ fprintf (stderr, "Error: Cannot open file %s: %s\n", filename, strerror (errno));
+ goto DONE;
+ }
+
+ while (! g_mime_stream_eos (stream)) {
+ ssize = g_mime_stream_read (stream, buf, sizeof (buf));
+ if (ssize < 0) {
+ fprintf (stderr, "Error: Read failed from %s\n", filename);
+ goto DONE;
+ }
+
+ if (ssize > 0 && fwrite (buf, ssize, 1, stdout) != 1) {
+ fprintf (stderr, "Error: Write %ld chars to stdout failed\n", ssize);
+ goto DONE;
+ }
+ }
+
+ ret = NOTMUCH_STATUS_SUCCESS;
+
+ /* XXX This DONE is just for the special case of a node in a single file */
+ DONE:
+ if (stream)
+ g_object_unref (stream);
+
+ return ret;
+ }
+
+ GMimeStream *stream_filter = g_mime_stream_filter_new (params->out_stream);
+
+ if (GMIME_IS_PART (node->part)) {
+ /* For leaf parts, we emit only the transfer-decoded
+ * body. */
+ GMimeDataWrapper *wrapper;
+ wrapper = g_mime_part_get_content (GMIME_PART (node->part));
+
+ if (wrapper && stream_filter)
+ g_mime_data_wrapper_write_to_stream (wrapper, stream_filter);
+ } else {
+ /* Write out the whole part. For message parts (the root
+ * part and embedded message parts), this will be the
+ * message including its headers (but not the
+ * encapsulating part's headers). For multipart parts,
+ * this will include the headers. */
+ if (stream_filter)
+ g_mime_object_write_to_stream (node->part, NULL, stream_filter);