/* there is also an identical copy of this in camel-filter-search.c */ gboolean camel_search_message_body_contains (CamelDataWrapper *object, regex_t *pattern) { CamelDataWrapper *containee; int truth = FALSE; int parts, i; containee = camel_medium_get_content_object (CAMEL_MEDIUM (object)); if (containee == NULL) return FALSE; /* using the object types is more accurate than using the mime/types */ if (CAMEL_IS_MULTIPART (containee)) { parts = camel_multipart_get_number (CAMEL_MULTIPART (containee)); for (i = 0; i < parts && truth == FALSE; i++) { CamelDataWrapper *part = (CamelDataWrapper *)camel_multipart_get_part (CAMEL_MULTIPART (containee), i); if (part) truth = camel_search_message_body_contains (part, pattern); } } else if (CAMEL_IS_MIME_MESSAGE (containee)) { /* for messages we only look at its contents */ truth = camel_search_message_body_contains ((CamelDataWrapper *)containee, pattern); } else if (camel_content_type_is(CAMEL_DATA_WRAPPER (containee)->mime_type, "text", "*")) { /* for all other text parts, we look inside, otherwise we dont care */ CamelStreamMem *mem = (CamelStreamMem *)camel_stream_mem_new (); camel_data_wrapper_write_to_stream (containee, CAMEL_STREAM (mem)); camel_stream_write (CAMEL_STREAM (mem), "", 1); truth = regexec (pattern, (char *) mem->buffer->data, 0, NULL, 0) == 0; camel_object_unref (mem); } return truth; }
static void dump_mime_struct (CamelMimePart *mime_part, gint depth) { CamelDataWrapper *content; gchar *mime_type; gint i = 0; while (i < depth) { printf (" "); i++; } content = camel_medium_get_content ((CamelMedium *) mime_part); mime_type = camel_data_wrapper_get_mime_type (content); printf ("Content-Type: %s\n", mime_type); g_free (mime_type); if (CAMEL_IS_MULTIPART (content)) { guint num, index = 0; num = camel_multipart_get_number ((CamelMultipart *) content); while (index < num) { mime_part = camel_multipart_get_part ((CamelMultipart *) content, index); dump_mime_struct (mime_part, depth + 1); index++; } } else if (CAMEL_IS_MIME_MESSAGE (content)) { dump_mime_struct ((CamelMimePart *) content, depth + 1); } }
void org_gnome_prefer_plain_multipart_alternative(void *ep, EMFormatHookTarget *t) { CamelMultipart *mp = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)t->part); CamelMimePart *part, *display_part = NULL; int i, nparts, partidlen, displayid = 0; if (epp_mode == EPP_NORMAL) { /* Try to find text/html part even when not as last and force to show it. Old handler will show the last part of multipart/alternate, but if we can offer HTML, then offer it, regardless of position in multipart. */ nparts = camel_multipart_get_number (mp); for (i = 0; i < nparts; i++) { part = camel_multipart_get_part (mp, i); if (part && camel_content_type_is (camel_mime_part_get_content_type (part), "text", "html")) { displayid = i; display_part = part; break; } } if (display_part) { g_string_append_printf (t->format->part_id, ".alternative.%d", displayid); em_format_part_as (t->format, t->stream, display_part, "text/html"); g_string_truncate (t->format->part_id, partidlen); } else { t->item->handler.old->handler (t->format, t->stream, t->part, t->item->handler.old); } return; } else if (!CAMEL_IS_MULTIPART(mp)) { em_format_format_source(t->format, t->stream, t->part); return; } nparts = camel_multipart_get_number(mp); for (i=0; i<nparts; i++) { part = camel_multipart_get_part(mp, i); if (part && camel_content_type_is(camel_mime_part_get_content_type(part), "text", "plain")) { displayid = i; display_part = part; break; } } /* this part-id stuff is poking private data, needs api */ partidlen = t->format->part_id->len; /* if we found a text part, show it */ if (display_part) { g_string_append_printf(t->format->part_id, ".alternative.%d", displayid); em_format_part_as(t->format, t->stream, display_part, "text/plain"); g_string_truncate(t->format->part_id, partidlen); } /* all other parts are attachments */ export_as_attachments (mp, t->format, t->stream, display_part); g_string_truncate(t->format->part_id, partidlen); }
/** * * It dumps attachments to /tmp * **/ void util_attachments_to_files(CamelMimeMessage *message) { gint parts, i = 0; char *store_dir; CamelDataWrapper *content = NULL; content = camel_medium_get_content_object((CamelMedium *) message); if (!content || !CAMEL_IS_MULTIPART(content)) return; parts = camel_multipart_get_number(CAMEL_MULTIPART(content)); if (parts < 1) return; store_dir = "/tmp"; // TODO home for (i = 1; i < parts; i++) { gchar *filename = NULL; gchar *path = NULL; gchar *tmp = NULL; const gchar *orig_filename = NULL; CamelMimePart *mime_part = camel_multipart_get_part(CAMEL_MULTIPART(content), i); orig_filename = camel_mime_part_get_filename(mime_part); g_debug("Orig filename : %s\n", orig_filename); if (orig_filename == NULL) { g_print("Esto es un adjunto distinto."); orig_filename = camel_mime_part_get_description(mime_part); } if (!orig_filename) continue; tmp = clean_name((const guchar *) orig_filename); filename = g_strdup_printf("%s-%s", "evosugar", tmp); path = g_build_filename(store_dir, filename, NULL); g_debug("Attach. to file : %s\n", path); BREAKPOINT; // TODO should be done in another thread if (em_utils_save_part_to_file(NULL, path, mime_part)) { gchar *uri; BREAKPOINT; uri = g_filename_to_uri(path, NULL, NULL); BREAKPOINT; g_free(uri); } BREAKPOINT; g_free(tmp); BREAKPOINT; g_free(filename); BREAKPOINT; g_free(path); BREAKPOINT; } //g_free (store_dir); }
/** * * "util_get_msg_body" is based on mail-to-task eplugin's get_description function. * which is GPL licensed. * */ static gchar * util_get_msg_body(CamelMimeMessage *message, gchar **text) { CamelDataWrapper *content; CamelStream *mem; CamelContentType *type; CamelMimePart *mime_part = CAMEL_MIME_PART(message); GSList sl; gchar *str, *convert_str = NULL; gsize bytes_read, bytes_written; gint count = 2; content = camel_medium_get_content_object((CamelMedium *) message); if (!content) return; /* * Get non-multipart content from multipart message. */ while (CAMEL_IS_MULTIPART(content) && count > 0) { mime_part = camel_multipart_get_part(CAMEL_MULTIPART(content), 0); content = camel_medium_get_content_object(CAMEL_MEDIUM(mime_part)); count--; } if (!mime_part) return; type = camel_mime_part_get_content_type(mime_part); if (!camel_content_type_is(type, "text", "plain")) return; mem = camel_stream_mem_new(); camel_data_wrapper_decode_to_stream(content, mem); str = g_strndup((const gchar *) ((CamelStreamMem *) mem)->buffer->data, ((CamelStreamMem *) mem)->buffer->len); camel_object_unref(mem); /* convert to UTF-8 string */ if (str && content->mime_type->params && content->mime_type->params->value) { convert_str = g_convert(str, strlen(str), "UTF-8", content->mime_type->params->value, &bytes_read, &bytes_written, NULL); } if (convert_str) *text = convert_str; else *text = str; /*g_free (str); if (convert_str) g_free (convert_str); */ }
static void export_as_attachments (CamelMultipart *mp, EMFormat *format, CamelStream *stream, CamelMimePart *except) { int i, nparts, partidlen; CamelMimePart *part; if (!mp || !CAMEL_IS_MULTIPART (mp)) return; partidlen = format->part_id->len; nparts = camel_multipart_get_number(mp); for (i = 0; i < nparts; i++) { part = camel_multipart_get_part (mp, i); if (part != except) { CamelMultipart *multipart = (CamelMultipart *)camel_medium_get_content_object((CamelMedium *)part); if (CAMEL_IS_MULTIPART (multipart)) { export_as_attachments (multipart, format, stream, except); } else { g_string_append_printf (format->part_id, ".alternative.%d", i); if (camel_content_type_is (camel_mime_part_get_content_type (part), "text", "html")) { /* always show HTML as attachments and not inline */ camel_mime_part_set_disposition (part, "attachment"); if (!camel_mime_part_get_filename (part)) { char *str = g_strdup_printf ("%s.html", _("attachment")); camel_mime_part_set_filename (part, str); g_free (str); } em_format_part_as (format, stream, part, "application/octet-stream"); } else em_format_part (format, stream, part); g_string_truncate (format->part_id, partidlen); } } } }
static void message_dump_rec (CamelMimeMessage *msg, CamelMimePart *part, gint depth) { CamelDataWrapper *containee; gint parts, i; gchar *s; gchar *mime_type; s = alloca (depth + 1); memset (s, ' ', depth); s[depth] = 0; mime_type = camel_data_wrapper_get_mime_type ((CamelDataWrapper *) part); printf ("%sPart <%s>\n", s, G_OBJECT_TYPE_NAME (part)); printf ("%sContent-Type: %s\n", s, mime_type); g_free (mime_type); printf ("%s encoding: %s\n", s, camel_transfer_encoding_to_string (((CamelDataWrapper *)part)->encoding)); printf ("%s part encoding: %s\n", s, camel_transfer_encoding_to_string (camel_mime_part_get_encoding (part))); containee = camel_medium_get_content (CAMEL_MEDIUM (part)); if (containee == NULL) return; mime_type = camel_data_wrapper_get_mime_type (containee); printf ("%sContent <%s>\n", s, G_OBJECT_TYPE_NAME (containee)); printf ("%sContent-Type: %s\n", s, mime_type); g_free (mime_type); printf ("%s encoding: %s\n", s, camel_transfer_encoding_to_string (((CamelDataWrapper *)containee)->encoding)); /* using the object types is more accurate than using the mime/types */ if (CAMEL_IS_MULTIPART (containee)) { parts = camel_multipart_get_number (CAMEL_MULTIPART (containee)); for (i = 0; i < parts; i++) { CamelMimePart *part = camel_multipart_get_part (CAMEL_MULTIPART (containee), i); message_dump_rec (msg, part, depth + 1); } } else if (CAMEL_IS_MIME_MESSAGE (containee)) { message_dump_rec (msg, (CamelMimePart *) containee, depth + 1); } }
/** * * It stores the attachment list into the model. * */ GtkTreeModel * util_get_msg_attachments(CamelMimeMessage *message) { gint parts, i = 0; GtkTreeIter iter; CamelDataWrapper *content = NULL; GtkTreeStore *tree_store = gtk_tree_store_new(2, G_TYPE_BOOLEAN, G_TYPE_STRING); content = camel_medium_get_content_object((CamelMedium *) message); if (!content || !CAMEL_IS_MULTIPART(content)) return; parts = camel_multipart_get_number(CAMEL_MULTIPART(content)); if (parts < 1) return; for (i = 1; i < parts; i++) { const gchar *orig_filename; CamelMimePart *mime_part; mime_part = camel_multipart_get_part(CAMEL_MULTIPART(content), i); orig_filename = camel_mime_part_get_filename(mime_part); if (orig_filename == NULL) { g_debug("No hay filename, esto es un adjunto distinto.\n"); orig_filename = camel_mime_part_get_description(mime_part); } gtk_tree_store_append(tree_store, &iter, NULL); gtk_tree_store_set(tree_store, &iter, 0, TRUE, 1, orig_filename, -1); g_print("Orig filename : %s\n", orig_filename); if (!orig_filename) continue; BREAKPOINT; } return GTK_TREE_MODEL(tree_store); }
/* there is also an identical copy of this in camel-filter-search.c */ gboolean camel_search_message_body_contains (CamelDataWrapper *object, regex_t *pattern) { CamelDataWrapper *containee; gint truth = FALSE; gint parts, i; containee = camel_medium_get_content (CAMEL_MEDIUM (object)); if (containee == NULL) return FALSE; /* using the object types is more accurate than using the mime/types */ if (CAMEL_IS_MULTIPART (containee)) { parts = camel_multipart_get_number (CAMEL_MULTIPART (containee)); for (i = 0; i < parts && truth == FALSE; i++) { CamelDataWrapper *part = (CamelDataWrapper *)camel_multipart_get_part (CAMEL_MULTIPART (containee), i); if (part) truth = camel_search_message_body_contains (part, pattern); } } else if (CAMEL_IS_MIME_MESSAGE (containee)) { /* for messages we only look at its contents */ truth = camel_search_message_body_contains ((CamelDataWrapper *)containee, pattern); } else if (camel_content_type_is(CAMEL_DATA_WRAPPER (containee)->mime_type, "text", "*") || camel_content_type_is(CAMEL_DATA_WRAPPER (containee)->mime_type, "x-evolution", "evolution-rss-feed")) { /* for all other text parts, we look inside, otherwise we dont care */ CamelStream *stream; GByteArray *byte_array; byte_array = g_byte_array_new (); stream = camel_stream_mem_new_with_byte_array (byte_array); camel_data_wrapper_write_to_stream_sync ( containee, stream, NULL, NULL); camel_stream_write (stream, "", 1, NULL, NULL); truth = regexec (pattern, (gchar *) byte_array->data, 0, NULL, 0) == 0; g_object_unref (stream); } return truth; }
gboolean scalix_appointment_init_from_mime_message (ScalixObject * object, CamelMimeMessage * msg) { const char *msgid; const char *attachment_store; const char *mime_type, *alternative_mime_type; const char *content_disposition; const char *mime_filename; const char *cid; const char *cuid; const char *attachment_file_url; GSList *attachments = NULL; GSList *attachments_new = NULL; GSList *siter = NULL; CamelMimePart *part, *alternative; CamelMultipart *multipart, *nested_multipart; CamelDataWrapper *content, *alternative_content; int i, j, num_parts, num_alternatives; gboolean found_ical = FALSE; attachment_store = g_object_get_data (G_OBJECT (object), "attachment-store"); part = CAMEL_MIME_PART (msg); content = camel_medium_get_content_object (CAMEL_MEDIUM (part)); if (content == NULL) { return FALSE; } mime_type = camel_content_type_simple (content->mime_type); if (CAMEL_IS_MULTIPART (content)) { multipart = (CamelMultipart *) content; num_parts = (int) camel_multipart_get_number (multipart); for (i = 0; i < num_parts; i++) { part = camel_multipart_get_part (multipart, i); content = camel_medium_get_content_object (CAMEL_MEDIUM (part)); mime_type = camel_content_type_simple (content->mime_type); mime_filename = camel_mime_part_get_filename (part); content_disposition = camel_mime_part_get_disposition (part); if (CAMEL_IS_MULTIPART (content)) { nested_multipart = (CamelMultipart *) content; num_alternatives = (int) camel_multipart_get_number (nested_multipart); for (j = 0; j < num_alternatives; j++) { alternative = camel_multipart_get_part (nested_multipart, j); alternative_content = camel_medium_get_content_object (CAMEL_MEDIUM (alternative)); alternative_mime_type = camel_content_type_simple (alternative_content-> mime_type); if (g_str_equal (alternative_mime_type, "text/calendar") && found_ical == FALSE) { if (set_ical_from_mime_part (alternative, object) == TRUE) { e_cal_component_get_uid (E_CAL_COMPONENT (object), &cuid); e_cal_component_get_attachment_list (E_CAL_COMPONENT (object), &attachments); /* we are only interested in the first ical body part */ found_ical = TRUE; } } } } else if (g_str_equal (mime_type, "text/calendar") && found_ical == FALSE) { if (set_ical_from_mime_part (part, object) == TRUE) { e_cal_component_get_uid (E_CAL_COMPONENT (object), &cuid); e_cal_component_get_attachment_list (E_CAL_COMPONENT (object), &attachments); /* we are only interested in the first ical body part */ found_ical = TRUE; } } else if (content_disposition && strcmp (content_disposition, "attachment") == 0) { cid = camel_mime_part_get_content_id (part); if (cid != NULL) { for (siter = attachments; siter; siter = siter->next) { if (strstr (siter->data, cid) == (char *) (siter->data) + 4) { attachment_file_url = save_attachment (part, cuid, attachment_store); if (attachment_file_url != NULL) { attachments_new = g_slist_append (attachments_new, g_strdup (attachment_file_url)); } } } } } else { g_print ("XXXXX Unhandled mime part: %s\n", mime_type); } } } else { /* just a simple ical message */ if (g_str_equal (mime_type, "text/calendar")) { set_ical_from_mime_part (part, object); } } if (attachments_new != NULL) { e_cal_component_set_attachment_list (E_CAL_COMPONENT (object), attachments_new); } msgid = camel_mime_message_get_message_id (msg); scalix_appointment_unset (SCALIX_APPOINTMENT (object), X_SCALIX_MSG_ID); scalix_appointment_set (SCALIX_APPOINTMENT (object), X_SCALIX_MSG_ID, msgid); return TRUE; }
static void set_attachments (ECalClient *client, ECalComponent *comp, CamelMimeMessage *message) { /* XXX Much of this is copied from CompEditor::get_attachment_list(). * Perhaps it should be split off as a separate utility? */ EAttachmentStore *store; CamelDataWrapper *content; CamelMultipart *multipart; GFile *destination; GList *attachment_list = NULL; GSList *uri_list = NULL; const gchar *comp_uid = NULL; const gchar *local_store; gchar *filename_prefix, *tmp; gint ii, n_parts; struct _att_async_cb_data cb_data; cb_data.flag = e_flag_new (); cb_data.uris = NULL; content = camel_medium_get_content ((CamelMedium *) message); if (!content || !CAMEL_IS_MULTIPART (content)) return; n_parts = camel_multipart_get_number (CAMEL_MULTIPART (content)); if (n_parts < 1) return; e_cal_component_get_uid (comp, &comp_uid); g_return_if_fail (comp_uid != NULL); tmp = g_strdup (comp_uid); e_filename_make_safe (tmp); filename_prefix = g_strconcat (tmp, "-", NULL); g_free (tmp); local_store = e_cal_client_get_local_attachment_store (client); destination = g_file_new_for_path (local_store); /* Create EAttachments from the MIME parts and add them to the * attachment store. */ multipart = CAMEL_MULTIPART (content); store = E_ATTACHMENT_STORE (e_attachment_store_new ()); for (ii = 1; ii < n_parts; ii++) { EAttachment *attachment; CamelMimePart *mime_part; attachment = e_attachment_new (); mime_part = camel_multipart_get_part (multipart, ii); e_attachment_set_mime_part (attachment, mime_part); attachment_list = g_list_append (attachment_list, attachment); } e_flag_clear (cb_data.flag); e_attachment_store_load_async ( store, attachment_list, (GAsyncReadyCallback) attachment_load_finished, &cb_data); /* Loading should be instantaneous since we already have * the full content, but we need to wait for the callback. */ e_flag_wait (cb_data.flag); g_list_foreach (attachment_list, (GFunc) g_object_unref, NULL); g_list_free (attachment_list); cb_data.uris = NULL; e_flag_clear (cb_data.flag); e_attachment_store_save_async ( store, destination, filename_prefix, (GAsyncReadyCallback) attachment_save_finished, &cb_data); g_free (filename_prefix); /* We can't return until we have results. */ e_flag_wait (cb_data.flag); if (cb_data.uris == NULL) { e_flag_free (cb_data.flag); g_warning ("No attachment URIs retrieved."); return; } /* Transfer the URI strings to the GSList. */ for (ii = 0; cb_data.uris[ii] != NULL; ii++) { uri_list = g_slist_prepend (uri_list, cb_data.uris[ii]); cb_data.uris[ii] = NULL; } e_flag_free (cb_data.flag); g_free (cb_data.uris); /* XXX Does this take ownership of the list? */ e_cal_component_set_attachment_list (comp, uri_list); e_attachment_store_remove_all (store); g_object_unref (destination); g_object_unref (store); }
static void set_description (ECalComponent *comp, CamelMimeMessage *message) { CamelDataWrapper *content; CamelStream *stream; CamelContentType *type; CamelMimePart *mime_part = CAMEL_MIME_PART (message); ECalComponentText *text = NULL; GByteArray *byte_array; GSList *sl = NULL; gchar *str, *convert_str = NULL; gsize bytes_read, bytes_written; gint count = 2; content = camel_medium_get_content ((CamelMedium *) message); if (!content) return; /* * Get non-multipart content from multipart message. */ while (CAMEL_IS_MULTIPART (content) && count > 0) { mime_part = camel_multipart_get_part (CAMEL_MULTIPART (content), 0); content = camel_medium_get_content (CAMEL_MEDIUM (mime_part)); count--; } if (!mime_part) return; type = camel_mime_part_get_content_type (mime_part); if (!camel_content_type_is (type, "text", "plain")) return; byte_array = g_byte_array_new (); stream = camel_stream_mem_new_with_byte_array (byte_array); camel_data_wrapper_decode_to_stream_sync (content, stream, NULL, NULL); str = g_strndup ((gchar *) byte_array->data, byte_array->len); g_object_unref (stream); /* convert to UTF-8 string */ if (str && content->mime_type->params && content->mime_type->params->value) { convert_str = g_convert ( str, strlen (str), "UTF-8", content->mime_type->params->value, &bytes_read, &bytes_written, NULL); } text = g_new0 (ECalComponentText, 1); if (convert_str) text->value = prepend_from (message, &convert_str); else text->value = prepend_from (message, &str); text->altrep = NULL; sl = g_slist_append (sl, text); e_cal_component_set_description_list (comp, sl); g_free (str); if (convert_str) g_free (convert_str); e_cal_component_free_text_list (sl); }
static gboolean empe_mp_alternative_parse (EMailParserExtension *extension, EMailParser *parser, CamelMimePart *part, GString *part_id, GCancellable *cancellable, GQueue *out_mail_parts) { CamelMultipart *mp; gint i, nparts, bestid = 0; CamelMimePart *best = NULL; EMailExtensionRegistry *reg; reg = e_mail_parser_get_extension_registry (parser); mp = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part); if (!CAMEL_IS_MULTIPART (mp)) return e_mail_parser_parse_part_as ( parser, part, part_id, "application/vnd.evolution.source", cancellable, out_mail_parts); /* as per rfc, find the last part we know how to display */ nparts = camel_multipart_get_number (mp); for (i = 0; i < nparts; i++) { CamelMimePart *mpart; CamelDataWrapper *data_wrapper; CamelContentType *type; gchar *mime_type; gsize content_size; if (g_cancellable_is_cancelled (cancellable)) return TRUE; /* is it correct to use the passed in *part here? */ mpart = camel_multipart_get_part (mp, i); if (mpart == NULL) continue; /* This may block even though the stream does not. * XXX Pretty inefficient way to test if the MIME part * is empty. Surely there's a quicker way? */ data_wrapper = camel_medium_get_content (CAMEL_MEDIUM (mpart)); content_size = camel_data_wrapper_calculate_decoded_size_sync (data_wrapper, cancellable, NULL); if (content_size == 0) continue; type = camel_mime_part_get_content_type (mpart); mime_type = camel_content_type_simple (type); camel_strdown (mime_type); if (!e_mail_part_is_attachment (mpart) && ((camel_content_type_is (type, "multipart", "related") == 0) || !related_display_part_is_attachment (mpart)) && (e_mail_extension_registry_get_for_mime_type (reg, mime_type) || ((best == NULL) && (e_mail_extension_registry_get_fallback (reg, mime_type))))) { best = mpart; bestid = i; } g_free (mime_type); } if (best) { gint len = part_id->len; g_string_append_printf (part_id, ".alternative.%d", bestid); e_mail_parser_parse_part ( parser, best, part_id, cancellable, out_mail_parts); g_string_truncate (part_id, len); } else { e_mail_parser_parse_part_as ( parser, part, part_id, "multipart/mixed", cancellable, out_mail_parts); } return TRUE; }
static gboolean empe_mp_signed_parse (EMailParserExtension *extension, EMailParser *parser, CamelMimePart *part, GString *part_id, GCancellable *cancellable, GQueue *out_mail_parts) { CamelMimePart *cpart = NULL; CamelMultipart *multipart; CamelCipherContext *cipher = NULL; CamelContentType *content_type; CamelSession *session; guint32 validity_type; CamelCipherValidity *valid; const gchar *protocol = NULL; GError *local_error = NULL; gint i, nparts, len; gboolean secured; /* If the part is application/pgp-signature sub-part then skip it. */ if (!CAMEL_IS_MULTIPART (part)) { content_type = camel_mime_part_get_content_type (part); if (camel_content_type_is ( content_type, "application", "pgp-signature")) { return TRUE; } } multipart = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part); if (CAMEL_IS_MULTIPART_SIGNED (multipart)) { cpart = camel_multipart_get_part ( multipart, CAMEL_MULTIPART_SIGNED_CONTENT); } if (cpart == NULL) { e_mail_parser_error ( parser, out_mail_parts, _("Could not parse MIME message. " "Displaying as source.")); e_mail_parser_parse_part_as ( parser, part, part_id, "application/vnd.evolution.source", cancellable, out_mail_parts); return TRUE; } content_type = camel_data_wrapper_get_mime_type_field ( CAMEL_DATA_WRAPPER (multipart)); if (content_type != NULL) protocol = camel_content_type_param (content_type, "protocol"); session = e_mail_parser_get_session (parser); /* FIXME: Should be done via a plugin interface */ /* FIXME: duplicated in em-format-html-display.c */ if (protocol != NULL) { #ifdef ENABLE_SMIME if (g_ascii_strcasecmp ("application/x-pkcs7-signature", protocol) == 0 || g_ascii_strcasecmp ("application/pkcs7-signature", protocol) == 0) { cipher = camel_smime_context_new (session); validity_type = E_MAIL_PART_VALIDITY_SMIME; } else { #endif if (g_ascii_strcasecmp ("application/pgp-signature", protocol) == 0) { cipher = camel_gpg_context_new (session); validity_type = E_MAIL_PART_VALIDITY_PGP; } #ifdef ENABLE_SMIME } #endif } if (cipher == NULL) { e_mail_parser_error ( parser, out_mail_parts, _("Unsupported signature format")); e_mail_parser_parse_part_as ( parser, part, part_id, "multipart/mixed", cancellable, out_mail_parts); return TRUE; } valid = camel_cipher_context_verify_sync ( cipher, part, cancellable, &local_error); if (local_error != NULL) { e_mail_parser_error ( parser, out_mail_parts, _("Error verifying signature: %s"), local_error->message); e_mail_parser_parse_part_as ( parser, part, part_id, "multipart/mixed", cancellable, out_mail_parts); g_object_unref (cipher); g_error_free (local_error); return TRUE; } nparts = camel_multipart_get_number (multipart); secured = FALSE; len = part_id->len; for (i = 0; i < nparts; i++) { GQueue work_queue = G_QUEUE_INIT; GList *head, *link; CamelMimePart *subpart; subpart = camel_multipart_get_part (multipart, i); g_string_append_printf (part_id, ".signed.%d", i); g_warn_if_fail (e_mail_parser_parse_part ( parser, subpart, part_id, cancellable, &work_queue)); g_string_truncate (part_id, len); if (!secured) secured = e_mail_part_is_secured (subpart); head = g_queue_peek_head_link (&work_queue); for (link = head; link != NULL; link = g_list_next (link)) { EMailPart *mail_part = link->data; e_mail_part_update_validity ( mail_part, valid, validity_type | E_MAIL_PART_VALIDITY_SIGNED); } e_queue_transfer (&work_queue, out_mail_parts); } /* Add a widget with details about the encryption, but only when * the encrypted isn't itself secured, in that case it has created * the button itself. */ if (!secured) { GQueue work_queue = G_QUEUE_INIT; EMailPart *mail_part; g_string_append (part_id, ".signed.button"); e_mail_parser_parse_part_as ( parser, part, part_id, "application/vnd.evolution.widget.secure-button", cancellable, &work_queue); mail_part = g_queue_peek_head (&work_queue); if (mail_part != NULL) e_mail_part_update_validity ( mail_part, valid, validity_type | E_MAIL_PART_VALIDITY_SIGNED); e_queue_transfer (&work_queue, out_mail_parts); g_string_truncate (part_id, len); } camel_cipher_validity_free (valid); g_object_unref (cipher); return TRUE; }
static gboolean empe_mp_digest_parse (EMailParserExtension *extension, EMailParser *parser, CamelMimePart *part, GString *part_id, GCancellable *cancellable, GQueue *out_mail_parts) { CamelMultipart *mp; gint i, nparts, len; mp = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part); if (!CAMEL_IS_MULTIPART (mp)) return e_mail_parser_parse_part_as ( parser, part, part_id, "application/vnd.evolution.source", cancellable, out_mail_parts); len = part_id->len; nparts = camel_multipart_get_number (mp); for (i = 0; i < nparts; i++) { CamelMimePart *subpart; CamelContentType *ct; gchar *cts; subpart = camel_multipart_get_part (mp, i); if (!subpart) continue; g_string_append_printf (part_id, ".digest.%d", i); ct = camel_mime_part_get_content_type (subpart); /* According to RFC this shouldn't happen, but who knows... */ if (ct && !camel_content_type_is (ct, "message", "rfc822")) { cts = camel_content_type_simple (ct); e_mail_parser_parse_part_as ( parser, subpart, part_id, cts, cancellable, out_mail_parts); g_free (cts); } else { GQueue work_queue = G_QUEUE_INIT; EMailPart *mail_part; gboolean wrap_as_attachment; e_mail_parser_parse_part_as ( parser, subpart, part_id, "message/rfc822", cancellable, &work_queue); mail_part = g_queue_peek_head (&work_queue); wrap_as_attachment = (mail_part != NULL) && !e_mail_part_get_is_attachment (mail_part); /* Force the message to be collapsable */ if (wrap_as_attachment) e_mail_parser_wrap_as_attachment ( parser, subpart, part_id, &work_queue); mail_part = g_queue_peek_head (&work_queue); /* Force the message to be expanded */ if (mail_part != NULL) mail_part->force_inline = TRUE; e_queue_transfer (&work_queue, out_mail_parts); } g_string_truncate (part_id, len); } return TRUE; }
static void fill_model_rec(CamelMimeMessage *msg, CamelMimePart *part, GtkTreeStore *model, GtkTreeIter *parent, GString *name) { CamelDataWrapper *containee; int parts, i; char *type; GtkTreeIter iter; int len = name->len; CamelContentType *mime; containee = camel_medium_get_content_object((CamelMedium *)part); if (containee == NULL) return; mime = ((CamelDataWrapper *)containee)->mime_type; type = camel_content_type_simple(mime); if (CAMEL_IS_MULTIPART(containee)) { gtk_tree_store_append(model, &iter, parent); g_string_append_printf(name, ".multipart"); gtk_tree_store_set(model, &iter, 0, FALSE, 1, type, 2, name->str, 3, name->str, 4, part, -1); parts = camel_multipart_get_number((CamelMultipart *)containee); for (i = 0; i < parts; i++) { CamelMimePart *mpart = camel_multipart_get_part((CamelMultipart *)containee, i); g_string_truncate(name, len); g_string_append_printf(name, ".%d", i); fill_model_rec(msg, mpart, model, &iter, name); } } else if (CAMEL_IS_MIME_MESSAGE(containee)) { gtk_tree_store_append(model, &iter, parent); g_string_append_printf(name, ".msg"); gtk_tree_store_set(model, &iter, 0, FALSE, 1, type, 2, name->str, 3, name->str, 4, part, -1); fill_model_rec(msg, (CamelMimePart *)containee, model, &iter, name); } else { char *filename = NULL; const char *ext = NULL, *tmp; int save = FALSE; gtk_tree_store_append(model, &iter, parent); tmp = camel_mime_part_get_filename(part); if (tmp) { filename = clean_name(tmp); ext = strrchr(filename, '.'); } tmp = camel_mime_part_get_disposition(part); if (tmp && !strcmp(tmp, "attachment")) save = TRUE; if (camel_content_type_is(mime, "text", "*")) { if (ext == NULL) { if ((ext = mime->subtype) == NULL || !strcmp(ext, "plain")) ext = "text"; } } else if (camel_content_type_is(mime, "image", "*")) { if (ext == NULL) { if ((ext = mime->subtype) == NULL) ext = "image"; } save = TRUE; } g_string_append_printf(name, ".%s", ext); gtk_tree_store_set(model, &iter, 0, save, 1, type, 2, filename?filename:name->str, 3, filename?NULL:name->str, 4, part, -1); g_free(filename); } g_free(type); g_string_truncate(name, len); }