diff --git a/lib/mu-msg-crypto.c b/lib/mu-msg-crypto.c index 005d43b3..ba414b49 100644 --- a/lib/mu-msg-crypto.c +++ b/lib/mu-msg-crypto.c @@ -29,7 +29,6 @@ #include "mu-msg-crypto.h" #include "mu-date.h" - #include #include @@ -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"); diff --git a/lib/mu-msg-crypto.h b/lib/mu-msg-crypto.h index ac2eb4e3..7d1b8e4a 100644 --- a/lib/mu-msg-crypto.h +++ b/lib/mu-msg-crypto.h @@ -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__*/ diff --git a/lib/mu-msg-sexp.c b/lib/mu-msg-sexp.c index 05d788b1..da82d4bf 100644 --- a/lib/mu-msg-sexp.c +++ b/lib/mu-msg-sexp.c @@ -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); diff --git a/lib/mu-msg.c b/lib/mu-msg.c index a6d8aaf6..bbb9cdfb 100644 --- a/lib/mu-msg.c +++ b/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 * regress...*/ static const char* diff --git a/lib/mu-msg.h b/lib/mu-msg.h index b1299c8a..23298399 100644 --- a/lib/mu-msg.h +++ b/lib/mu-msg.h @@ -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 diff --git a/lib/mu-store-write.cc b/lib/mu-store-write.cc index 773ac969..513b188b 100644 --- a/lib/mu-store-write.cc +++ b/lib/mu-store-write.cc @@ -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); } diff --git a/mu/mu-cmd-extract.c b/mu/mu-cmd-extract.c index de873d9f..638a9e21 100644 --- a/mu/mu-cmd-extract.c +++ b/mu/mu-cmd-extract.c @@ -32,33 +32,37 @@ #include "mu-util.h" #include "mu-str.h" + + static gboolean -save_part (MuMsg *msg, const char *targetdir, guint partidx, gboolean overwrite, - gboolean play) +save_part (MuMsg *msg, const char *targetdir, guint partidx, MuConfig *opts) { GError *err; gchar *filepath; gboolean rv; + MuMsgOptions msgopts; err = NULL; 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) 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; - if (play) + if (opts->play) rv = mu_util_play (filepath, TRUE, FALSE, &err); else rv = TRUE; exit: - if (err) - g_warning ("error with MIME-part: %s", - err->message); - g_clear_error (&err); + if (err) { + g_warning ("error with MIME-part: %s", err->message); + g_clear_error (&err); + } g_free (filepath); return rv; @@ -87,8 +91,7 @@ save_numbered_parts (MuMsg *msg, MuConfig *opts) break; } - if (!save_part (msg, opts->targetdir, idx, opts->overwrite, - opts->play)) { + if (!save_part (msg, opts->targetdir, idx, opts)) { g_warning ("failed to save MIME-part %d", idx); rv = FALSE; break; @@ -135,13 +138,16 @@ save_part_with_filename (MuMsg *msg, const char *pattern, MuConfig *opts) GSList *lst, *cur; GRegex *rx; gboolean rv; + MuMsgOptions msgopts; + + msgopts = mu_config_get_msg_options (opts); /* 'anchor' the pattern with '^...$' if not already */ rx = anchored_regex (pattern); if (!rx) return FALSE; - lst = mu_msg_part_find_files (msg, rx); + lst = mu_msg_find_files (msg, msgopts, rx); g_regex_unref (rx); if (!lst) { 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)) - rv &= save_part (msg, opts->targetdir, - GPOINTER_TO_UINT(cur->data), - opts->overwrite, opts->play); + rv = rv && save_part (msg, opts->targetdir, + GPOINTER_TO_UINT(cur->data), opts); g_slist_free (lst); return rv; @@ -160,12 +165,9 @@ save_part_with_filename (MuMsg *msg, const char *pattern, MuConfig *opts) struct _SaveData { - gboolean attachments_only; gboolean result; guint saved_num; - const gchar* targetdir; - gboolean overwrite; - gboolean play; + MuConfig *opts; }; typedef struct _SaveData SaveData; @@ -177,14 +179,13 @@ ignore_part (MuMsg *msg, MuMsgPart *part, SaveData *sd) if (!sd->result) return TRUE; - /* filter out non-attachments if only want attachments */ - if (sd->attachments_only && - !mu_msg_part_looks_like_attachment (part, TRUE)) + /* only consider leaf parts */ + if (!(part->part_type & MU_MSG_PART_TYPE_LEAF)) return TRUE; - /* ignore multiparts */ - if (part->type && - g_ascii_strcasecmp (part->type, "multipart") == 0) + /* filter out non-attachments? */ + if (!sd->opts->save_all && + !(mu_msg_part_looks_like_attachment (part, TRUE))) return TRUE; return FALSE; @@ -197,23 +198,26 @@ save_part_if (MuMsg *msg, MuMsgPart *part, SaveData *sd) gchar *filepath; gboolean rv; GError *err; + MuMsgOptions msgopts; if (ignore_part (msg, part, sd)) return; rv = FALSE; 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) goto exit; - if (!mu_msg_part_save (msg, filepath, part->index, - sd->overwrite, FALSE, &err)) + if (!mu_msg_part_save (msg, msgopts, filepath, part->index, &err)) goto exit; - if (sd->play) + if (sd->opts->play) rv = mu_util_play (filepath, TRUE, FALSE, &err); else rv = TRUE; @@ -225,30 +229,28 @@ exit: g_free (filepath); g_clear_error (&err); + sd->result = rv; } static gboolean -save_certain_parts (MuMsg *msg, gboolean attachments_only, - const gchar *targetdir, gboolean overwrite, gboolean play) +save_certain_parts (MuMsg *msg, MuConfig *opts) { SaveData sd; + MuMsgOptions msgopts; sd.result = TRUE; sd.saved_num = 0; - sd.attachments_only = attachments_only; - sd.overwrite = overwrite; - sd.targetdir = targetdir; - sd.play = play; + sd.opts = opts; - mu_msg_part_foreach (msg, - (MuMsgPartForeachFunc)save_part_if, - &sd, MU_MSG_OPTION_NONE); + msgopts = mu_config_get_msg_options (opts); + mu_msg_part_foreach (msg, msgopts, + (MuMsgPartForeachFunc)save_part_if, &sd); if (sd.saved_num == 0) { g_warning ("no %s extracted from this message", - attachments_only ? "attachments" : "parts"); + opts->save_attachments ? "attachments" : "parts"); sd.result = FALSE; } @@ -281,16 +283,8 @@ save_parts (const char *path, const char *filename, MuConfig *opts) rv = save_numbered_parts (msg, opts); else if (filename) 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 - g_assert_not_reached (); + rv = save_certain_parts (msg, opts); 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) +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 ""; +} + static void 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); /* filename */ - color_maybe (MU_COLOR_GREEN); - mu_util_fputs_encoded (part->file_name ? part->file_name : "", - stdout); + color_maybe (MU_COLOR_GREEN); { + gchar *fname; + fname = mu_msg_part_get_filename (part, FALSE); + mu_util_fputs_encoded (fname ? fname : "", stdout); + g_free (fname); + } /* content-type */ color_maybe (MU_COLOR_BLUE); mu_util_print_encoded ( @@ -316,11 +323,9 @@ each_part_show (MuMsg *msg, MuMsgPart *part, gboolean color) part->type ? part->type : "", part->subtype ? part->subtype : ""); - /* disposition */ + /* /\* disposition *\/ */ color_maybe (MU_COLOR_MAGENTA); - mu_util_print_encoded ( - "[%s]", part->disposition ? part->disposition : ""); - + mu_util_print_encoded ("[%s]", disp_str(part->part_type)); /* size */ if (part->size > 0) { @@ -336,18 +341,21 @@ each_part_show (MuMsg *msg, MuMsgPart *part, gboolean color) static gboolean show_parts (const char* path, MuConfig *opts, GError **err) { - MuMsg* msg; + MuMsg *msg; + MuMsgOptions msgopts; msg = mu_msg_new_from_file (path, NULL, err); if (!msg) 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 - (msg, (MuMsgPartForeachFunc)each_part_show, - GUINT_TO_POINTER(!opts->nocolor), - MU_MSG_OPTION_NONE); + (msg, msgopts, + (MuMsgPartForeachFunc)each_part_show, + GUINT_TO_POINTER(!opts->nocolor)); mu_msg_unref (msg); @@ -370,8 +378,8 @@ check_params (MuConfig *opts) if (opts->save_attachments || opts->save_all) if (opts->parts || param_num == 3) { - g_warning ("--save-attachments --save-all don't accept " - "a filename pattern or --parts"); + g_warning ("--save-attachments and --save-all don't " + "accept a filename pattern or --parts"); return FALSE; } @@ -405,9 +413,10 @@ mu_cmd_extract (MuConfig *opts, GError **err) else { rv = mu_util_check_dir(opts->targetdir, FALSE, TRUE); if (!rv) - g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE_CANNOT_WRITE, - "target '%s' is not a writable directory", - opts->targetdir); + mu_util_g_set_error + (err, MU_ERROR_FILE_CANNOT_WRITE, + "target '%s' is not a writable directory", + opts->targetdir); else rv = save_parts (opts->params[1], opts->params[2], diff --git a/mu/mu-cmd-server.c b/mu/mu-cmd-server.c index 309c9f2c..b8751343 100644 --- a/mu/mu-cmd-server.c +++ b/mu/mu-cmd-server.c @@ -421,18 +421,17 @@ each_part (MuMsg *msg, MuMsgPart *part, GSList **attlist) return; 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) { print_and_clear_g_error (&err); return; } att = g_strdup_printf ( - "(:file-name \"%s\" :mime-type \"%s/%s\" " - ":disposition \"%s\")", - cachefile, - part->type, part->subtype, - part->disposition ? part->disposition : "attachment"); + "(:file-name \"%s\" :mime-type \"%s/%s\")", + cachefile, part->type, part->subtype); *attlist = g_slist_append (*attlist, att); g_free (cachefile); } @@ -452,8 +451,9 @@ include_attachments (MuMsg *msg) GString *gstr; attlist = NULL; - mu_msg_part_foreach (msg, (MuMsgPartForeachFunc)each_part, - &attlist, MU_MSG_OPTION_NONE); + mu_msg_part_foreach (msg, MU_MSG_OPTION_NONE, + (MuMsgPartForeachFunc)each_part, + &attlist); gstr = g_string_sized_new (512); 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); - rv = mu_msg_part_save (msg, path, index, - TRUE/*overwrite*/, FALSE/*use cache*/, err); + rv = mu_msg_part_save (msg, MU_MSG_OPTION_OVERWRITE, + path, index, err); if (!rv) { print_and_clear_g_error (err); return MU_OK; @@ -698,15 +698,19 @@ open_part (MuMsg *msg, unsigned index, GError **err) char *targetpath; gboolean rv; - targetpath = mu_msg_part_filepath_cache (msg, index); - rv = mu_msg_part_save (msg, targetpath, index, - FALSE/*overwrite*/, TRUE/*use cache*/, err); + targetpath = mu_msg_part_get_cache_path (msg,MU_MSG_OPTION_NONE, + index, 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) { print_and_clear_g_error (err); goto leave; } - rv = mu_util_play (targetpath, TRUE/*allow local*/, + rv = mu_util_play (targetpath, TRUE,/*allow local*/ FALSE/*allow remote*/, err); if (!rv) 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, "param", ¶m, err); - path = mu_msg_part_filepath_cache (msg, index); - if (!mu_msg_part_save (msg, path, index, - FALSE/*overwrite*/, TRUE/*use cache*/, err)) + path = mu_msg_part_get_cache_path (msg, MU_MSG_OPTION_NONE, index, err); + if (!path) + 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); else { gchar *escpath, *escparam; @@ -1346,17 +1352,16 @@ cmd_view (ServerContext *ctx, GSList *args, GError **err) unsigned docid; char *sexp; MuMsgOptions opts; - gboolean decrypt; - opts = MU_MSG_OPTION_CHECK_SIGNATURES; - if (get_bool_from_args (args, "extract-images", FALSE, err)) + opts = MU_MSG_OPTION_VERIFY; + if (get_bool_from_args (args, "extract-images", FALSE, NULL)) opts |= MU_MSG_OPTION_EXTRACT_IMAGES; if (get_bool_from_args (args, "use-agent", FALSE, NULL)) opts |= MU_MSG_OPTION_USE_AGENT; if (get_bool_from_args (args, "auto-retrieve-key", FALSE, NULL)) - opts |= MU_MSG_OPTION_AUTO_RETRIEVE_KEY; - - decrypt = get_bool_from_args (args, "extract-encrypted", FALSE, err); + opts |= MU_MSG_OPTION_AUTO_RETRIEVE; + if (get_bool_from_args (args, "extract-encrypted", FALSE, NULL)) + opts |= MU_MSG_OPTION_DECRYPT; docid = determine_docid (ctx->query, args, err); if (docid == MU_STORE_INVALID_DOCID) { @@ -1370,7 +1375,6 @@ cmd_view (ServerContext *ctx, GSList *args, GError **err) return MU_OK; } - mu_msg_set_auto_decrypt (msg, decrypt); sexp = mu_msg_to_sexp (msg, docid, NULL, opts); mu_msg_unref (msg);