/* 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; }
/** * * 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); }
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); } }
/** * * "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 multipart_finalize (GObject *object) { CamelMultipart *multipart = CAMEL_MULTIPART (object); g_free (multipart->preface); g_free (multipart->postface); /* Chain up to parent's finalize() method. */ G_OBJECT_CLASS (camel_multipart_parent_class)->finalize (object); }
/** * * 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); }
static void multipart_dispose (GObject *object) { CamelMultipart *multipart = CAMEL_MULTIPART (object); g_list_foreach (multipart->parts, (GFunc) g_object_unref, NULL); g_list_free (multipart->parts); multipart->parts = NULL; /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (camel_multipart_parent_class)->dispose (object); }
/* 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; }
static gboolean multipart_is_offline (CamelDataWrapper *data_wrapper) { CamelMultipart *multipart = CAMEL_MULTIPART (data_wrapper); GList *node; CamelDataWrapper *part; if (CAMEL_DATA_WRAPPER_CLASS (camel_multipart_parent_class)->is_offline (data_wrapper)) return TRUE; for (node = multipart->parts; node; node = node->next) { part = node->data; if (camel_data_wrapper_is_offline (part)) return TRUE; } return FALSE; }
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); }
/* this is MIME specific, doesn't belong here really */ static gssize multipart_write_to_stream_sync (CamelDataWrapper *data_wrapper, CamelStream *stream, GCancellable *cancellable, GError **error) { CamelMultipart *multipart = CAMEL_MULTIPART (data_wrapper); const gchar *boundary; GList *node; gchar *content; gssize total = 0; gssize count; /* get the bundary text */ boundary = camel_multipart_get_boundary (multipart); /* we cannot write a multipart without a boundary string */ g_return_val_if_fail (boundary, -1); /* * write the preface text (usually something like * "This is a mime message, if you see this, then * your mail client probably doesn't support ...." */ if (multipart->preface) { count = camel_stream_write_string ( stream, multipart->preface, cancellable, error); if (count == -1) return -1; total += count; } /* * Now, write all the parts, separated by the boundary * delimiter */ node = multipart->parts; while (node) { content = g_strdup_printf ("\n--%s\n", boundary); count = camel_stream_write_string ( stream, content, cancellable, error); g_free (content); if (count == -1) return -1; total += count; count = camel_data_wrapper_write_to_stream_sync ( CAMEL_DATA_WRAPPER (node->data), stream, cancellable, error); if (count == -1) return -1; total += count; node = node->next; } /* write the terminating boudary delimiter */ content = g_strdup_printf ("\n--%s--\n", boundary); count = camel_stream_write_string ( stream, content, cancellable, error); g_free (content); if (count == -1) return -1; total += count; /* and finally the postface */ if (multipart->postface) { count = camel_stream_write_string ( stream, multipart->postface, cancellable, error); if (count == -1) return -1; total += count; } return total; }