From 00bfef8526a15a609420e3f9e1e3913015c4b51d Mon Sep 17 00:00:00 2001 From: Michal Sojka Date: Thu, 8 Apr 2010 16:32:48 +0200 Subject: [PATCH] Add 'cat' subcommand This command dumps raw message identified by filename to standard output. It uses mail store interface to get the message from the right place. notmuch.el was modified to use this command to access the raw message content (view/save attachments, view raw message and pipe message to command). With this patch, it is straightforward to use notmuch emacs interface remotely over SSH. To do this, it is sufficient to redefine notmuch-command variable to contain the name of a script containing: ssh user@host notmuch "$@" Signed-off-by: Michal Sojka --- NEWS | 3 +++ emacs/notmuch-show.el | 11 +++++--- notmuch-client.h | 3 +++ notmuch-show.c | 62 +++++++++++++++++++++++++++++++++++++++++++ notmuch.c | 4 +++ 5 files changed, 80 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index f29ac274..3bd21fac 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +A new subcommand 'cat' was added, which simplifies use of Emacs +interface with remote database (accessed over SSH). + Notmuch 0.1 (2010-04-05) ======================== This is the first release of the notmuch mail system. diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 6f5a55d4..45d49d1f 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -328,7 +328,11 @@ buffer." (defun notmuch-show-view-raw-message () "View the raw email of the current message." (interactive) - (view-file (notmuch-show-get-filename))) + (let ((filename (notmuch-show-get-filename))) + (let ((buf (get-buffer-create (concat "*notmuch-raw-" filename "*")))) + (switch-to-buffer buf) + (save-excursion + (call-process notmuch-command nil t nil "cat" filename))))) (defmacro with-current-notmuch-show-message (&rest body) "Evaluate body with current buffer set to the text of current message" @@ -336,7 +340,7 @@ buffer." (let ((filename (notmuch-show-get-filename))) (let ((buf (generate-new-buffer (concat "*notmuch-msg-" filename "*")))) (with-current-buffer buf - (insert-file-contents filename nil nil nil t) + (call-process notmuch-command nil t nil "cat" filename) ,@body) (kill-buffer buf))))) @@ -390,7 +394,8 @@ current email message as stdin. Anything printed by the command to stdout or stderr will appear in the *Messages* buffer." (interactive "sPipe message to command: ") (apply 'start-process-shell-command "notmuch-pipe-command" "*notmuch-pipe*" - (list command " < " (shell-quote-argument (notmuch-show-get-filename))))) + (list notmuch-command "cat" + (shell-quote-argument (notmuch-show-get-filename) " | " command)))) (defun notmuch-show-move-to-current-message-summary-line () "Move to the beginning of the one-line summary of the current message. diff --git a/notmuch-client.h b/notmuch-client.h index 728e448b..666e70db 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -110,6 +110,9 @@ notmuch_tag_command (void *ctx, int argc, char *argv[]); 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[]); diff --git a/notmuch-show.c b/notmuch-show.c index 66fd773c..dbab9a78 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -514,6 +514,68 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[])) return 0; } +int +notmuch_cat_command (void *ctx, unused (int argc), unused (char *argv[])) +{ + notmuch_config_t *config; + notmuch_database_t *notmuch; + notmuch_mailstore_t *mailstore; + int i; + FILE *file; + const char *filename; + size_t size; + char buf[4096]; + + for (i = 0; i < argc && argv[i][0] == '-'; i++) { +/* if (STRNCMP_LITERAL (argv[i], "--part=") == 0) { */ +/* part = atoi(argv[i] + sizeof ("--part=") - 1); */ +/* } else { */ + fprintf (stderr, "Unrecognized option: %s\n", argv[i]); +/* return 1; */ +/* } */ + } + + argc -= i; + argv += i; + + if (argc == 0) { + fprintf (stderr, "Error: No filename given\n"); + return 1; + } + filename = argv[0]; + + config = notmuch_config_open (ctx, NULL, NULL); + if (config == NULL) + return 1; + + mailstore = notmuch_config_get_mailstore (config); + + if (mailstore == NULL) { + fprintf (stderr, "Error: I have no mailstore\n"); + return 1; + } + + notmuch = notmuch_database_open (notmuch_config_get_database_path (config), + NOTMUCH_DATABASE_MODE_READ_ONLY, + mailstore); + + file = notmuch_mailstore_open_file(mailstore, filename); + if (file == NULL) { + fprintf (stderr, "Error: Cannot open %s in %s: %s\n", filename, + notmuch_mailstore_get_type (mailstore), strerror (errno)); + return 1; + } + while (!feof (file)) { + size = fread(buf, 1, sizeof(buf), file); + fwrite (buf, size, 1, stdout); + } + fclose (file); + + notmuch_database_close (notmuch); + + return 0; +} + int notmuch_part_command (void *ctx, unused (int argc), unused (char *argv[])) { diff --git a/notmuch.c b/notmuch.c index f5669fcd..bcebcdcb 100644 --- a/notmuch.c +++ b/notmuch.c @@ -294,6 +294,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, + "", + "Dump raw message identified by path to standard output.", + "" }, { "part", notmuch_part_command, "--part= ", "Output a single MIME part of a message.", -- 2.39.2