From 51037be7fb19515fb5fd18655be4fb995f551096 Mon Sep 17 00:00:00 2001 From: "Foivos S. Zakkak" Date: Fri, 10 Oct 2014 18:34:57 +0300 Subject: [PATCH] Fix #186 Part 3 This patch fixes the attachment extraction (open, save, temp) when using `mu4e`. `mu4e` used to not notify the mu-server about the mu4e-decryption-policy. As a result mu-server did not decrypt the attachments for extract, open, or temp. --- lib/mu-msg-part.c | 15 ++++++++++++++- mu/mu-cmd-server.c | 46 +++++++++++++++++++++++++++++++--------------- mu4e/mu4e-proc.el | 16 +++++++++------- mu4e/mu4e-view.el | 14 +++++++------- 4 files changed, 61 insertions(+), 30 deletions(-) diff --git a/lib/mu-msg-part.c b/lib/mu-msg-part.c index 7fe838de..1333d028 100644 --- a/lib/mu-msg-part.c +++ b/lib/mu-msg-part.c @@ -42,8 +42,13 @@ do_it_with_index (MuMsg *msg, MuMsgPart *part, DoData *ddata) if (ddata->mime_obj) return; - if (part->index == ddata->index) + if (part->index == ddata->index) { + /* Add a reference to this object, this way if it is + * encrypted it will not be garbage collected before + * we are done with it. */ + g_object_ref (part->data); ddata->mime_obj = (GMimeObject*)part->data; + } } static GMimeObject* @@ -648,6 +653,10 @@ save_object (GMimeObject *obj, MuMsgOptions opts, const char *fullpath, else rv = write_object_to_fd (obj, fd, err); + /* Unref it since it was referenced earlier by + * get_mime_object_at_index */ + g_object_unref (obj); + if (close (fd) != 0 && !err) { /* don't write on top of old err */ g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE, "could not close '%s': %s", @@ -681,6 +690,10 @@ mu_msg_part_get_path (MuMsg *msg, MuMsgOptions opts, fname = mime_part_get_filename (mobj, index, TRUE); filepath = g_build_path (G_DIR_SEPARATOR_S, targetdir ? targetdir : "", fname, NULL); + + /* Unref it since it was referenced earlier by + * get_mime_object_at_index */ + g_object_unref (mobj); g_free (fname); return filepath; diff --git a/mu/mu-cmd-server.c b/mu/mu-cmd-server.c index 881abf92..0209ef80 100644 --- a/mu/mu-cmd-server.c +++ b/mu/mu-cmd-server.c @@ -675,8 +675,8 @@ print_sexps (MuMsgIter *iter, unsigned maxnum) static MuError -save_part (MuMsg *msg, unsigned docid, - unsigned index, GHashTable *args, GError **err) +save_part (MuMsg *msg, unsigned docid, unsigned index, + MuMsgOptions opts, GHashTable *args, GError **err) { gboolean rv; const gchar *path; @@ -684,7 +684,7 @@ save_part (MuMsg *msg, unsigned docid, GET_STRING_OR_ERROR_RETURN (args, "path", &path, err); - rv = mu_msg_part_save (msg, MU_MSG_OPTION_OVERWRITE, + rv = mu_msg_part_save (msg, opts | MU_MSG_OPTION_OVERWRITE, path, index, err); if (!rv) { print_and_clear_g_error (err); @@ -701,17 +701,17 @@ save_part (MuMsg *msg, unsigned docid, static MuError -open_part (MuMsg *msg, unsigned docid, unsigned index, GError **err) +open_part (MuMsg *msg, unsigned docid, unsigned index, + MuMsgOptions opts, GError **err) { char *targetpath; gboolean rv; - targetpath = mu_msg_part_get_cache_path (msg,MU_MSG_OPTION_NONE, - index, err); + targetpath = mu_msg_part_get_cache_path (msg, opts, index, err); if (!targetpath) return print_and_clear_g_error (err); - rv = mu_msg_part_save (msg, MU_MSG_OPTION_USE_EXISTING, + rv = mu_msg_part_save (msg, opts | MU_MSG_OPTION_USE_EXISTING, targetpath, index, err); if (!rv) { print_and_clear_g_error (err); @@ -736,8 +736,8 @@ leave: static MuError -temp_part (MuMsg *msg, unsigned docid, unsigned index, GHashTable *args, - GError **err) +temp_part (MuMsg *msg, unsigned docid, unsigned index, + MuMsgOptions opts, GHashTable *args, GError **err) { const char *what, *param; char *path; @@ -745,11 +745,10 @@ temp_part (MuMsg *msg, unsigned docid, unsigned index, GHashTable *args, GET_STRING_OR_ERROR_RETURN (args, "what", &what, err); param = get_string_from_args (args, "param", TRUE, NULL); - path = mu_msg_part_get_cache_path (msg, MU_MSG_OPTION_NONE, - index, err); + path = mu_msg_part_get_cache_path (msg, opts, index, err); if (!path) print_and_clear_g_error (err); - else if (!mu_msg_part_save (msg, MU_MSG_OPTION_USE_EXISTING, + else if (!mu_msg_part_save (msg, opts | MU_MSG_OPTION_USE_EXISTING, path, index, err)) print_and_clear_g_error (err); else { @@ -778,6 +777,21 @@ temp_part (MuMsg *msg, unsigned docid, unsigned index, GHashTable *args, } +static MuMsgOptions +get_extract_msg_opts (GHashTable *args) +{ + MuMsgOptions opts; + + opts = MU_MSG_OPTION_NONE; + + if (get_bool_from_args (args, "use-agent", FALSE, NULL)) + opts |= MU_MSG_OPTION_USE_AGENT; + if (get_bool_from_args (args, "extract-encrypted", FALSE, NULL)) + opts |= MU_MSG_OPTION_DECRYPT; + + return opts; +} + enum { SAVE, OPEN, TEMP, INVALID_ACTION }; static int action_type (const char *actionstr) @@ -799,8 +813,10 @@ cmd_extract (ServerContext *ctx, GHashTable *args, GError **err) MuMsg *msg; int docid, index, action; MuError rv; + MuMsgOptions opts; const char* actionstr, *indexstr; + opts = get_extract_msg_opts (args); rv = MU_ERROR; /* read parameters */ @@ -824,9 +840,9 @@ cmd_extract (ServerContext *ctx, GHashTable *args, GError **err) } switch (action) { - case SAVE: rv = save_part (msg, docid, index, args, err); break; - case OPEN: rv = open_part (msg, docid, index, err); break; - case TEMP: rv = temp_part (msg, docid, index, args, err); break; + case SAVE: rv = save_part (msg, docid, index, opts, args, err); break; + case OPEN: rv = open_part (msg, docid, index, opts, err); break; + case TEMP: rv = temp_part (msg, docid, index, opts, args, err); break; default: print_error (MU_ERROR_INTERNAL, "unknown action"); } diff --git a/mu4e/mu4e-proc.el b/mu4e/mu4e-proc.el index e5b4a652..2efd0e47 100644 --- a/mu4e/mu4e-proc.el +++ b/mu4e/mu4e-proc.el @@ -452,7 +452,7 @@ The result will be delivered to the function registered as "Create a new maildir-directory at filesystem PATH." (mu4e~proc-send-command "cmd:mkdir path:%s" (mu4e~proc-escape path))) -(defun mu4e~proc-extract (action docid partidx &optional path what param) +(defun mu4e~proc-extract (action docid partidx decrypt &optional path what param) "Extract an attachment with index PARTIDX from message with DOCID and perform ACTION on it (as symbol, either `save', `open', `temp') which mean: @@ -464,17 +464,19 @@ mean: (concat "cmd:extract " (case action (save - (format "action:save docid:%d index:%d path:%s" - docid partidx (mu4e~proc-escape path))) - (open (format "action:open docid:%d index:%d" docid partidx)) + (format "action:save docid:%d index:%d path:%s extract-encrypted:%s use-agent:true" + docid partidx (mu4e~proc-escape path) (if decrypt "true" "false"))) + (open (format "action:open docid:%d index:%d extract-encrypted:%s use-agent:true" + docid partidx (if decrypt "true" "false"))) (temp - (format "action:temp docid:%d index:%d what:%s%s" + (format "action:temp docid:%d index:%d what:%s%s extract-encrypted:%s use-agent:true" docid partidx what (if param (if (stringp param) (format " param:%s" (mu4e~proc-escape param)) - (format " param:%S" param)) ""))) - (otherwise (mu4e-error "Unsupported action %S" action)))))) + (format " param:%S" param)) "") (if decrypt "true" "false"))) + (otherwise (mu4e-error "Unsupported action %S" action)))) + )) (mu4e~proc-send-command "%s" cmd))) diff --git a/mu4e/mu4e-view.el b/mu4e/mu4e-view.el index 01421bf3..b9573f7a 100644 --- a/mu4e/mu4e-view.el +++ b/mu4e/mu4e-view.el @@ -251,7 +251,7 @@ found." "Display the message MSG in a new buffer, and keep in sync with HDRSBUF. 'In sync' here means that moving to the next/previous message in the the message view affects HDRSBUF, as does marking etc. - + As a side-effect, a message that is being viewed loses its 'unread' marking if it still had that." (let* ((embedded ;; is it as an embedded msg (ie. message/rfc822 att)? @@ -274,7 +274,7 @@ marking if it still had that." (goto-char (point-min)) (mu4e~fontify-cited) (mu4e~fontify-signature) - (mu4e~view-make-urls-clickable) + (mu4e~view-make-urls-clickable) (mu4e~view-show-images-maybe msg) (setq mu4e~view-buffer buf @@ -296,7 +296,7 @@ Meant to be evoked from interactive commands." (window-buffer (posn-window posn))) )) (get-text-property (point) prop))) - + (defun mu4e~view-construct-header (field val &optional dont-propertize-val) "Return header field FIELD (as in `mu4e-header-info') with value VAL if VAL is non-nil. If DONT-PROPERTIZE-VAL is non-nil, do not @@ -324,7 +324,7 @@ add text-properties to VAL." (indent-to-column margin)))) (buffer-string)) ""))) - + (defun mu4e~view-compose-contact (&optional point) "Compose a message for the address at point." (interactive) @@ -780,7 +780,7 @@ Also number them so they can be opened using `mu4e-view-go-to-url'." keymap ,mu4e-view-clickable-urls-keymap help-echo "[mouse-1] or [M-RET] to open the link")) - (overlay-put ov 'after-string + (overlay-put ov 'after-string (propertize (format "[%d]" num) 'face 'mu4e-url-number-face)) ))))) @@ -1045,13 +1045,13 @@ If ATTNUM is nil ask for the attachment number." ;; current message when quiting that one. (mu4e~view-temp-action docid index "mu4e" docid) ;; otherwise, open with the default program (handled in mu-server - (mu4e~proc-extract 'open docid index)))) + (mu4e~proc-extract 'open docid index mu4e-decryption-policy)))) (defun mu4e~view-temp-action (docid index what &optional param) "Open attachment INDEX for message with DOCID, and invoke ACTION." (interactive) - (mu4e~proc-extract 'temp docid index nil what param)) + (mu4e~proc-extract 'temp docid index mu4e-decryption-policy nil what param )) (defvar mu4e~view-open-with-hist nil "History list for the open-with argument.")