+ /* Skip over any trailing whitespace. */
+ while (*cp && isspace((unsigned char) *cp)) {
+ ++cp, ++pos;
+ }
+
+ return pos;
+}
+
+
+/*
+ * Check for valid base64 encoding, and "fix" if invalid.
+ */
+static int
+check_base64_encoding (CT *ctp)
+{
+ char *remainder = NULL;
+ int status = OK;
+
+ /* If there's a footer after base64 content, set c_end to before it, and
+ store the footer in remainder. */
+ (*ctp)->c_end = (*ctp)->c_begin + get_valid_base64(*ctp, &remainder);
+
+ if (remainder != NULL) {
+ /* Move ct to a subpart of a new multipart/related, and add the
+ remainder as a new text/plain subpart of it. */
+ int ignore_message_mods = 0;
+
+ status = insert_into_new_mp_mixed(ctp, remainder, &ignore_message_mods);
+ free(remainder);
+ }
+
+ return status;
+}
+
+
+/*
+ * Reformat content as plain text.
+ * Some of the arguments aren't really needed now, but maybe will
+ * be in the future for other than text types.
+ */
+static int
+reformat_part (CT ct, char *file, char *type, char *subtype, int c_type)
+{
+ int output_subtype, output_encoding;
+ const char *reason = NULL;
+ char *cp, *cf;
+ int status;
+
+ /* Hacky: this redirects the output from whatever command is used
+ to show the part to a file. So, the user can't have any output
+ redirection in that command.
+ Could show_multi() in mhshowsbr.c avoid this? */
+
+ /* Check for invo_name-format-type/subtype. */
+ if ((cf = context_find_by_type ("format", type, subtype)) == NULL) {
+ if (verbosw) {
+ inform("Don't know how to convert %s, there is no "
+ "%s-format-%s/%s profile entry",
+ ct->c_file, invo_name, type, subtype);
+ }
+ return NOTOK;
+ }
+ if (strchr (cf, '>')) {
+ inform("'>' prohibited in \"%s\",\nplease fix your "
+ "%s-format-%s/%s profile entry", cf, invo_name, type,
+ FENDNULL(subtype));
+
+ return NOTOK;
+ }
+
+ cp = concat (cf, " >", file, NULL);
+ status = show_content_aux (ct, 0, cp, NULL, NULL);
+ free (cp);
+
+ /* Unlink decoded content tmp file and free its filename to avoid
+ leaks. The file stream should already have been closed. */
+ if (ct->c_cefile.ce_unlink) {
+ (void) m_unlink (ct->c_cefile.ce_file);
+ free (ct->c_cefile.ce_file);
+ ct->c_cefile.ce_file = NULL;
+ ct->c_cefile.ce_unlink = 0;
+ }
+
+ if (c_type == CT_TEXT) {
+ output_subtype = TEXT_PLAIN;
+ } else {
+ /* Set subtype to 0, which is always an UNKNOWN subtype. */
+ output_subtype = 0;
+ }
+
+ output_encoding = content_encoding (ct, &reason);
+ if (status == OK &&
+ set_ct_type (ct, c_type, output_subtype, output_encoding) == OK) {
+ ct->c_cefile.ce_file = file;
+ ct->c_cefile.ce_unlink = 1;
+ } else {
+ ct->c_cefile.ce_unlink = 0;
+ status = NOTOK;
+ }
+
+ return status;