static gint multipart_construct_from_parser (CamelMultipart *multipart, CamelMimeParser *mp) { gint err; CamelContentType *content_type; CamelMimePart *bodypart; gchar *buf; gsize len; g_assert (camel_mime_parser_state (mp) == CAMEL_MIME_PARSER_STATE_MULTIPART); /* FIXME: we should use a came-mime-mutlipart, not jsut a camel-multipart, but who cares */ d(printf("Creating multi-part\n")); content_type = camel_mime_parser_content_type (mp); camel_multipart_set_boundary (multipart, camel_content_type_param(content_type, "boundary")); while (camel_mime_parser_step (mp, &buf, &len) != CAMEL_MIME_PARSER_STATE_MULTIPART_END) { camel_mime_parser_unstep (mp); bodypart = camel_mime_part_new (); camel_mime_part_construct_from_parser_sync ( bodypart, mp, NULL, NULL); camel_multipart_add_part (multipart, bodypart); g_object_unref (bodypart); } /* these are only return valid data in the MULTIPART_END state */ camel_multipart_set_preface (multipart, camel_mime_parser_preface (mp)); camel_multipart_set_postface (multipart, camel_mime_parser_postface (mp)); err = camel_mime_parser_errno (mp); if (err != 0) { errno = err; return -1; } else return 0; }
static gint multipart_signed_parse_content (CamelMultipartSigned *mps) { CamelMimeParser *cmp; CamelMultipart *mp = (CamelMultipart *) mps; CamelDataWrapper *data_wrapper; GByteArray *byte_array; CamelStream *stream; const gchar *boundary; gchar *buf; gsize len; gint state; boundary = camel_multipart_get_boundary (mp); g_return_val_if_fail (boundary != NULL, -1); data_wrapper = CAMEL_DATA_WRAPPER (mps); byte_array = camel_data_wrapper_get_byte_array (data_wrapper); stream = camel_stream_mem_new (); /* Do not give the stream ownership of the byte array. */ camel_stream_mem_set_byte_array ( CAMEL_STREAM_MEM (stream), byte_array); /* This is all seriously complex. * This is so we can parse all cases properly, without altering the content. * All we are doing is finding part offsets. */ cmp = camel_mime_parser_new (); camel_mime_parser_init_with_stream (cmp, stream, NULL); camel_mime_parser_push_state (cmp, CAMEL_MIME_PARSER_STATE_MULTIPART, boundary); mps->start1 = -1; mps->end1 = -1; mps->start2 = -1; mps->end2 = -1; while ((state = camel_mime_parser_step (cmp, &buf, &len)) != CAMEL_MIME_PARSER_STATE_MULTIPART_END) { if (mps->start1 == -1) { mps->start1 = camel_mime_parser_tell_start_headers (cmp); } else if (mps->start2 == -1) { mps->start2 = camel_mime_parser_tell_start_headers (cmp); mps->end1 = camel_mime_parser_tell_start_boundary (cmp); if (mps->end1 > mps->start1 && byte_array->data[mps->end1 - 1] == '\n') mps->end1--; if (mps->end1 > mps->start1 && byte_array->data[mps->end1 - 1] == '\r') mps->end1--; } else { g_warning ("multipart/signed has more than 2 parts, remaining parts ignored"); state = CAMEL_MIME_PARSER_STATE_MULTIPART_END; break; } if (multipart_signed_skip_content (cmp) == -1) break; } if (state == CAMEL_MIME_PARSER_STATE_MULTIPART_END) { mps->end2 = camel_mime_parser_tell_start_boundary (cmp); camel_multipart_set_preface (mp, camel_mime_parser_preface (cmp)); camel_multipart_set_postface (mp, camel_mime_parser_postface (cmp)); } g_object_unref (cmp); g_object_unref (stream); if (mps->end2 == -1 || mps->start2 == -1) { if (mps->end1 == -1) mps->start1 = -1; return -1; } return 0; }