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.
This commit is contained in:
Foivos S. Zakkak 2014-10-10 18:34:57 +03:00
parent 91250b0d71
commit 51037be7fb
4 changed files with 61 additions and 30 deletions

View File

@ -42,8 +42,13 @@ do_it_with_index (MuMsg *msg, MuMsgPart *part, DoData *ddata)
if (ddata->mime_obj) if (ddata->mime_obj)
return; 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; ddata->mime_obj = (GMimeObject*)part->data;
}
} }
static GMimeObject* static GMimeObject*
@ -648,6 +653,10 @@ save_object (GMimeObject *obj, MuMsgOptions opts, const char *fullpath,
else else
rv = write_object_to_fd (obj, fd, err); 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 */ if (close (fd) != 0 && !err) { /* don't write on top of old err */
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE, g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE,
"could not close '%s': %s", "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); fname = mime_part_get_filename (mobj, index, TRUE);
filepath = g_build_path (G_DIR_SEPARATOR_S, targetdir ? targetdir : "", filepath = g_build_path (G_DIR_SEPARATOR_S, targetdir ? targetdir : "",
fname, NULL); fname, NULL);
/* Unref it since it was referenced earlier by
* get_mime_object_at_index */
g_object_unref (mobj);
g_free (fname); g_free (fname);
return filepath; return filepath;

View File

@ -675,8 +675,8 @@ print_sexps (MuMsgIter *iter, unsigned maxnum)
static MuError static MuError
save_part (MuMsg *msg, unsigned docid, save_part (MuMsg *msg, unsigned docid, unsigned index,
unsigned index, GHashTable *args, GError **err) MuMsgOptions opts, GHashTable *args, GError **err)
{ {
gboolean rv; gboolean rv;
const gchar *path; const gchar *path;
@ -684,7 +684,7 @@ save_part (MuMsg *msg, unsigned docid,
GET_STRING_OR_ERROR_RETURN (args, "path", &path, err); 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); path, index, err);
if (!rv) { if (!rv) {
print_and_clear_g_error (err); print_and_clear_g_error (err);
@ -701,17 +701,17 @@ save_part (MuMsg *msg, unsigned docid,
static MuError 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; char *targetpath;
gboolean rv; gboolean rv;
targetpath = mu_msg_part_get_cache_path (msg,MU_MSG_OPTION_NONE, targetpath = mu_msg_part_get_cache_path (msg, opts, index, err);
index, err);
if (!targetpath) if (!targetpath)
return print_and_clear_g_error (err); 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); targetpath, index, err);
if (!rv) { if (!rv) {
print_and_clear_g_error (err); print_and_clear_g_error (err);
@ -736,8 +736,8 @@ leave:
static MuError static MuError
temp_part (MuMsg *msg, unsigned docid, unsigned index, GHashTable *args, temp_part (MuMsg *msg, unsigned docid, unsigned index,
GError **err) MuMsgOptions opts, GHashTable *args, GError **err)
{ {
const char *what, *param; const char *what, *param;
char *path; 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); GET_STRING_OR_ERROR_RETURN (args, "what", &what, err);
param = get_string_from_args (args, "param", TRUE, NULL); param = get_string_from_args (args, "param", TRUE, NULL);
path = mu_msg_part_get_cache_path (msg, MU_MSG_OPTION_NONE, path = mu_msg_part_get_cache_path (msg, opts, index, err);
index, err);
if (!path) if (!path)
print_and_clear_g_error (err); 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)) path, index, err))
print_and_clear_g_error (err); print_and_clear_g_error (err);
else { 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 }; enum { SAVE, OPEN, TEMP, INVALID_ACTION };
static int static int
action_type (const char *actionstr) action_type (const char *actionstr)
@ -799,8 +813,10 @@ cmd_extract (ServerContext *ctx, GHashTable *args, GError **err)
MuMsg *msg; MuMsg *msg;
int docid, index, action; int docid, index, action;
MuError rv; MuError rv;
MuMsgOptions opts;
const char* actionstr, *indexstr; const char* actionstr, *indexstr;
opts = get_extract_msg_opts (args);
rv = MU_ERROR; rv = MU_ERROR;
/* read parameters */ /* read parameters */
@ -824,9 +840,9 @@ cmd_extract (ServerContext *ctx, GHashTable *args, GError **err)
} }
switch (action) { switch (action) {
case SAVE: rv = save_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, err); break; case OPEN: rv = open_part (msg, docid, index, opts, err); break;
case TEMP: rv = temp_part (msg, docid, index, args, err); break; case TEMP: rv = temp_part (msg, docid, index, opts, args, err); break;
default: print_error (MU_ERROR_INTERNAL, "unknown action"); default: print_error (MU_ERROR_INTERNAL, "unknown action");
} }

View File

@ -452,7 +452,7 @@ The result will be delivered to the function registered as
"Create a new maildir-directory at filesystem PATH." "Create a new maildir-directory at filesystem PATH."
(mu4e~proc-send-command "cmd:mkdir path:%s" (mu4e~proc-escape 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 "Extract an attachment with index PARTIDX from message with DOCID
and perform ACTION on it (as symbol, either `save', `open', `temp') which and perform ACTION on it (as symbol, either `save', `open', `temp') which
mean: mean:
@ -464,17 +464,19 @@ mean:
(concat "cmd:extract " (concat "cmd:extract "
(case action (case action
(save (save
(format "action:save docid:%d index:%d path:%s" (format "action:save docid:%d index:%d path:%s extract-encrypted:%s use-agent:true"
docid partidx (mu4e~proc-escape path))) docid partidx (mu4e~proc-escape path) (if decrypt "true" "false")))
(open (format "action:open docid:%d index:%d" docid partidx)) (open (format "action:open docid:%d index:%d extract-encrypted:%s use-agent:true"
docid partidx (if decrypt "true" "false")))
(temp (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 docid partidx what
(if param (if param
(if (stringp param) (if (stringp param)
(format " param:%s" (mu4e~proc-escape param)) (format " param:%s" (mu4e~proc-escape param))
(format " param:%S" param)) ""))) (format " param:%S" param)) "") (if decrypt "true" "false")))
(otherwise (mu4e-error "Unsupported action %S" action)))))) (otherwise (mu4e-error "Unsupported action %S" action))))
))
(mu4e~proc-send-command "%s" cmd))) (mu4e~proc-send-command "%s" cmd)))

View File

@ -251,7 +251,7 @@ found."
"Display the message MSG in a new buffer, and keep in sync with HDRSBUF. "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 'In sync' here means that moving to the next/previous message in
the the message view affects HDRSBUF, as does marking etc. the the message view affects HDRSBUF, as does marking etc.
As a side-effect, a message that is being viewed loses its 'unread' As a side-effect, a message that is being viewed loses its 'unread'
marking if it still had that." marking if it still had that."
(let* ((embedded ;; is it as an embedded msg (ie. message/rfc822 att)? (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)) (goto-char (point-min))
(mu4e~fontify-cited) (mu4e~fontify-cited)
(mu4e~fontify-signature) (mu4e~fontify-signature)
(mu4e~view-make-urls-clickable) (mu4e~view-make-urls-clickable)
(mu4e~view-show-images-maybe msg) (mu4e~view-show-images-maybe msg)
(setq (setq
mu4e~view-buffer buf mu4e~view-buffer buf
@ -296,7 +296,7 @@ Meant to be evoked from interactive commands."
(window-buffer (posn-window posn))) (window-buffer (posn-window posn)))
)) ))
(get-text-property (point) prop))) (get-text-property (point) prop)))
(defun mu4e~view-construct-header (field val &optional dont-propertize-val) (defun mu4e~view-construct-header (field val &optional dont-propertize-val)
"Return header field FIELD (as in `mu4e-header-info') with value "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 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)))) (indent-to-column margin))))
(buffer-string)) (buffer-string))
""))) "")))
(defun mu4e~view-compose-contact (&optional point) (defun mu4e~view-compose-contact (&optional point)
"Compose a message for the address at point." "Compose a message for the address at point."
(interactive) (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 keymap ,mu4e-view-clickable-urls-keymap
help-echo help-echo
"[mouse-1] or [M-RET] to open the link")) "[mouse-1] or [M-RET] to open the link"))
(overlay-put ov 'after-string (overlay-put ov 'after-string
(propertize (format "[%d]" num) (propertize (format "[%d]" num)
'face 'mu4e-url-number-face)) 'face 'mu4e-url-number-face))
))))) )))))
@ -1045,13 +1045,13 @@ If ATTNUM is nil ask for the attachment number."
;; current message when quiting that one. ;; current message when quiting that one.
(mu4e~view-temp-action docid index "mu4e" docid) (mu4e~view-temp-action docid index "mu4e" docid)
;; otherwise, open with the default program (handled in mu-server ;; 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) (defun mu4e~view-temp-action (docid index what &optional param)
"Open attachment INDEX for message with DOCID, and invoke ACTION." "Open attachment INDEX for message with DOCID, and invoke ACTION."
(interactive) (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.") (defvar mu4e~view-open-with-hist nil "History list for the open-with argument.")