static void
format_headers_message_part_text (GMimeMessage *message);
-static void
+static notmuch_status_t
format_part_text (const void *ctx, mime_node_t *node,
int indent, const notmuch_show_params_t *params);
.message_set_end = ""
};
-static void
+static notmuch_status_t
format_part_json_entry (const void *ctx, mime_node_t *node,
int indent, const notmuch_show_params_t *params);
.message_set_end = "]"
};
-static void
-format_message_mbox (const void *ctx,
- notmuch_message_t *message,
- unused (int indent));
+static notmuch_status_t
+format_part_mbox (const void *ctx, mime_node_t *node,
+ int indent, const notmuch_show_params_t *params);
static const notmuch_show_format_t format_mbox = {
- "", NULL,
- "", format_message_mbox,
- "", NULL, NULL, "",
- "",
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- "",
- "",
- "", "",
- ""
+ .message_set_start = "",
+ .part = format_part_mbox,
+ .message_set_sep = "",
+ .message_set_end = ""
};
static void
date = notmuch_message_get_date (message);
relative_date = notmuch_time_relative_date (ctx, date);
- printf ("\"id\": %s, \"match\": %s, \"filename\": %s, \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [",
+ printf ("\"id\": %s, \"match\": %s, \"excluded\": %s, \"filename\": %s, \"timestamp\": %ld, \"date_relative\": \"%s\", \"tags\": [",
json_quote_str (ctx_quote, notmuch_message_get_message_id (message)),
notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? "true" : "false",
+ notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? "true" : "false",
json_quote_str (ctx_quote, notmuch_message_get_filename (message)),
date, relative_date);
return 0;
}
-/* Print a message in "mboxrd" format as documented, for example,
- * here:
- *
- * http://qmail.org/qmail-manual-html/man5/mbox.html
- */
-static void
-format_message_mbox (const void *ctx,
- notmuch_message_t *message,
- unused (int indent))
-{
- const char *filename;
- FILE *file;
- const char *from;
-
- time_t date;
- struct tm date_gmtime;
- char date_asctime[26];
-
- char *line = NULL;
- size_t line_size;
- ssize_t line_len;
-
- filename = notmuch_message_get_filename (message);
- file = fopen (filename, "r");
- if (file == NULL) {
- fprintf (stderr, "Failed to open %s: %s\n",
- filename, strerror (errno));
- return;
- }
-
- from = notmuch_message_get_header (message, "from");
- from = _extract_email_address (ctx, from);
-
- date = notmuch_message_get_date (message);
- gmtime_r (&date, &date_gmtime);
- asctime_r (&date_gmtime, date_asctime);
-
- printf ("From %s %s", from, date_asctime);
-
- while ((line_len = getline (&line, &line_size, file)) != -1 ) {
- if (_is_from_line (line))
- putchar ('>');
- printf ("%s", line);
- }
-
- printf ("\n");
-
- fclose (file);
-}
-
static void
format_headers_message_part_text (GMimeMessage *message)
{
}
#endif
-static void
-format_part_content_raw (GMimeObject *part)
-{
- if (! GMIME_IS_PART (part))
- return;
-
- GMimeStream *stream_stdout;
- GMimeStream *stream_filter = NULL;
- GMimeDataWrapper *wrapper;
-
- stream_stdout = g_mime_stream_file_new (stdout);
- g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE);
-
- stream_filter = g_mime_stream_filter_new (stream_stdout);
-
- 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 void
+static notmuch_status_t
format_part_text (const void *ctx, mime_node_t *node,
int indent, const notmuch_show_params_t *params)
{
notmuch_message_t *message = node->envelope_file;
part_type = "message";
- printf ("\f%s{ id:%s depth:%d match:%d filename:%s\n",
+ printf ("\f%s{ id:%s depth:%d match:%d excluded:%d filename:%s\n",
part_type,
notmuch_message_get_message_id (message),
indent,
- notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH),
+ notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? 1 : 0,
+ notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED) ? 1 : 0,
notmuch_message_get_filename (message));
} else {
GMimeContentDisposition *disposition = g_mime_object_get_content_disposition (meta);
printf ("\fbody}\n");
printf ("\f%s}\n", part_type);
+
+ return NOTMUCH_STATUS_SUCCESS;
}
static void
printf ("%s}", terminator);
}
-static void
+static notmuch_status_t
format_part_json_entry (const void *ctx, mime_node_t *node, unused (int indent),
unused (const notmuch_show_params_t *params))
{
format_part_json (ctx, node, TRUE);
+
+ return NOTMUCH_STATUS_SUCCESS;
+}
+
+/* Print a message in "mboxrd" format as documented, for example,
+ * here:
+ *
+ * http://qmail.org/qmail-manual-html/man5/mbox.html
+ */
+static notmuch_status_t
+format_part_mbox (const void *ctx, mime_node_t *node, unused (int indent),
+ unused (const notmuch_show_params_t *params))
+{
+ notmuch_message_t *message = node->envelope_file;
+
+ const char *filename;
+ FILE *file;
+ const char *from;
+
+ time_t date;
+ struct tm date_gmtime;
+ char date_asctime[26];
+
+ char *line = NULL;
+ size_t line_size;
+ ssize_t line_len;
+
+ if (!message)
+ INTERNAL_ERROR ("format_part_mbox requires a root part");
+
+ filename = notmuch_message_get_filename (message);
+ file = fopen (filename, "r");
+ if (file == NULL) {
+ fprintf (stderr, "Failed to open %s: %s\n",
+ filename, strerror (errno));
+ return NOTMUCH_STATUS_FILE_ERROR;
+ }
+
+ from = notmuch_message_get_header (message, "from");
+ from = _extract_email_address (ctx, from);
+
+ date = notmuch_message_get_date (message);
+ gmtime_r (&date, &date_gmtime);
+ asctime_r (&date_gmtime, date_asctime);
+
+ printf ("From %s %s", from, date_asctime);
+
+ while ((line_len = getline (&line, &line_size, file)) != -1 ) {
+ if (_is_from_line (line))
+ putchar ('>');
+ printf ("%s", line);
+ }
+
+ printf ("\n");
+
+ fclose (file);
+
+ return NOTMUCH_STATUS_SUCCESS;
}
static void
+format_part_content_raw (GMimeObject *part)
+{
+ if (! GMIME_IS_PART (part))
+ return;
+
+ GMimeStream *stream_stdout;
+ GMimeStream *stream_filter = NULL;
+ GMimeDataWrapper *wrapper;
+
+ stream_stdout = g_mime_stream_file_new (stdout);
+ g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE);
+
+ stream_filter = g_mime_stream_filter_new (stream_stdout);
+
+ 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 notmuch_status_t
show_message (void *ctx,
const notmuch_show_format_t *format,
notmuch_message_t *message,
if (format->part) {
void *local = talloc_new (ctx);
mime_node_t *root, *part;
-
- if (mime_node_open (local, message, params->cryptoctx, params->decrypt,
- &root) == NOTMUCH_STATUS_SUCCESS &&
- (part = mime_node_seek_dfs (root, (params->part < 0 ?
- 0 : params->part))))
- format->part (local, part, indent, params);
+ notmuch_status_t status;
+
+ status = mime_node_open (local, message, params->cryptoctx,
+ params->decrypt, &root);
+ if (status)
+ goto DONE;
+ part = mime_node_seek_dfs (root, (params->part < 0 ? 0 : params->part));
+ if (part)
+ status = format->part (local, part, indent, params);
+ DONE:
talloc_free (local);
- return;
+ return status;
}
if (params->part <= 0) {
fputs (format->message_end, stdout);
}
+
+ return NOTMUCH_STATUS_SUCCESS;
}
-static void
+static notmuch_status_t
show_messages (void *ctx,
const notmuch_show_format_t *format,
notmuch_messages_t *messages,
notmuch_bool_t match;
int first_set = 1;
int next_indent;
+ notmuch_status_t status, res = NOTMUCH_STATUS_SUCCESS;
fputs (format->message_set_start, stdout);
next_indent = indent;
if (match || params->entire_thread) {
- show_message (ctx, format, message, indent, params);
+ status = show_message (ctx, format, message, indent, params);
+ if (status && !res)
+ res = status;
next_indent = indent + 1;
- fputs (format->message_set_sep, stdout);
+ if (!status)
+ fputs (format->message_set_sep, stdout);
}
- show_messages (ctx,
- format,
- notmuch_message_get_replies (message),
- next_indent,
- params);
+ status = show_messages (ctx,
+ format,
+ notmuch_message_get_replies (message),
+ next_indent,
+ params);
+ if (status && !res)
+ res = status;
notmuch_message_destroy (message);
}
fputs (format->message_set_end, stdout);
+
+ return res;
}
/* Formatted output of single message */
fclose (file);
+ return 0;
+
} else {
- show_message (ctx, format, message, 0, params);
+ return show_message (ctx, format, message, 0, params) != NOTMUCH_STATUS_SUCCESS;
}
-
- return 0;
}
/* Formatted output of threads */
notmuch_thread_t *thread;
notmuch_messages_t *messages;
int first_toplevel = 1;
+ notmuch_status_t status, res = NOTMUCH_STATUS_SUCCESS;
fputs (format->message_set_start, stdout);
fputs (format->message_set_sep, stdout);
first_toplevel = 0;
- show_messages (ctx, format, messages, 0, params);
+ status = show_messages (ctx, format, messages, 0, params);
+ if (status && !res)
+ res = status;
notmuch_thread_destroy (thread);
fputs (format->message_set_end, stdout);
- return 0;
+ return res != NOTMUCH_STATUS_SUCCESS;
}
enum {
notmuch_show_params_t params = { .part = -1 };
int format_sel = NOTMUCH_FORMAT_NOT_SPECIFIED;
notmuch_bool_t verify = FALSE;
+ notmuch_bool_t no_exclude = FALSE;
notmuch_opt_desc_t options[] = {
{ NOTMUCH_OPT_KEYWORD, &format_sel, "format", 'f',
{ NOTMUCH_OPT_BOOLEAN, ¶ms.entire_thread, "entire-thread", 't', 0 },
{ NOTMUCH_OPT_BOOLEAN, ¶ms.decrypt, "decrypt", 'd', 0 },
{ NOTMUCH_OPT_BOOLEAN, &verify, "verify", 'v', 0 },
+ { NOTMUCH_OPT_BOOLEAN, &no_exclude, "no-exclude", 'n', 0 },
{ 0, 0, 0, 0, 0 }
};
fprintf (stderr, "Error: specifying parts is incompatible with mbox output format.\n");
return 1;
}
+
format = &format_mbox;
break;
case NOTMUCH_FORMAT_RAW:
return 1;
}
+ /* if format=mbox then we can not output excluded messages as
+ * there is no way to make the exclude flag available */
+ if (format_sel == NOTMUCH_FORMAT_MBOX)
+ notmuch_query_set_omit_excluded_messages (query, TRUE);
+
+ /* If a single message is requested we do not use search_excludes. */
if (params.part >= 0)
ret = do_show_single (ctx, query, format, ¶ms);
- else
+ else {
+ if (!no_exclude) {
+ const char **search_exclude_tags;
+ size_t search_exclude_tags_length;
+ unsigned int i;
+
+ search_exclude_tags = notmuch_config_get_search_exclude_tags
+ (config, &search_exclude_tags_length);
+ for (i = 0; i < search_exclude_tags_length; i++)
+ notmuch_query_add_tag_exclude (query, search_exclude_tags[i]);
+ }
ret = do_show (ctx, query, format, ¶ms);
+ }
+
notmuch_query_destroy (query);
notmuch_database_close (notmuch);