aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--notmuch-client.h3
-rw-r--r--notmuch-show.c83
-rw-r--r--notmuch.14
-rw-r--r--notmuch.c4
-rwxr-xr-xtest/cat40
-rwxr-xr-xtest/notmuch-test2
6 files changed, 135 insertions, 1 deletions
diff --git a/notmuch-client.h b/notmuch-client.h
index d530578a..fdfb94ad 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -111,6 +111,9 @@ int
notmuch_search_tags_command (void *ctx, int argc, char *argv[]);
int
+notmuch_cat_command (void *ctx, int argc, char *argv[]);
+
+int
notmuch_part_command (void *ctx, int argc, char *argv[]);
int
diff --git a/notmuch-show.c b/notmuch-show.c
index ea465dec..f46e0c82 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -632,6 +632,89 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))
}
int
+notmuch_cat_command (void *ctx, unused (int argc), unused (char *argv[]))
+{
+ notmuch_config_t *config;
+ notmuch_database_t *notmuch;
+ notmuch_query_t *query;
+ notmuch_messages_t *messages;
+ notmuch_message_t *message;
+ char *query_string;
+ int i;
+ const char *filename;
+ FILE *file;
+ size_t size;
+ char buf[4096];
+
+ for (i = 0; i < argc && argv[i][0] == '-'; i++) {
+ fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
+ return 1;
+ }
+
+ config = notmuch_config_open (ctx, NULL, NULL);
+ if (config == NULL)
+ return 1;
+
+ query_string = query_string_from_args (ctx, argc, argv);
+ if (query_string == NULL) {
+ fprintf (stderr, "Out of memory\n");
+ return 1;
+ }
+
+ if (*query_string == '\0') {
+ fprintf (stderr, "Error: notmuch cat requires at least one search term.\n");
+ return 1;
+ }
+
+ notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
+ NOTMUCH_DATABASE_MODE_READ_ONLY);
+ if (notmuch == NULL)
+ return 1;
+
+ query = notmuch_query_create (notmuch, query_string);
+ if (query == NULL) {
+ fprintf (stderr, "Error: Out of memory\n");
+ return 1;
+ }
+
+ if (notmuch_query_count_messages (query) != 1) {
+ fprintf (stderr, "Error: search term did not match precisely one message.\n");
+ return 1;
+ }
+
+ messages = notmuch_query_search_messages (query);
+ message = notmuch_messages_get (messages);
+
+ if (message == NULL) {
+ fprintf (stderr, "Error: Cannot find matching message.\n");
+ return 1;
+ }
+
+ filename = notmuch_message_get_filename (message);
+ if (filename == NULL) {
+ fprintf (stderr, "Error: Cannot message filename.\n");
+ return 1;
+ }
+
+ file = fopen (filename, "r");
+ if (file == NULL) {
+ fprintf (stderr, "Error: Cannot open file %s: %s\n", filename, strerror (errno));
+ return 1;
+ }
+
+ while (!feof (file)) {
+ size = fread (buf, 1, sizeof (buf), file);
+ fwrite (buf, size, 1, stdout);
+ }
+
+ fclose (file);
+ notmuch_query_destroy (query);
+ notmuch_database_close (notmuch);
+
+ return 0;
+}
+
+int
notmuch_part_command (void *ctx, unused (int argc), unused (char *argv[]))
{
notmuch_config_t *config;
diff --git a/notmuch.1 b/notmuch.1
index e4eed60f..853b5eaf 100644
--- a/notmuch.1
+++ b/notmuch.1
@@ -300,6 +300,10 @@ See the
section below for details of the supported syntax for <search-terms>.
.RE
.TP
+.BR cat " <search-term>..."
+
+Output raw content of a single message matched by the search term.
+.TP
.BR count " <search-term>..."
Count messages matching the search terms.
diff --git a/notmuch.c b/notmuch.c
index 030e4942..0eba89a3 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -343,6 +343,10 @@ command_t commands[] = {
"\tcontain tags only from messages that match the search-term(s).\n"
"\n"
"\tIn both cases the list will be alphabetically sorted." },
+ { "cat", notmuch_cat_command,
+ "<search-terms>",
+ "Output raw content of a single message matched by the search term.",
+ "" },
{ "part", notmuch_part_command,
"--part=<num> <search-terms>",
"Output a single MIME part of a message.",
diff --git a/test/cat b/test/cat
new file mode 100755
index 00000000..c2cfedb8
--- /dev/null
+++ b/test/cat
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+test_description='notmuch cat'
+. ./test-lib.sh
+
+test_begin_subtest "Generate some messages"
+generate_message
+generate_message
+output=$(NOTMUCH_NEW)
+test_expect_equal "$output" "Added 2 new messages to the database."
+
+test_begin_subtest "Without arguments"
+output=$(notmuch cat 2>&1)
+test_expect_equal "$output" "Error: notmuch cat requires at least one search term."
+
+test_begin_subtest "Attempt to cat multiple messages"
+output=$(notmuch cat "*" 2>&1)
+test_expect_equal "$output" "Error: search term did not match precisely one message."
+
+test_begin_subtest "Cat a message"
+output=$(notmuch cat id:msg-001@notmuch-test-suite)
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+To: Notmuch Test Suite <test_suite@notmuchmail.org>
+Message-Id: <msg-001@notmuch-test-suite>
+Subject: Test message #1
+Date: Tue, 05 Jan 2001 15:43:57 -0000
+
+This is just a test message (#1)"
+
+test_begin_subtest "Cat another message"
+output=$(notmuch cat id:msg-002@notmuch-test-suite)
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+To: Notmuch Test Suite <test_suite@notmuchmail.org>
+Message-Id: <msg-002@notmuch-test-suite>
+Subject: Test message #2
+Date: Tue, 05 Jan 2001 15:43:57 -0000
+
+This is just a test message (#2)"
+
+test_done
diff --git a/test/notmuch-test b/test/notmuch-test
index 60c3ecbc..6b894090 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -16,7 +16,7 @@ fi
cd $(dirname "$0")
-TESTS="basic new search json thread-naming reply dump-restore uuencode thread-order author-order from-guessing long-id encoding emacs"
+TESTS="basic new search json thread-naming reply cat dump-restore uuencode thread-order author-order from-guessing long-id encoding emacs"
# Clean up any results from a previous run
rm -r test-results >/dev/null 2>/dev/null