* updates for mu-msg-part changes
This commit is contained in:
@ -29,7 +29,6 @@
|
|||||||
#include "mu-msg-crypto.h"
|
#include "mu-msg-crypto.h"
|
||||||
#include "mu-date.h"
|
#include "mu-date.h"
|
||||||
|
|
||||||
|
|
||||||
#include <gmime/gmime.h>
|
#include <gmime/gmime.h>
|
||||||
#include <gmime/gmime-multipart-signed.h>
|
#include <gmime/gmime-multipart-signed.h>
|
||||||
|
|
||||||
@ -117,17 +116,11 @@ get_gpg_crypto_context (MuMsgOptions opts, GError **err)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_mime_gpg_context_set_use_agent
|
/* always try to use the agent */
|
||||||
(GMIME_GPG_CONTEXT(cctx), TRUE);
|
g_mime_gpg_context_set_use_agent (GMIME_GPG_CONTEXT(cctx), TRUE);
|
||||||
/* opts & MU_MSG_OPTION_USE_AGENT ? TRUE:FALSE); */
|
|
||||||
/* g_mime_gpg_context_set_use_agent */
|
|
||||||
/* (GMIME_GPG_CONTEXT(cctx), */
|
|
||||||
/* opts & MU_MSG_OPTION_USE_AGENT ? TRUE:FALSE); */
|
|
||||||
g_mime_gpg_context_set_auto_key_retrieve
|
g_mime_gpg_context_set_auto_key_retrieve
|
||||||
(GMIME_GPG_CONTEXT(cctx),
|
(GMIME_GPG_CONTEXT(cctx),
|
||||||
opts & MU_MSG_OPTION_AUTO_RETRIEVE_KEY ? TRUE:FALSE);
|
opts & MU_MSG_OPTION_AUTO_RETRIEVE ? TRUE:FALSE);
|
||||||
g_mime_gpg_context_set_always_trust
|
|
||||||
(GMIME_GPG_CONTEXT(cctx), FALSE);
|
|
||||||
|
|
||||||
return cctx;
|
return cctx;
|
||||||
}
|
}
|
||||||
@ -532,6 +525,7 @@ mu_msg_part_sig_info_to_string (MuMsgPartSigInfo *info)
|
|||||||
|
|
||||||
GMimeObject* /* this is declared in mu-msg-priv.h */
|
GMimeObject* /* this is declared in mu-msg-priv.h */
|
||||||
mu_msg_crypto_decrypt_part (GMimeMultipartEncrypted *enc, MuMsgOptions opts,
|
mu_msg_crypto_decrypt_part (GMimeMultipartEncrypted *enc, MuMsgOptions opts,
|
||||||
|
MuMsgPartPasswordFunc func, gpointer user_data,
|
||||||
GError **err)
|
GError **err)
|
||||||
{
|
{
|
||||||
GMimeObject *dec;
|
GMimeObject *dec;
|
||||||
@ -539,7 +533,7 @@ mu_msg_crypto_decrypt_part (GMimeMultipartEncrypted *enc, MuMsgOptions opts,
|
|||||||
|
|
||||||
g_return_val_if_fail (GMIME_IS_MULTIPART_ENCRYPTED(enc), NULL);
|
g_return_val_if_fail (GMIME_IS_MULTIPART_ENCRYPTED(enc), NULL);
|
||||||
|
|
||||||
ctx = get_crypto_context (opts, NULL, NULL, err);
|
ctx = get_crypto_context (opts, func, user_data, err);
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
mu_util_g_set_error (err, MU_ERROR_CRYPTO,
|
mu_util_g_set_error (err, MU_ERROR_CRYPTO,
|
||||||
"failed to get crypto context");
|
"failed to get crypto context");
|
||||||
|
|||||||
@ -96,7 +96,6 @@ const char* mu_msg_part_sig_status_to_string (MuMsgPartSigStatus status);
|
|||||||
*/
|
*/
|
||||||
MuMsgPartSigStatus mu_msg_part_sig_infos_verdict (GSList *sig_infos);
|
MuMsgPartSigStatus mu_msg_part_sig_infos_verdict (GSList *sig_infos);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* convert the bitwise-OR'ed statuses to a string
|
* convert the bitwise-OR'ed statuses to a string
|
||||||
*
|
*
|
||||||
@ -125,81 +124,8 @@ char* mu_msg_part_sig_info_to_string (MuMsgPartSigInfo *info)
|
|||||||
*/
|
*/
|
||||||
void mu_msg_part_free_sig_infos (GSList *siginfos);
|
void mu_msg_part_free_sig_infos (GSList *siginfos);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* below function only do anything useful if mu was built with crypto
|
|
||||||
* support
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct _MuMsgDecryptedPart;
|
struct _MuMsgDecryptedPart;
|
||||||
typedef struct _MuMsgDecryptedPart MuMsgDecryptedPart;
|
typedef struct _MuMsgDecryptedPart MuMsgDecryptedPart;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* callback function to provide decrypted message parts
|
|
||||||
*
|
|
||||||
* @param dpart a decrypted par
|
|
||||||
* @param user_data user pointer (as passed to mu_msg_part_decrypt_foreach)
|
|
||||||
*/
|
|
||||||
typedef void (*MuMsgPartDecryptForeachFunc) (MuMsgDecryptedPart *dpart,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* callback function to retrieve a password from the user
|
|
||||||
*
|
|
||||||
* @param user_id the user name / id to get the password for
|
|
||||||
* @param prompt_ctx a string containing some helpful context for the prompt
|
|
||||||
* @param reprompt whether this is a reprompt after an earlier, incorrect password
|
|
||||||
* @param user_data the user_data pointer passed to mu_msg_part_decrypt_foreach
|
|
||||||
*
|
|
||||||
* @return a newly allocated (g_free'able) string
|
|
||||||
*/
|
|
||||||
typedef char* (*MuMsgPartPasswordFunc) (const char *user_id, const char *prompt_ctx,
|
|
||||||
gboolean reprompt, gpointer user_data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* go through all MIME-parts for this message, and decrypted all parts
|
|
||||||
* that are encrypted. After decryption,
|
|
||||||
*
|
|
||||||
* If mu was built without crypto support, function does nothing.
|
|
||||||
*
|
|
||||||
* @param msg a valid MuMsg instance
|
|
||||||
* @param fun a callback function called for each decrypted part
|
|
||||||
* @param password_func a callback func called to retrieve a password from user
|
|
||||||
* @param user_data user data which passed to the callback function
|
|
||||||
* @param opts options
|
|
||||||
* @param err receives error information
|
|
||||||
*
|
|
||||||
* @return TRUE if function succeeded, FALSE otherwise
|
|
||||||
*/
|
|
||||||
gboolean mu_msg_part_decrypt_foreach (MuMsg *msg, MuMsgPartDecryptForeachFunc func,
|
|
||||||
MuMsgPartPasswordFunc password_func,
|
|
||||||
gpointer user_data, MuMsgOptions opts,
|
|
||||||
GError **err);
|
|
||||||
/**
|
|
||||||
* convert the decrypted part to a string.
|
|
||||||
*
|
|
||||||
* @param dpart decrypted part
|
|
||||||
* @param err receives error information
|
|
||||||
*
|
|
||||||
* @return decrypted part as a string (g_free after use), or NULL
|
|
||||||
*/
|
|
||||||
char* mu_msg_decrypted_part_to_string (MuMsgDecryptedPart *dpart, GError **err);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* write the decrypted part to a file.
|
|
||||||
*
|
|
||||||
* @param dpart decrypted part
|
|
||||||
* @param path path to write it to
|
|
||||||
* @param err receives error information
|
|
||||||
*
|
|
||||||
* @return TRUE if it succeeded, FALSE otherwise
|
|
||||||
*/
|
|
||||||
gboolean mu_msg_decrypted_part_to_file (MuMsgDecryptedPart *dpart, const char *path,
|
|
||||||
GError **err);
|
|
||||||
|
|
||||||
#endif /*__MU_MSG_CRYPTO_H__*/
|
#endif /*__MU_MSG_CRYPTO_H__*/
|
||||||
|
|||||||
@ -117,23 +117,18 @@ each_contact (MuMsgContact *c, ContactData *cdata)
|
|||||||
case MU_MSG_CONTACT_TYPE_FROM:
|
case MU_MSG_CONTACT_TYPE_FROM:
|
||||||
add_prefix_maybe (cdata->gstr, &cdata->from, "\t:from (");
|
add_prefix_maybe (cdata->gstr, &cdata->from, "\t:from (");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MU_MSG_CONTACT_TYPE_TO:
|
case MU_MSG_CONTACT_TYPE_TO:
|
||||||
add_prefix_maybe (cdata->gstr, &cdata->to, "\t:to (");
|
add_prefix_maybe (cdata->gstr, &cdata->to, "\t:to (");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MU_MSG_CONTACT_TYPE_CC:
|
case MU_MSG_CONTACT_TYPE_CC:
|
||||||
add_prefix_maybe (cdata->gstr, &cdata->cc, "\t:cc (");
|
add_prefix_maybe (cdata->gstr, &cdata->cc, "\t:cc (");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MU_MSG_CONTACT_TYPE_BCC:
|
case MU_MSG_CONTACT_TYPE_BCC:
|
||||||
add_prefix_maybe (cdata->gstr, &cdata->bcc, "\t:bcc (");
|
add_prefix_maybe (cdata->gstr, &cdata->bcc, "\t:bcc (");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MU_MSG_CONTACT_TYPE_REPLY_TO:
|
case MU_MSG_CONTACT_TYPE_REPLY_TO:
|
||||||
add_prefix_maybe (cdata->gstr, &cdata->reply_to, "\t:reply-to (");
|
add_prefix_maybe (cdata->gstr, &cdata->reply_to, "\t:reply-to (");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: g_return_val_if_reached (FALSE);
|
default: g_return_val_if_reached (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,23 +198,27 @@ append_sexp_flags (GString *gstr, MuMsg *msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char*
|
static char*
|
||||||
get_temp_file (MuMsg *msg, unsigned index)
|
get_temp_file (MuMsg *msg, MuMsgOptions opts, unsigned index)
|
||||||
{
|
{
|
||||||
char *path;
|
char *path;
|
||||||
GError *err;
|
GError *err;
|
||||||
|
|
||||||
err = NULL;
|
err = NULL;
|
||||||
path = mu_msg_part_filepath_cache (msg, index);
|
path = mu_msg_part_get_cache_path (msg, opts, index, &err);
|
||||||
if (!mu_msg_part_save (msg, path, index,
|
if (!path)
|
||||||
FALSE/*overwrite*/, TRUE/*use cache*/, &err)) {
|
goto errexit;
|
||||||
|
|
||||||
|
if (!mu_msg_part_save (msg, opts, path, index, &err))
|
||||||
|
goto errexit;
|
||||||
|
|
||||||
|
return path;
|
||||||
|
|
||||||
|
errexit:
|
||||||
g_warning ("failed to save mime part: %s",
|
g_warning ("failed to save mime part: %s",
|
||||||
err->message ? err->message : "something went wrong");
|
err->message ? err->message : "something went wrong");
|
||||||
g_clear_error (&err);
|
g_clear_error (&err);
|
||||||
g_free (path);
|
g_free (path);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -232,7 +231,7 @@ get_temp_file_maybe (MuMsg *msg, MuMsgPart *part, MuMsgOptions opts)
|
|||||||
g_ascii_strcasecmp (part->type, "image") != 0)
|
g_ascii_strcasecmp (part->type, "image") != 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
tmp = get_temp_file (msg, part->index);
|
tmp = get_temp_file (msg, opts, part->index);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -274,32 +273,6 @@ sig_verdict (GSList *sig_infos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char*
|
|
||||||
get_part_filename (MuMsgPart *part)
|
|
||||||
{
|
|
||||||
const char *fname;
|
|
||||||
char *name;
|
|
||||||
const char *ctype, *csubtype;
|
|
||||||
|
|
||||||
ctype = part->type;
|
|
||||||
csubtype = part->subtype;
|
|
||||||
if (!ctype || !csubtype) {
|
|
||||||
ctype = "application";
|
|
||||||
csubtype = "octet-stream";
|
|
||||||
}
|
|
||||||
|
|
||||||
fname = mu_msg_part_file_name (part);
|
|
||||||
if (!fname)
|
|
||||||
fname = mu_msg_part_description (part);
|
|
||||||
|
|
||||||
if (fname)
|
|
||||||
name = mu_str_escape_c_literal (fname, TRUE);
|
|
||||||
else
|
|
||||||
name = g_strdup_printf ("\"%s-%s-%d\"",
|
|
||||||
ctype, csubtype, part->index);
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
get_part_type_string (MuMsgPartType ptype)
|
get_part_type_string (MuMsgPartType ptype)
|
||||||
{
|
{
|
||||||
@ -348,16 +321,16 @@ each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo)
|
|||||||
char *name, *tmp, *parttype;
|
char *name, *tmp, *parttype;
|
||||||
char *tmpfile;
|
char *tmpfile;
|
||||||
|
|
||||||
name = get_part_filename (part);
|
name = mu_msg_part_get_filename (part, TRUE);
|
||||||
|
|
||||||
tmpfile = get_temp_file_maybe (msg, part, pinfo->opts);
|
tmpfile = get_temp_file_maybe (msg, part, pinfo->opts);
|
||||||
parttype = get_part_type_string (part->part_type);
|
parttype = get_part_type_string (part->part_type);
|
||||||
|
|
||||||
tmp = g_strdup_printf
|
tmp = g_strdup_printf
|
||||||
("%s(:index %d :name %s :mime-type \"%s/%s\"%s%s "
|
("%s(:index %d :name \"%s\" :mime-type \"%s/%s\"%s%s "
|
||||||
":type %s "
|
":type %s "
|
||||||
":attachment %s :size %i %s)",
|
":attachment %s :size %i %s)",
|
||||||
elvis (pinfo->parts, ""), part->index, name,
|
elvis (pinfo->parts, ""), part->index,
|
||||||
|
name ? name : "noname",
|
||||||
elvis (part->type, "application"),
|
elvis (part->type, "application"),
|
||||||
elvis (part->subtype, "octet-stream"),
|
elvis (part->subtype, "octet-stream"),
|
||||||
tmpfile ? " :temp" : "", tmpfile ? tmpfile : "",
|
tmpfile ? " :temp" : "", tmpfile ? tmpfile : "",
|
||||||
@ -379,28 +352,16 @@ append_sexp_parts (GString *gstr, MuMsg *msg, MuMsgOptions opts)
|
|||||||
pinfo.parts = NULL;
|
pinfo.parts = NULL;
|
||||||
pinfo.opts = opts;
|
pinfo.opts = opts;
|
||||||
|
|
||||||
mu_msg_part_foreach (msg, (MuMsgPartForeachFunc)each_part,
|
if (!mu_msg_part_foreach (msg, opts, (MuMsgPartForeachFunc)each_part,
|
||||||
&pinfo, opts);
|
&pinfo)) {
|
||||||
if (pinfo.parts) {
|
/* if decryption failed, mark this message as encrypted */
|
||||||
|
g_string_append (gstr, "\t:encrypted t\n");
|
||||||
|
} else if (pinfo.parts) {
|
||||||
g_string_append_printf (gstr, "\t:parts (%s)\n", pinfo.parts);
|
g_string_append_printf (gstr, "\t:parts (%s)\n", pinfo.parts);
|
||||||
g_free (pinfo.parts);
|
g_free (pinfo.parts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
append_sexp_message_file_attr (GString *gstr, MuMsg *msg)
|
|
||||||
{
|
|
||||||
append_sexp_attr_list (gstr, "references", mu_msg_get_references (msg));
|
|
||||||
append_sexp_attr (gstr, "in-reply-to",
|
|
||||||
mu_msg_get_header (msg, "In-Reply-To"));
|
|
||||||
append_sexp_attr (gstr, "body-txt",
|
|
||||||
mu_msg_get_body_text(msg));
|
|
||||||
append_sexp_attr (gstr, "body-html",
|
|
||||||
mu_msg_get_body_html(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
append_sexp_thread_info (GString *gstr, const MuMsgIterThreadInfo *ti)
|
append_sexp_thread_info (GString *gstr, const MuMsgIterThreadInfo *ti)
|
||||||
{
|
{
|
||||||
@ -418,11 +379,30 @@ append_sexp_thread_info (GString *gstr, const MuMsgIterThreadInfo *ti)
|
|||||||
" :has-child t" : "");
|
" :has-child t" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
append_non_headers_only_attr (GString *gstr, MuMsg *msg, MuMsgOptions opts)
|
append_message_file_parts (GString *gstr, MuMsg *msg, MuMsgOptions opts)
|
||||||
{
|
{
|
||||||
append_sexp_message_file_attr (gstr, msg);
|
GError *err;
|
||||||
|
err = NULL;
|
||||||
|
|
||||||
|
if (!mu_msg_load_msg_file (msg, &err)) {
|
||||||
|
g_warning ("failed to load message file: %s",
|
||||||
|
err ? err->message : "some error occured");
|
||||||
|
g_clear_error (&err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
append_sexp_parts (gstr, msg, opts);
|
append_sexp_parts (gstr, msg, opts);
|
||||||
|
append_sexp_contacts (gstr, msg);
|
||||||
|
|
||||||
|
append_sexp_attr_list (gstr, "references", mu_msg_get_references (msg));
|
||||||
|
append_sexp_attr (gstr, "in-reply-to",
|
||||||
|
mu_msg_get_header (msg, "In-Reply-To"));
|
||||||
|
append_sexp_attr (gstr, "body-txt",
|
||||||
|
mu_msg_get_body_text(msg));
|
||||||
|
append_sexp_attr (gstr, "body-html",
|
||||||
|
mu_msg_get_body_html(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -449,6 +429,11 @@ mu_msg_to_sexp (MuMsg *msg, unsigned docid, const MuMsgIterThreadInfo *ti,
|
|||||||
|
|
||||||
append_sexp_attr (gstr, "subject", mu_msg_get_subject (msg));
|
append_sexp_attr (gstr, "subject", mu_msg_get_subject (msg));
|
||||||
|
|
||||||
|
/* in the no-headers-only case (see below) we get a more complete list
|
||||||
|
* of contacts, so no need to get them here if that's the case */
|
||||||
|
if (opts & MU_MSG_OPTION_HEADERS_ONLY)
|
||||||
|
append_sexp_contacts (gstr, msg);
|
||||||
|
|
||||||
t = mu_msg_get_date (msg);
|
t = mu_msg_get_date (msg);
|
||||||
/* weird time format for emacs 29-bit ints...*/
|
/* weird time format for emacs 29-bit ints...*/
|
||||||
g_string_append_printf (gstr,"\t:date (%u %u 0)\n", (unsigned)(t >> 16),
|
g_string_append_printf (gstr,"\t:date (%u %u 0)\n", (unsigned)(t >> 16),
|
||||||
@ -467,11 +452,7 @@ mu_msg_to_sexp (MuMsg *msg, unsigned docid, const MuMsgIterThreadInfo *ti,
|
|||||||
* file attr things can only be gotten from the file (ie., mu
|
* file attr things can only be gotten from the file (ie., mu
|
||||||
* view), not from the database (mu find). */
|
* view), not from the database (mu find). */
|
||||||
if (!(opts & MU_MSG_OPTION_HEADERS_ONLY))
|
if (!(opts & MU_MSG_OPTION_HEADERS_ONLY))
|
||||||
append_non_headers_only_attr (gstr, msg, opts);
|
append_message_file_parts (gstr, msg, opts);
|
||||||
|
|
||||||
/* note, some of the contacts info comes from the file, soe
|
|
||||||
* this has to be after the previous */
|
|
||||||
append_sexp_contacts (gstr, msg);
|
|
||||||
|
|
||||||
g_string_append (gstr, ")\n");
|
g_string_append (gstr, ")\n");
|
||||||
return g_string_free (gstr, FALSE);
|
return g_string_free (gstr, FALSE);
|
||||||
|
|||||||
20
lib/mu-msg.c
20
lib/mu-msg.c
@ -170,26 +170,6 @@ mu_msg_unref (MuMsg *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
mu_msg_set_auto_decrypt (MuMsg *msg, gboolean autodecrypt)
|
|
||||||
{
|
|
||||||
g_return_if_fail (msg);
|
|
||||||
mu_msg_load_msg_file (msg, NULL);
|
|
||||||
msg->_file->_auto_decrypt = autodecrypt;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
mu_msg_get_auto_decrypt (MuMsg *msg)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (msg, FALSE);
|
|
||||||
if (!msg->_file)
|
|
||||||
return FALSE;
|
|
||||||
return msg->_file->_auto_decrypt;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* use this instead of mu_msg_get_path so we don't get into infinite
|
/* use this instead of mu_msg_get_path so we don't get into infinite
|
||||||
* regress...*/
|
* regress...*/
|
||||||
static const char*
|
static const char*
|
||||||
|
|||||||
40
lib/mu-msg.h
40
lib/mu-msg.h
@ -43,10 +43,19 @@ enum _MuMsgOptions {
|
|||||||
|
|
||||||
/* below options are for checking signatures; only effective
|
/* below options are for checking signatures; only effective
|
||||||
* if mu was built with crypto support */
|
* if mu was built with crypto support */
|
||||||
MU_MSG_OPTION_CHECK_SIGNATURES = 1 << 4,
|
MU_MSG_OPTION_VERIFY = 1 << 4,
|
||||||
MU_MSG_OPTION_AUTO_RETRIEVE_KEY = 1 << 5,
|
MU_MSG_OPTION_AUTO_RETRIEVE = 1 << 5,
|
||||||
MU_MSG_OPTION_USE_AGENT = 1 << 6,
|
MU_MSG_OPTION_USE_AGENT = 1 << 6,
|
||||||
MU_MSG_OPTION_USE_PKCS7 = 1 << 7 /* gpg is the default */
|
MU_MSG_OPTION_USE_PKCS7 = 1 << 7, /* gpg is the default */
|
||||||
|
|
||||||
|
MU_MSG_OPTION_DECRYPT = 1 << 8,
|
||||||
|
|
||||||
|
/* misc */
|
||||||
|
MU_MSG_OPTION_OVERWRITE = 1 << 9,
|
||||||
|
MU_MSG_OPTION_USE_EXISTING = 1 << 10,
|
||||||
|
|
||||||
|
/* recurse into submessages */
|
||||||
|
MU_MSG_OPTION_RECURSE_RFC822 = 1 << 11
|
||||||
|
|
||||||
};
|
};
|
||||||
typedef enum _MuMsgOptions MuMsgOptions;
|
typedef enum _MuMsgOptions MuMsgOptions;
|
||||||
@ -135,30 +144,6 @@ MuMsg *mu_msg_ref (MuMsg *msg);
|
|||||||
*/
|
*/
|
||||||
void mu_msg_unref (MuMsg *msg);
|
void mu_msg_unref (MuMsg *msg);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* should we set this message to 'autodecrypt'? if so, try to
|
|
||||||
* automatically decrypt encrypted message parts.
|
|
||||||
*
|
|
||||||
* @param msg a message
|
|
||||||
* @param autodecrypt TRUE or FALSE
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
void mu_msg_set_auto_decrypt (MuMsg *msg, gboolean autodecrypt);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get the autodecrypt status for this message. See @func mu_msg_set_auto_decrypt
|
|
||||||
*
|
|
||||||
* @param msg a message
|
|
||||||
*
|
|
||||||
* @return the auto-decrypt status
|
|
||||||
*/
|
|
||||||
gboolean mu_msg_get_auto_decrypt (MuMsg *msg);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cache the values from the backend (file or db), so we don't the
|
* cache the values from the backend (file or db), so we don't the
|
||||||
* backend anymore
|
* backend anymore
|
||||||
@ -223,7 +208,6 @@ const char* mu_msg_get_to (MuMsg *msg);
|
|||||||
*/
|
*/
|
||||||
const char* mu_msg_get_cc (MuMsg *msg);
|
const char* mu_msg_get_cc (MuMsg *msg);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the blind carbon-copy recipients (Bcc:) of this message; this
|
* get the blind carbon-copy recipients (Bcc:) of this message; this
|
||||||
* field usually only appears in outgoing messages
|
* field usually only appears in outgoing messages
|
||||||
|
|||||||
@ -382,18 +382,26 @@ struct PartData {
|
|||||||
GStringChunk *_strchunk;
|
GStringChunk *_strchunk;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* index non-body text parts */
|
||||||
|
static void
|
||||||
static gboolean
|
|
||||||
maybe_index_text_part (MuMsg *msg, MuMsgPart *part, PartData *pdata)
|
maybe_index_text_part (MuMsg *msg, MuMsgPart *part, PartData *pdata)
|
||||||
{
|
{
|
||||||
gboolean err;
|
gboolean err;
|
||||||
char *txt, *norm;
|
char *txt, *norm;
|
||||||
Xapian::TermGenerator termgen;
|
Xapian::TermGenerator termgen;
|
||||||
|
|
||||||
txt = mu_msg_part_get_text (msg, part, &err);
|
if (part->part_type & MU_MSG_PART_TYPE_BODY)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* TODO: add other text types? */
|
||||||
|
if (g_ascii_strcasecmp (part->type, "text") != 0 ||
|
||||||
|
g_ascii_strcasecmp (part->subtype, "plain") != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
txt = mu_msg_part_get_text (msg, part, MU_MSG_OPTION_NONE,
|
||||||
|
&err);
|
||||||
if (!txt || err)
|
if (!txt || err)
|
||||||
return FALSE;
|
return;
|
||||||
|
|
||||||
termgen.set_document(pdata->_doc);
|
termgen.set_document(pdata->_doc);
|
||||||
|
|
||||||
@ -404,13 +412,13 @@ maybe_index_text_part (MuMsg *msg, MuMsgPart *part, PartData *pdata)
|
|||||||
(norm, 1, prefix(MU_MSG_FIELD_ID_EMBEDDED_TEXT));
|
(norm, 1, prefix(MU_MSG_FIELD_ID_EMBEDDED_TEXT));
|
||||||
|
|
||||||
g_free (txt);
|
g_free (txt);
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
each_part (MuMsg *msg, MuMsgPart *part, PartData *pdata)
|
each_part (MuMsg *msg, MuMsgPart *part, PartData *pdata)
|
||||||
{
|
{
|
||||||
|
char *fname;
|
||||||
static const std::string
|
static const std::string
|
||||||
file (prefix(MU_MSG_FIELD_ID_FILE)),
|
file (prefix(MU_MSG_FIELD_ID_FILE)),
|
||||||
mime (prefix(MU_MSG_FIELD_ID_MIME));
|
mime (prefix(MU_MSG_FIELD_ID_MIME));
|
||||||
@ -430,20 +438,17 @@ each_part (MuMsg *msg, MuMsgPart *part, PartData *pdata)
|
|||||||
(mime + std::string(ctype, 0, MuStore::MAX_TERM_LENGTH));
|
(mime + std::string(ctype, 0, MuStore::MAX_TERM_LENGTH));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save the name of anything that has a filename */
|
/* now, let's create a term it there's a filename. allocated
|
||||||
if (part->file_name) {
|
* on strchunk, no need to free*/
|
||||||
|
if ((fname = mu_msg_part_get_filename (part, FALSE))) {
|
||||||
char *val;
|
char *val;
|
||||||
/* now, let's create a term... allocated on strchunk,
|
val = mu_str_xapian_escape (fname, TRUE /*esc space*/,
|
||||||
* no need to free*/
|
|
||||||
val = mu_str_xapian_escape (part->file_name, TRUE /*esc space*/,
|
|
||||||
pdata->_strchunk);
|
pdata->_strchunk);
|
||||||
|
g_free (fname);
|
||||||
pdata->_doc.add_term
|
pdata->_doc.add_term
|
||||||
(file + std::string(val, 0, MuStore::MAX_TERM_LENGTH));
|
(file + std::string(val, 0, MuStore::MAX_TERM_LENGTH));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now, for non-body parts with some MIME-types, index the
|
|
||||||
* content as well */
|
|
||||||
if (mu_msg_part_looks_like_attachment (part, FALSE))
|
|
||||||
maybe_index_text_part (msg, part, pdata);
|
maybe_index_text_part (msg, part, pdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,9 +458,8 @@ add_terms_values_attach (Xapian::Document& doc, MuMsg *msg,
|
|||||||
MuMsgFieldId mfid, GStringChunk *strchunk)
|
MuMsgFieldId mfid, GStringChunk *strchunk)
|
||||||
{
|
{
|
||||||
PartData pdata (doc, mfid, strchunk);
|
PartData pdata (doc, mfid, strchunk);
|
||||||
mu_msg_part_foreach (msg,
|
mu_msg_part_foreach (msg, MU_MSG_OPTION_NONE,
|
||||||
(MuMsgPartForeachFunc)each_part, &pdata,
|
(MuMsgPartForeachFunc)each_part, &pdata);
|
||||||
MU_MSG_OPTION_NONE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -32,33 +32,37 @@
|
|||||||
#include "mu-util.h"
|
#include "mu-util.h"
|
||||||
#include "mu-str.h"
|
#include "mu-str.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
save_part (MuMsg *msg, const char *targetdir, guint partidx, gboolean overwrite,
|
save_part (MuMsg *msg, const char *targetdir, guint partidx, MuConfig *opts)
|
||||||
gboolean play)
|
|
||||||
{
|
{
|
||||||
GError *err;
|
GError *err;
|
||||||
gchar *filepath;
|
gchar *filepath;
|
||||||
gboolean rv;
|
gboolean rv;
|
||||||
|
MuMsgOptions msgopts;
|
||||||
|
|
||||||
err = NULL;
|
err = NULL;
|
||||||
rv = FALSE;
|
rv = FALSE;
|
||||||
|
|
||||||
filepath = mu_msg_part_filepath (msg, targetdir, partidx, &err);
|
msgopts = mu_config_get_msg_options (opts);
|
||||||
|
|
||||||
|
filepath = mu_msg_part_get_path (msg, msgopts, targetdir, partidx, &err);
|
||||||
if (!filepath)
|
if (!filepath)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (!mu_msg_part_save (msg, filepath, partidx, overwrite, FALSE, &err))
|
if (!mu_msg_part_save (msg, msgopts, filepath, partidx, &err))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (play)
|
if (opts->play)
|
||||||
rv = mu_util_play (filepath, TRUE, FALSE, &err);
|
rv = mu_util_play (filepath, TRUE, FALSE, &err);
|
||||||
else
|
else
|
||||||
rv = TRUE;
|
rv = TRUE;
|
||||||
exit:
|
exit:
|
||||||
if (err)
|
if (err) {
|
||||||
g_warning ("error with MIME-part: %s",
|
g_warning ("error with MIME-part: %s", err->message);
|
||||||
err->message);
|
|
||||||
g_clear_error (&err);
|
g_clear_error (&err);
|
||||||
|
}
|
||||||
|
|
||||||
g_free (filepath);
|
g_free (filepath);
|
||||||
return rv;
|
return rv;
|
||||||
@ -87,8 +91,7 @@ save_numbered_parts (MuMsg *msg, MuConfig *opts)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!save_part (msg, opts->targetdir, idx, opts->overwrite,
|
if (!save_part (msg, opts->targetdir, idx, opts)) {
|
||||||
opts->play)) {
|
|
||||||
g_warning ("failed to save MIME-part %d", idx);
|
g_warning ("failed to save MIME-part %d", idx);
|
||||||
rv = FALSE;
|
rv = FALSE;
|
||||||
break;
|
break;
|
||||||
@ -135,13 +138,16 @@ save_part_with_filename (MuMsg *msg, const char *pattern, MuConfig *opts)
|
|||||||
GSList *lst, *cur;
|
GSList *lst, *cur;
|
||||||
GRegex *rx;
|
GRegex *rx;
|
||||||
gboolean rv;
|
gboolean rv;
|
||||||
|
MuMsgOptions msgopts;
|
||||||
|
|
||||||
|
msgopts = mu_config_get_msg_options (opts);
|
||||||
|
|
||||||
/* 'anchor' the pattern with '^...$' if not already */
|
/* 'anchor' the pattern with '^...$' if not already */
|
||||||
rx = anchored_regex (pattern);
|
rx = anchored_regex (pattern);
|
||||||
if (!rx)
|
if (!rx)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
lst = mu_msg_part_find_files (msg, rx);
|
lst = mu_msg_find_files (msg, msgopts, rx);
|
||||||
g_regex_unref (rx);
|
g_regex_unref (rx);
|
||||||
if (!lst) {
|
if (!lst) {
|
||||||
g_warning ("no matching attachments found");
|
g_warning ("no matching attachments found");
|
||||||
@ -149,9 +155,8 @@ save_part_with_filename (MuMsg *msg, const char *pattern, MuConfig *opts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (cur = lst, rv = TRUE; cur; cur = g_slist_next (cur))
|
for (cur = lst, rv = TRUE; cur; cur = g_slist_next (cur))
|
||||||
rv &= save_part (msg, opts->targetdir,
|
rv = rv && save_part (msg, opts->targetdir,
|
||||||
GPOINTER_TO_UINT(cur->data),
|
GPOINTER_TO_UINT(cur->data), opts);
|
||||||
opts->overwrite, opts->play);
|
|
||||||
g_slist_free (lst);
|
g_slist_free (lst);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
@ -160,12 +165,9 @@ save_part_with_filename (MuMsg *msg, const char *pattern, MuConfig *opts)
|
|||||||
|
|
||||||
|
|
||||||
struct _SaveData {
|
struct _SaveData {
|
||||||
gboolean attachments_only;
|
|
||||||
gboolean result;
|
gboolean result;
|
||||||
guint saved_num;
|
guint saved_num;
|
||||||
const gchar* targetdir;
|
MuConfig *opts;
|
||||||
gboolean overwrite;
|
|
||||||
gboolean play;
|
|
||||||
};
|
};
|
||||||
typedef struct _SaveData SaveData;
|
typedef struct _SaveData SaveData;
|
||||||
|
|
||||||
@ -177,14 +179,13 @@ ignore_part (MuMsg *msg, MuMsgPart *part, SaveData *sd)
|
|||||||
if (!sd->result)
|
if (!sd->result)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* filter out non-attachments if only want attachments */
|
/* only consider leaf parts */
|
||||||
if (sd->attachments_only &&
|
if (!(part->part_type & MU_MSG_PART_TYPE_LEAF))
|
||||||
!mu_msg_part_looks_like_attachment (part, TRUE))
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* ignore multiparts */
|
/* filter out non-attachments? */
|
||||||
if (part->type &&
|
if (!sd->opts->save_all &&
|
||||||
g_ascii_strcasecmp (part->type, "multipart") == 0)
|
!(mu_msg_part_looks_like_attachment (part, TRUE)))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -197,23 +198,26 @@ save_part_if (MuMsg *msg, MuMsgPart *part, SaveData *sd)
|
|||||||
gchar *filepath;
|
gchar *filepath;
|
||||||
gboolean rv;
|
gboolean rv;
|
||||||
GError *err;
|
GError *err;
|
||||||
|
MuMsgOptions msgopts;
|
||||||
|
|
||||||
if (ignore_part (msg, part, sd))
|
if (ignore_part (msg, part, sd))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rv = FALSE;
|
rv = FALSE;
|
||||||
filepath = NULL;
|
filepath = NULL;
|
||||||
|
|
||||||
err = NULL;
|
err = NULL;
|
||||||
filepath = mu_msg_part_filepath (msg, sd->targetdir, part->index, &err);
|
|
||||||
|
msgopts = mu_config_get_msg_options (sd->opts);
|
||||||
|
filepath = mu_msg_part_get_path (msg, msgopts,
|
||||||
|
sd->opts->targetdir,
|
||||||
|
part->index, &err);
|
||||||
if (!filepath)
|
if (!filepath)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (!mu_msg_part_save (msg, filepath, part->index,
|
if (!mu_msg_part_save (msg, msgopts, filepath, part->index, &err))
|
||||||
sd->overwrite, FALSE, &err))
|
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (sd->play)
|
if (sd->opts->play)
|
||||||
rv = mu_util_play (filepath, TRUE, FALSE, &err);
|
rv = mu_util_play (filepath, TRUE, FALSE, &err);
|
||||||
else
|
else
|
||||||
rv = TRUE;
|
rv = TRUE;
|
||||||
@ -225,30 +229,28 @@ exit:
|
|||||||
|
|
||||||
g_free (filepath);
|
g_free (filepath);
|
||||||
g_clear_error (&err);
|
g_clear_error (&err);
|
||||||
|
|
||||||
sd->result = rv;
|
sd->result = rv;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
save_certain_parts (MuMsg *msg, gboolean attachments_only,
|
save_certain_parts (MuMsg *msg, MuConfig *opts)
|
||||||
const gchar *targetdir, gboolean overwrite, gboolean play)
|
|
||||||
{
|
{
|
||||||
SaveData sd;
|
SaveData sd;
|
||||||
|
MuMsgOptions msgopts;
|
||||||
|
|
||||||
sd.result = TRUE;
|
sd.result = TRUE;
|
||||||
sd.saved_num = 0;
|
sd.saved_num = 0;
|
||||||
sd.attachments_only = attachments_only;
|
sd.opts = opts;
|
||||||
sd.overwrite = overwrite;
|
|
||||||
sd.targetdir = targetdir;
|
|
||||||
sd.play = play;
|
|
||||||
|
|
||||||
mu_msg_part_foreach (msg,
|
msgopts = mu_config_get_msg_options (opts);
|
||||||
(MuMsgPartForeachFunc)save_part_if,
|
mu_msg_part_foreach (msg, msgopts,
|
||||||
&sd, MU_MSG_OPTION_NONE);
|
(MuMsgPartForeachFunc)save_part_if, &sd);
|
||||||
|
|
||||||
if (sd.saved_num == 0) {
|
if (sd.saved_num == 0) {
|
||||||
g_warning ("no %s extracted from this message",
|
g_warning ("no %s extracted from this message",
|
||||||
attachments_only ? "attachments" : "parts");
|
opts->save_attachments ? "attachments" : "parts");
|
||||||
sd.result = FALSE;
|
sd.result = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,16 +283,8 @@ save_parts (const char *path, const char *filename, MuConfig *opts)
|
|||||||
rv = save_numbered_parts (msg, opts);
|
rv = save_numbered_parts (msg, opts);
|
||||||
else if (filename)
|
else if (filename)
|
||||||
rv = save_part_with_filename (msg, filename, opts);
|
rv = save_part_with_filename (msg, filename, opts);
|
||||||
else if (opts->save_attachments) /* all attachments */
|
|
||||||
rv = save_certain_parts (msg, TRUE,
|
|
||||||
opts->targetdir, opts->overwrite,
|
|
||||||
opts->play);
|
|
||||||
else if (opts->save_all) /* all parts */
|
|
||||||
rv = save_certain_parts (msg, FALSE,
|
|
||||||
opts->targetdir, opts->overwrite,
|
|
||||||
opts->play);
|
|
||||||
else
|
else
|
||||||
g_assert_not_reached ();
|
rv = save_certain_parts (msg, opts);
|
||||||
|
|
||||||
mu_msg_unref (msg);
|
mu_msg_unref (msg);
|
||||||
|
|
||||||
@ -299,6 +293,16 @@ save_parts (const char *path, const char *filename, MuConfig *opts)
|
|||||||
|
|
||||||
#define color_maybe(C) do{ if (color) fputs ((C),stdout);}while(0)
|
#define color_maybe(C) do{ if (color) fputs ((C),stdout);}while(0)
|
||||||
|
|
||||||
|
static const char*
|
||||||
|
disp_str (MuMsgPartType ptype)
|
||||||
|
{
|
||||||
|
if (ptype & MU_MSG_PART_TYPE_ATTACHMENT)
|
||||||
|
return "attach";
|
||||||
|
if (ptype & MU_MSG_PART_TYPE_INLINE)
|
||||||
|
return "inline";
|
||||||
|
return "<none>";
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
each_part_show (MuMsg *msg, MuMsgPart *part, gboolean color)
|
each_part_show (MuMsg *msg, MuMsgPart *part, gboolean color)
|
||||||
{
|
{
|
||||||
@ -306,9 +310,12 @@ each_part_show (MuMsg *msg, MuMsgPart *part, gboolean color)
|
|||||||
g_print (" %u ", part->index);
|
g_print (" %u ", part->index);
|
||||||
|
|
||||||
/* filename */
|
/* filename */
|
||||||
color_maybe (MU_COLOR_GREEN);
|
color_maybe (MU_COLOR_GREEN); {
|
||||||
mu_util_fputs_encoded (part->file_name ? part->file_name : "<none>",
|
gchar *fname;
|
||||||
stdout);
|
fname = mu_msg_part_get_filename (part, FALSE);
|
||||||
|
mu_util_fputs_encoded (fname ? fname : "<none>", stdout);
|
||||||
|
g_free (fname);
|
||||||
|
}
|
||||||
/* content-type */
|
/* content-type */
|
||||||
color_maybe (MU_COLOR_BLUE);
|
color_maybe (MU_COLOR_BLUE);
|
||||||
mu_util_print_encoded (
|
mu_util_print_encoded (
|
||||||
@ -316,11 +323,9 @@ each_part_show (MuMsg *msg, MuMsgPart *part, gboolean color)
|
|||||||
part->type ? part->type : "<none>",
|
part->type ? part->type : "<none>",
|
||||||
part->subtype ? part->subtype : "<none>");
|
part->subtype ? part->subtype : "<none>");
|
||||||
|
|
||||||
/* disposition */
|
/* /\* disposition *\/ */
|
||||||
color_maybe (MU_COLOR_MAGENTA);
|
color_maybe (MU_COLOR_MAGENTA);
|
||||||
mu_util_print_encoded (
|
mu_util_print_encoded ("[%s]", disp_str(part->part_type));
|
||||||
"[%s]", part->disposition ? part->disposition : "<none>");
|
|
||||||
|
|
||||||
|
|
||||||
/* size */
|
/* size */
|
||||||
if (part->size > 0) {
|
if (part->size > 0) {
|
||||||
@ -336,18 +341,21 @@ each_part_show (MuMsg *msg, MuMsgPart *part, gboolean color)
|
|||||||
static gboolean
|
static gboolean
|
||||||
show_parts (const char* path, MuConfig *opts, GError **err)
|
show_parts (const char* path, MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
MuMsg* msg;
|
MuMsg *msg;
|
||||||
|
MuMsgOptions msgopts;
|
||||||
|
|
||||||
msg = mu_msg_new_from_file (path, NULL, err);
|
msg = mu_msg_new_from_file (path, NULL, err);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
g_print ("MIME-parts in this message:\n");
|
msgopts = mu_config_get_msg_options (opts);
|
||||||
|
|
||||||
|
/* TODO: update this for crypto */
|
||||||
|
g_print ("MIME-parts in this message:\n");
|
||||||
mu_msg_part_foreach
|
mu_msg_part_foreach
|
||||||
(msg, (MuMsgPartForeachFunc)each_part_show,
|
(msg, msgopts,
|
||||||
GUINT_TO_POINTER(!opts->nocolor),
|
(MuMsgPartForeachFunc)each_part_show,
|
||||||
MU_MSG_OPTION_NONE);
|
GUINT_TO_POINTER(!opts->nocolor));
|
||||||
|
|
||||||
mu_msg_unref (msg);
|
mu_msg_unref (msg);
|
||||||
|
|
||||||
@ -370,8 +378,8 @@ check_params (MuConfig *opts)
|
|||||||
|
|
||||||
if (opts->save_attachments || opts->save_all)
|
if (opts->save_attachments || opts->save_all)
|
||||||
if (opts->parts || param_num == 3) {
|
if (opts->parts || param_num == 3) {
|
||||||
g_warning ("--save-attachments --save-all don't accept "
|
g_warning ("--save-attachments and --save-all don't "
|
||||||
"a filename pattern or --parts");
|
"accept a filename pattern or --parts");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,7 +413,8 @@ mu_cmd_extract (MuConfig *opts, GError **err)
|
|||||||
else {
|
else {
|
||||||
rv = mu_util_check_dir(opts->targetdir, FALSE, TRUE);
|
rv = mu_util_check_dir(opts->targetdir, FALSE, TRUE);
|
||||||
if (!rv)
|
if (!rv)
|
||||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE_CANNOT_WRITE,
|
mu_util_g_set_error
|
||||||
|
(err, MU_ERROR_FILE_CANNOT_WRITE,
|
||||||
"target '%s' is not a writable directory",
|
"target '%s' is not a writable directory",
|
||||||
opts->targetdir);
|
opts->targetdir);
|
||||||
else
|
else
|
||||||
|
|||||||
@ -421,18 +421,17 @@ each_part (MuMsg *msg, MuMsgPart *part, GSList **attlist)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
err = NULL;
|
err = NULL;
|
||||||
cachefile = mu_msg_part_save_temp (msg, part->index, &err);
|
cachefile = mu_msg_part_save_temp (msg,
|
||||||
|
MU_MSG_OPTION_NONE,
|
||||||
|
part->index, &err);
|
||||||
if (!cachefile) {
|
if (!cachefile) {
|
||||||
print_and_clear_g_error (&err);
|
print_and_clear_g_error (&err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
att = g_strdup_printf (
|
att = g_strdup_printf (
|
||||||
"(:file-name \"%s\" :mime-type \"%s/%s\" "
|
"(:file-name \"%s\" :mime-type \"%s/%s\")",
|
||||||
":disposition \"%s\")",
|
cachefile, part->type, part->subtype);
|
||||||
cachefile,
|
|
||||||
part->type, part->subtype,
|
|
||||||
part->disposition ? part->disposition : "attachment");
|
|
||||||
*attlist = g_slist_append (*attlist, att);
|
*attlist = g_slist_append (*attlist, att);
|
||||||
g_free (cachefile);
|
g_free (cachefile);
|
||||||
}
|
}
|
||||||
@ -452,8 +451,9 @@ include_attachments (MuMsg *msg)
|
|||||||
GString *gstr;
|
GString *gstr;
|
||||||
|
|
||||||
attlist = NULL;
|
attlist = NULL;
|
||||||
mu_msg_part_foreach (msg, (MuMsgPartForeachFunc)each_part,
|
mu_msg_part_foreach (msg, MU_MSG_OPTION_NONE,
|
||||||
&attlist, MU_MSG_OPTION_NONE);
|
(MuMsgPartForeachFunc)each_part,
|
||||||
|
&attlist);
|
||||||
|
|
||||||
gstr = g_string_sized_new (512);
|
gstr = g_string_sized_new (512);
|
||||||
gstr = g_string_append_c (gstr, '(');
|
gstr = g_string_append_c (gstr, '(');
|
||||||
@ -676,8 +676,8 @@ save_part (MuMsg *msg, unsigned index, GSList *args, GError **err)
|
|||||||
|
|
||||||
GET_STRING_OR_ERROR_RETURN (args, "path", &path, err);
|
GET_STRING_OR_ERROR_RETURN (args, "path", &path, err);
|
||||||
|
|
||||||
rv = mu_msg_part_save (msg, path, index,
|
rv = mu_msg_part_save (msg, MU_MSG_OPTION_OVERWRITE,
|
||||||
TRUE/*overwrite*/, FALSE/*use cache*/, err);
|
path, index, err);
|
||||||
if (!rv) {
|
if (!rv) {
|
||||||
print_and_clear_g_error (err);
|
print_and_clear_g_error (err);
|
||||||
return MU_OK;
|
return MU_OK;
|
||||||
@ -698,15 +698,19 @@ open_part (MuMsg *msg, unsigned index, GError **err)
|
|||||||
char *targetpath;
|
char *targetpath;
|
||||||
gboolean rv;
|
gboolean rv;
|
||||||
|
|
||||||
targetpath = mu_msg_part_filepath_cache (msg, index);
|
targetpath = mu_msg_part_get_cache_path (msg,MU_MSG_OPTION_NONE,
|
||||||
rv = mu_msg_part_save (msg, targetpath, index,
|
index, err);
|
||||||
FALSE/*overwrite*/, TRUE/*use cache*/, err);
|
if (!targetpath)
|
||||||
|
return print_and_clear_g_error (err);
|
||||||
|
|
||||||
|
rv = mu_msg_part_save (msg, MU_MSG_OPTION_USE_EXISTING,
|
||||||
|
targetpath, index, err);
|
||||||
if (!rv) {
|
if (!rv) {
|
||||||
print_and_clear_g_error (err);
|
print_and_clear_g_error (err);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = mu_util_play (targetpath, TRUE/*allow local*/,
|
rv = mu_util_play (targetpath, TRUE,/*allow local*/
|
||||||
FALSE/*allow remote*/, err);
|
FALSE/*allow remote*/, err);
|
||||||
if (!rv)
|
if (!rv)
|
||||||
print_and_clear_g_error (err);
|
print_and_clear_g_error (err);
|
||||||
@ -732,9 +736,11 @@ temp_part (MuMsg *msg, unsigned index, GSList *args, GError **err)
|
|||||||
GET_STRING_OR_ERROR_RETURN (args, "what", &what, err);
|
GET_STRING_OR_ERROR_RETURN (args, "what", &what, err);
|
||||||
GET_STRING_OR_ERROR_RETURN (args, "param", ¶m, err);
|
GET_STRING_OR_ERROR_RETURN (args, "param", ¶m, err);
|
||||||
|
|
||||||
path = mu_msg_part_filepath_cache (msg, index);
|
path = mu_msg_part_get_cache_path (msg, MU_MSG_OPTION_NONE, index, err);
|
||||||
if (!mu_msg_part_save (msg, path, index,
|
if (!path)
|
||||||
FALSE/*overwrite*/, TRUE/*use cache*/, err))
|
print_and_clear_g_error (err);
|
||||||
|
else if (!mu_msg_part_save (msg, MU_MSG_OPTION_USE_EXISTING,
|
||||||
|
path, index, err))
|
||||||
print_and_clear_g_error (err);
|
print_and_clear_g_error (err);
|
||||||
else {
|
else {
|
||||||
gchar *escpath, *escparam;
|
gchar *escpath, *escparam;
|
||||||
@ -1346,17 +1352,16 @@ cmd_view (ServerContext *ctx, GSList *args, GError **err)
|
|||||||
unsigned docid;
|
unsigned docid;
|
||||||
char *sexp;
|
char *sexp;
|
||||||
MuMsgOptions opts;
|
MuMsgOptions opts;
|
||||||
gboolean decrypt;
|
|
||||||
|
|
||||||
opts = MU_MSG_OPTION_CHECK_SIGNATURES;
|
opts = MU_MSG_OPTION_VERIFY;
|
||||||
if (get_bool_from_args (args, "extract-images", FALSE, err))
|
if (get_bool_from_args (args, "extract-images", FALSE, NULL))
|
||||||
opts |= MU_MSG_OPTION_EXTRACT_IMAGES;
|
opts |= MU_MSG_OPTION_EXTRACT_IMAGES;
|
||||||
if (get_bool_from_args (args, "use-agent", FALSE, NULL))
|
if (get_bool_from_args (args, "use-agent", FALSE, NULL))
|
||||||
opts |= MU_MSG_OPTION_USE_AGENT;
|
opts |= MU_MSG_OPTION_USE_AGENT;
|
||||||
if (get_bool_from_args (args, "auto-retrieve-key", FALSE, NULL))
|
if (get_bool_from_args (args, "auto-retrieve-key", FALSE, NULL))
|
||||||
opts |= MU_MSG_OPTION_AUTO_RETRIEVE_KEY;
|
opts |= MU_MSG_OPTION_AUTO_RETRIEVE;
|
||||||
|
if (get_bool_from_args (args, "extract-encrypted", FALSE, NULL))
|
||||||
decrypt = get_bool_from_args (args, "extract-encrypted", FALSE, err);
|
opts |= MU_MSG_OPTION_DECRYPT;
|
||||||
|
|
||||||
docid = determine_docid (ctx->query, args, err);
|
docid = determine_docid (ctx->query, args, err);
|
||||||
if (docid == MU_STORE_INVALID_DOCID) {
|
if (docid == MU_STORE_INVALID_DOCID) {
|
||||||
@ -1370,7 +1375,6 @@ cmd_view (ServerContext *ctx, GSList *args, GError **err)
|
|||||||
return MU_OK;
|
return MU_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
mu_msg_set_auto_decrypt (msg, decrypt);
|
|
||||||
sexp = mu_msg_to_sexp (msg, docid, NULL, opts);
|
sexp = mu_msg_to_sexp (msg, docid, NULL, opts);
|
||||||
mu_msg_unref (msg);
|
mu_msg_unref (msg);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user