* updates for mu-msg-part changes

This commit is contained in:
djcb
2012-08-01 17:02:43 +03:00
parent 536665d126
commit 67a9282fc9
8 changed files with 194 additions and 312 deletions

View File

@ -29,7 +29,6 @@
#include "mu-msg-crypto.h"
#include "mu-date.h"
#include <gmime/gmime.h>
#include <gmime/gmime-multipart-signed.h>
@ -117,17 +116,11 @@ get_gpg_crypto_context (MuMsgOptions opts, GError **err)
return NULL;
}
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
/* always try to use the agent */
g_mime_gpg_context_set_use_agent (GMIME_GPG_CONTEXT(cctx), TRUE);
g_mime_gpg_context_set_auto_key_retrieve
(GMIME_GPG_CONTEXT(cctx),
opts & MU_MSG_OPTION_AUTO_RETRIEVE_KEY ? TRUE:FALSE);
g_mime_gpg_context_set_always_trust
(GMIME_GPG_CONTEXT(cctx), FALSE);
opts & MU_MSG_OPTION_AUTO_RETRIEVE ? TRUE:FALSE);
return cctx;
}
@ -532,6 +525,7 @@ mu_msg_part_sig_info_to_string (MuMsgPartSigInfo *info)
GMimeObject* /* this is declared in mu-msg-priv.h */
mu_msg_crypto_decrypt_part (GMimeMultipartEncrypted *enc, MuMsgOptions opts,
MuMsgPartPasswordFunc func, gpointer user_data,
GError **err)
{
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);
ctx = get_crypto_context (opts, NULL, NULL, err);
ctx = get_crypto_context (opts, func, user_data, err);
if (!ctx) {
mu_util_g_set_error (err, MU_ERROR_CRYPTO,
"failed to get crypto context");

View File

@ -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);
/**
* 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);
/*
* below function only do anything useful if mu was built with crypto
* support
*/
struct _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__*/

View File

@ -117,23 +117,18 @@ each_contact (MuMsgContact *c, ContactData *cdata)
case MU_MSG_CONTACT_TYPE_FROM:
add_prefix_maybe (cdata->gstr, &cdata->from, "\t:from (");
break;
case MU_MSG_CONTACT_TYPE_TO:
add_prefix_maybe (cdata->gstr, &cdata->to, "\t:to (");
break;
case MU_MSG_CONTACT_TYPE_CC:
add_prefix_maybe (cdata->gstr, &cdata->cc, "\t:cc (");
break;
case MU_MSG_CONTACT_TYPE_BCC:
add_prefix_maybe (cdata->gstr, &cdata->bcc, "\t:bcc (");
break;
case MU_MSG_CONTACT_TYPE_REPLY_TO:
add_prefix_maybe (cdata->gstr, &cdata->reply_to, "\t:reply-to (");
break;
default: g_return_val_if_reached (FALSE);
}
@ -203,23 +198,27 @@ append_sexp_flags (GString *gstr, MuMsg *msg)
}
static char*
get_temp_file (MuMsg *msg, unsigned index)
get_temp_file (MuMsg *msg, MuMsgOptions opts, unsigned index)
{
char *path;
GError *err;
err = NULL;
path = mu_msg_part_filepath_cache (msg, index);
if (!mu_msg_part_save (msg, path, index,
FALSE/*overwrite*/, TRUE/*use cache*/, &err)) {
g_warning ("failed to save mime part: %s",
err->message ? err->message : "something went wrong");
g_clear_error (&err);
g_free (path);
return NULL;
}
path = mu_msg_part_get_cache_path (msg, opts, index, &err);
if (!path)
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",
err->message ? err->message : "something went wrong");
g_clear_error (&err);
g_free (path);
return NULL;
}
@ -232,7 +231,7 @@ get_temp_file_maybe (MuMsg *msg, MuMsgPart *part, MuMsgOptions opts)
g_ascii_strcasecmp (part->type, "image") != 0)
return NULL;
tmp = get_temp_file (msg, part->index);
tmp = get_temp_file (msg, opts, part->index);
if (!tmp)
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 *
get_part_type_string (MuMsgPartType ptype)
{
@ -348,16 +321,16 @@ each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo)
char *name, *tmp, *parttype;
char *tmpfile;
name = get_part_filename (part);
name = mu_msg_part_get_filename (part, TRUE);
tmpfile = get_temp_file_maybe (msg, part, pinfo->opts);
parttype = get_part_type_string (part->part_type);
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 "
":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->subtype, "octet-stream"),
tmpfile ? " :temp" : "", tmpfile ? tmpfile : "",
@ -379,28 +352,16 @@ append_sexp_parts (GString *gstr, MuMsg *msg, MuMsgOptions opts)
pinfo.parts = NULL;
pinfo.opts = opts;
mu_msg_part_foreach (msg, (MuMsgPartForeachFunc)each_part,
&pinfo, opts);
if (pinfo.parts) {
if (!mu_msg_part_foreach (msg, opts, (MuMsgPartForeachFunc)each_part,
&pinfo)) {
/* 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_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
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" : "");
}
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_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));
/* 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);
/* weird time format for emacs 29-bit ints...*/
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
* view), not from the database (mu find). */
if (!(opts & MU_MSG_OPTION_HEADERS_ONLY))
append_non_headers_only_attr (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);
append_message_file_parts (gstr, msg, opts);
g_string_append (gstr, ")\n");
return g_string_free (gstr, FALSE);

View File

@ -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
* regress...*/
static const char*

View File

@ -43,10 +43,19 @@ enum _MuMsgOptions {
/* below options are for checking signatures; only effective
* if mu was built with crypto support */
MU_MSG_OPTION_CHECK_SIGNATURES = 1 << 4,
MU_MSG_OPTION_AUTO_RETRIEVE_KEY = 1 << 5,
MU_MSG_OPTION_VERIFY = 1 << 4,
MU_MSG_OPTION_AUTO_RETRIEVE = 1 << 5,
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;
@ -135,30 +144,6 @@ MuMsg *mu_msg_ref (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
* backend anymore
@ -223,7 +208,6 @@ const char* mu_msg_get_to (MuMsg *msg);
*/
const char* mu_msg_get_cc (MuMsg *msg);
/**
* get the blind carbon-copy recipients (Bcc:) of this message; this
* field usually only appears in outgoing messages

View File

@ -382,18 +382,26 @@ struct PartData {
GStringChunk *_strchunk;
};
static gboolean
/* index non-body text parts */
static void
maybe_index_text_part (MuMsg *msg, MuMsgPart *part, PartData *pdata)
{
gboolean err;
char *txt, *norm;
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)
return FALSE;
return;
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));
g_free (txt);
return TRUE;
}
static void
each_part (MuMsg *msg, MuMsgPart *part, PartData *pdata)
{
char *fname;
static const std::string
file (prefix(MU_MSG_FIELD_ID_FILE)),
mime (prefix(MU_MSG_FIELD_ID_MIME));
@ -430,21 +438,18 @@ each_part (MuMsg *msg, MuMsgPart *part, PartData *pdata)
(mime + std::string(ctype, 0, MuStore::MAX_TERM_LENGTH));
}
/* save the name of anything that has a filename */
if (part->file_name) {
/* now, let's create a term it there's a filename. allocated
* on strchunk, no need to free*/
if ((fname = mu_msg_part_get_filename (part, FALSE))) {
char *val;
/* now, let's create a term... allocated on strchunk,
* no need to free*/
val = mu_str_xapian_escape (part->file_name, TRUE /*esc space*/,
val = mu_str_xapian_escape (fname, TRUE /*esc space*/,
pdata->_strchunk);
g_free (fname);
pdata->_doc.add_term
(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)
{
PartData pdata (doc, mfid, strchunk);
mu_msg_part_foreach (msg,
(MuMsgPartForeachFunc)each_part, &pdata,
MU_MSG_OPTION_NONE);
mu_msg_part_foreach (msg, MU_MSG_OPTION_NONE,
(MuMsgPartForeachFunc)each_part, &pdata);
}