static void part_extractor_foreach_callback(GMimeObject *parent, GMimeObject *part, gpointer user_data) { PartExtractorData *a_data = (PartExtractorData *) user_data; if (GMIME_IS_MESSAGE_PART(part)) { if (a_data->recursion_depth < RECURSION_LIMIT) { GMimeMessage *message = g_mime_message_part_get_message((GMimeMessagePart *) part); // transfer none if (message) g_mime_message_foreach(message, part_extractor_foreach_callback, a_data); } else { g_printerr("endless recursion detected: %d\r\n", a_data->recursion_depth); return; } } else if (GMIME_IS_MESSAGE_PARTIAL (part)) { // Save into an array ? Todo: Look into the specs } else if (GMIME_IS_MULTIPART (part)) { // Nothing special needed on multipart, let descend further } else if (GMIME_IS_PART (part)) { // We are interested only in the part 0 (counting down by same logic) if (a_data->part_id == 0) extract_part(part, a_data); a_data->part_id--; } else { g_assert_not_reached(); } }
static void collector_foreach_callback(GMimeObject *parent, GMimeObject *part, gpointer user_data) { g_return_if_fail(user_data != NULL); PartCollectorData *fdata = (PartCollectorData *) user_data; if (GMIME_IS_MESSAGE_PART(part)) { if (fdata->recursion_depth++ < RECURSION_LIMIT) { GMimeMessage *message = g_mime_message_part_get_message((GMimeMessagePart *) part); // transfer none if (message) g_mime_message_foreach(message, collector_foreach_callback, user_data); } else { g_printerr("endless recursion detected: %d\r\n", fdata->recursion_depth); return; } } else if (GMIME_IS_MESSAGE_PARTIAL(part)) { // Save into an array ? Todo: Look into the specs } else if (GMIME_IS_MULTIPART(part)) { // Nothing special needed on multipart, let descend further } else if (GMIME_IS_PART(part)) { collect_part(part, fdata, GMIME_IS_MULTIPART(parent)); fdata->part_id++; } else { g_assert_not_reached(); } }
void count_parts_in_message (GMimeMessage *message) { int count = 0; /* count the number of parts (recursively) in the message * including the container multiparts */ g_mime_message_foreach (message, count_foreach_callback, &count); printf ("There are %d parts in the message\n", count); }
static GByteArray *gmime_message_get_part_data(GMimeMessage* message, guint part_id) { g_return_val_if_fail(message != NULL, NULL); PartExtractorData *a_data = new_part_extractor_data(part_id); g_mime_message_foreach(message, part_extractor_foreach_callback, a_data); GByteArray *content = a_data->content; free_part_extractor_data(a_data, FALSE); if (!content) g_printerr("could not locate partId %d\r\n", part_id); return content; }
static gboolean handle_children (MuMsg *msg, GMimeMessage *mime_msg, MuMsgOptions opts, unsigned index, MuMsgPartForeachFunc func, gpointer user_data) { ForeachData fdata; fdata.func = func; fdata.user_data = user_data; fdata.opts = opts; fdata.msg = msg; fdata.index = 0; g_mime_message_foreach (mime_msg, (GMimeObjectForeachFunc)each_child, &fdata); return TRUE; }
static int process_message(GMimeMessage *message, const char *post_dir) { struct mime_cbinfo cbinfo = { .count = 0, .post_dir = post_dir, }; #ifdef AST_GMIME_VER_24 g_mime_message_foreach(message, process_message_callback, &cbinfo); #else g_mime_message_foreach_part(message, process_message_callback, &cbinfo); #endif return cbinfo.count; } /* Find a sequence of bytes within a binary array. */ static int find_sequence(char * inbuf, int inlen, char * matchbuf, int matchlen) { int current; int comp; int found = 0; for (current = 0; current < inlen-matchlen; current++, inbuf++) { if (*inbuf == *matchbuf) { found=1; for (comp = 1; comp < matchlen; comp++) { if (inbuf[comp] != matchbuf[comp]) { found = 0; break; } } if (found) { break; } } } if (found) { return current; } else { return -1; } }
static void mime_foreach_callback (GMimeObject * parent, GMimeObject * part, gpointer user_data) { GMimeContentType *type; if (GMIME_IS_MESSAGE_PART (part)) { /* message/rfc822 or message/news */ GMimeMessage *message; /* g_mime_message_foreach_part() won't descend into child message parts, so if we want to count any subparts of this child message, we'll have to call g_mime_message_foreach_part() again here. */ rspamd_printf ("got message part %p: parent: %p\n", part, parent); message = g_mime_message_part_get_message ((GMimeMessagePart *) part); g_mime_message_foreach (message, mime_foreach_callback, part); } else if (GMIME_IS_MULTIPART (part)) { type = (GMimeContentType *) g_mime_object_get_content_type (GMIME_OBJECT ( part)); rspamd_printf ("got multipart part %p, boundary: %s: parent: %p, type: %s/%s\n", part, g_mime_multipart_get_boundary (GMIME_MULTIPART(part)), parent, g_mime_content_type_get_media_type (type), g_mime_content_type_get_media_subtype (type)); } else { type = (GMimeContentType *) g_mime_object_get_content_type (GMIME_OBJECT ( part)); rspamd_printf ("got normal part %p, parent: %p, type: %s/%s\n", part, parent, g_mime_content_type_get_media_type (type), g_mime_content_type_get_media_subtype (type)); } }
static void count_foreach_callback (GMimeObject *parent, GMimeObject *part, gpointer user_data) { int *count = user_data; (*count)++; /* 'part' points to the current part node that * g_mime_message_foreach() is iterating over */ /* find out what class 'part' is... */ if (GMIME_IS_MESSAGE_PART (part)) { /* message/rfc822 or message/news */ GMimeMessage *message; /* g_mime_message_foreach() won't descend into child message parts, so if we want to count any subparts of this child message, we'll have to call g_mime_message_foreach() again here. */ printf("\n===============descend into subparts=================\n"); message = g_mime_message_part_get_message ((GMimeMessagePart *) part); g_mime_message_foreach (message, count_foreach_callback, count); } else if (GMIME_IS_MESSAGE_PARTIAL (part)) { /* message/partial */ /* this is an incomplete message part, probably a large message that the sender has broken into smaller parts and is sending us bit by bit. we could save some info about it so that we could piece this back together again once we get all the parts? */ printf("\n===============partial=================\n"); } else if (GMIME_IS_MULTIPART (part)) { /* multipart/mixed, multipart/alternative, * multipart/related, multipart/signed, * multipart/encrypted, etc... */ /* we'll get to finding out if this is a * signed/encrypted multipart later... */ printf("\n===============multipart=================\n"); } else if (GMIME_IS_PART (part)) { /* a normal leaf part, could be text/plain or * image/jpeg etc */ printf("\n===============normal leaf part=================\n"); printf("====>>>>====>>>>====>>>>Decode start here<<<<====<<<<====<<<<====\n"); { #if 0 printf("\ndecode this normal leaf part================\n" ); //GMimeStream *stream = g_mime_stream_file_new (stdout); //GMimeDataWrapper * content=g_mime_part_get_content_object(part); //g_mime_data_wrapper_write_to_stream(content,stream); #endif } AnalyseMessageParse((GMimePart*)part); } else { printf("\n===============descend not reached=================\n"); g_assert_not_reached (); } }
static PartCollectorData *collect_parts(GMimeMessage *message, guint content_option) { PartCollectorData *pc = new_part_collector_data(content_option); g_mime_message_foreach(message, collector_foreach_callback, pc); return pc; }
static void rspamd_process_file (struct rspamd_config *cfg, const gchar *fname, gint mode) { struct rspamd_task *task; gint fd; gpointer map; struct stat st; GError *err = NULL; #if 0 GMimeMessage *message; GMimeParser *parser; GMimeStream *stream; GByteArray tmp; #endif struct rspamd_mime_part *part; guint i; gdouble ts1, ts2; fd = open (fname, O_RDONLY); if (fd == -1) { rspamd_fprintf (stderr, "cannot open %s: %s\n", fname, strerror (errno)); exit (EXIT_FAILURE); } if (fstat (fd, &st) == -1) { rspamd_fprintf (stderr, "cannot stat %s: %s\n", fname, strerror (errno)); exit (EXIT_FAILURE); } map = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); close (fd); if (map == MAP_FAILED) { rspamd_fprintf (stderr, "cannot mmap %s: %s\n", fname, strerror (errno)); exit (EXIT_FAILURE); } task = rspamd_task_new (NULL, cfg); task->msg.begin = map; task->msg.len = st.st_size; ts1 = rspamd_get_ticks (); if (mode == MODE_NORMAL) { if (!rspamd_mime_parse_task (task, &err)) { rspamd_fprintf (stderr, "cannot parse %s: %e\n", fname, err); g_error_free (err); } } #if 0 else if (mode == MODE_GMIME) { tmp.data = map; tmp.len = st.st_size; stream = g_mime_stream_mem_new_with_byte_array (&tmp); g_mime_stream_mem_set_owner (GMIME_STREAM_MEM (stream), FALSE); parser = g_mime_parser_new_with_stream (stream); message = g_mime_parser_construct_message (parser); } #endif ts2 = rspamd_get_ticks (); total_time += ts2 - ts1; if (mode == MODE_NORMAL) { for (i = 0; i < task->parts->len; i ++) { part = g_ptr_array_index (task->parts, i); if (part->ct->flags & RSPAMD_CONTENT_TYPE_MULTIPART) { rspamd_show_multipart (part); } else if (part->ct->flags & RSPAMD_CONTENT_TYPE_MESSAGE) { rspamd_show_message (part); } else { rspamd_show_normal (part); } } } #if 0 else if (mode == MODE_GMIME) { g_mime_message_foreach (message, mime_foreach_callback, NULL); } #endif rspamd_task_free (task); munmap (map, st.st_size); #if 0 if (mode == MODE_GMIME) { g_object_unref (message); } #endif }