diff --git a/mu/mu-cmd.c b/mu/mu-cmd.c index 83ee88c0..461e4479 100644 --- a/mu/mu-cmd.c +++ b/mu/mu-cmd.c @@ -48,7 +48,7 @@ static gboolean -view_msg_sexp (MuMsg *msg) +view_msg_sexp (MuMsg *msg, MuConfig *opts) { char *sexp; @@ -111,40 +111,121 @@ print_field (const char* field, const char *val, gboolean color) fputs ("\n", stdout); } +static char* +get_password (const char *user_id, const char *prompt_ctx, + gboolean reprompt, gpointer user_data) +{ + char *pass, *prompt; + if (reprompt) + g_printerr ("Incorrect password. Please try again\n"); + /* else */ + /* g_print ("mu: %s\n", prompt_ctx); *\/ */ + + prompt = g_strdup_printf ("mu: password for %s: ", user_id); + pass = getpass (prompt); + g_free (prompt); + + return pass; +} + + +struct _DData { + GString *gstr; + GError *err; +}; +typedef struct _DData DData; + +static void +each_decrypted_part (MuMsgDecryptedPart *dpart, DData *ddata) +{ + gchar *str; + + if (ddata->err) + return; + + str = mu_msg_decrypted_part_to_string (dpart, + &ddata->err); + ddata->gstr = g_string_append (ddata->gstr, + str ? str : ""); + g_free (str); +} + + +static gchar* +try_decrypt_body (MuMsg *msg, MuConfig *opts) +{ + DData ddata; + GError *err; + + err = NULL; + ddata.gstr = g_string_sized_new (mu_msg_get_size(msg)); + ddata.err = NULL; + + if (!mu_msg_part_decrypt_foreach + (msg,(MuMsgPartDecryptForeachFunc)each_decrypted_part, + (MuMsgPartPasswordFunc)get_password, + &ddata, MU_MSG_OPTION_USE_AGENT, &err)) + goto errexit; + + if (ddata.err) + goto errexit; + + return g_string_free (ddata.gstr, FALSE); + +errexit: + g_warning ("decryption failed: %s", + err ? err->message : "something went wrong"); + g_clear_error (&err); + return NULL; +} + /* a summary_len of 0 mean 'don't show summary, show body */ static void -body_or_summary (MuMsg *msg, unsigned summary_len, gboolean color) +body_or_summary (MuMsg *msg, MuConfig *opts) { - const char* field; + const char *str; + const char *body; + char *decrypted; + gboolean color; - field = mu_msg_get_body_text (msg); - if (!field) + color = !opts->nocolor; + + str = mu_msg_get_body_text (msg); + decrypted = NULL; + + if (!str && opts->decrypt) + decrypted = try_decrypt_body (msg, opts); + if (!str && !decrypted) return; /* no body -- nothing more to do */ + body = str ? str : decrypted; - if (summary_len != 0) { + if (opts->summary_len != 0) { gchar *summ; - summ = mu_str_summarize (field, summary_len); + summ = mu_str_summarize (body, opts->summary_len); print_field ("Summary", summ, color); g_free (summ); } else { color_maybe (MU_COLOR_YELLOW); - mu_util_print_encoded ("\n%s\n", field); + mu_util_print_encoded ("\n%s\n", body); color_maybe (MU_COLOR_DEFAULT); } + + g_free (decrypted); } /* we ignore fields for now */ /* summary_len == 0 means "no summary */ static gboolean -view_msg_plain (MuMsg *msg, const gchar *fields, unsigned summary_len, - gboolean color) +view_msg_plain (MuMsg *msg, MuConfig *opts) { gchar *attachs; time_t date; const GSList *lst; + gboolean color; + color = !opts->nocolor; print_field ("From", mu_msg_get_from (msg), color); print_field ("To", mu_msg_get_to (msg), color); print_field ("Cc", mu_msg_get_cc (msg), color); @@ -167,7 +248,7 @@ view_msg_plain (MuMsg *msg, const gchar *fields, unsigned summary_len, g_free (attachs); } - body_or_summary (msg, summary_len, color); + body_or_summary (msg, opts); return TRUE; } @@ -186,13 +267,10 @@ handle_msg (const char *fname, MuConfig *opts, GError **err) switch (opts->format) { case MU_CONFIG_FORMAT_PLAIN: - rv = view_msg_plain - (msg, NULL, - opts->summary ? opts->summary_len : 0, - !opts->nocolor); + rv = view_msg_plain (msg, opts); break; case MU_CONFIG_FORMAT_SEXP: - rv = view_msg_sexp (msg); + rv = view_msg_sexp (msg, opts); break; default: g_critical ("bug: should not be reached"); diff --git a/mu/mu-config.c b/mu/mu-config.c index 815e1e61..155d3d81 100644 --- a/mu/mu-config.c +++ b/mu/mu-config.c @@ -302,6 +302,9 @@ config_options_group_view (void) "terminate messages with ascii-0x07 (\\f, form-feed)", NULL}, {"format", 'o', 0, G_OPTION_ARG_STRING, &MU_CONFIG.formatstr, "output format ('plain'(*), 'sexp')", NULL}, + {"decrypt", 0, 0, G_OPTION_ARG_NONE, &MU_CONFIG.decrypt, + "attempt to decrypt the message body, if it is encrypted", NULL}, + {NULL, 0, 0, 0, NULL, NULL, NULL} }; diff --git a/mu/mu-config.h b/mu/mu-config.h index a98f2025..a4781e49 100644 --- a/mu/mu-config.h +++ b/mu/mu-config.h @@ -89,7 +89,6 @@ struct _MuConfig { * MU_CONFIG_CMD_NONE */ const char *cmdstr; /* cmd string, for user * info */ - /* general options */ gboolean quiet; /* don't give any output */ gboolean debug; /* spew out debug info */ @@ -146,6 +145,9 @@ struct _MuConfig { gboolean terminator; /* add separator \f between * multiple messages in mu * view */ + gboolean decrypt; /* try to decrypt the + * message body, if any */ + /* options for cfind (and 'find' --> "after") */ gboolean personal; /* only show 'personal' addresses */ /* also 'after' --> see above */