static gboolean mime_message_construct_from_parser_sync (CamelMimePart *dw, CamelMimeParser *mp, GCancellable *cancellable, GError **error) { CamelMimePartClass *mime_part_class; gchar *buf; gsize len; gint state; gint err; gboolean success; /* let the mime-part construct the guts ... */ mime_part_class = CAMEL_MIME_PART_CLASS (camel_mime_message_parent_class); success = mime_part_class->construct_from_parser_sync ( dw, mp, cancellable, error); if (!success) return FALSE; /* ... then clean up the follow-on state */ state = camel_mime_parser_step (mp, &buf, &len); switch (state) { case CAMEL_MIME_PARSER_STATE_EOF: case CAMEL_MIME_PARSER_STATE_FROM_END: /* these doesn't belong to us */ camel_mime_parser_unstep (mp); case CAMEL_MIME_PARSER_STATE_MESSAGE_END: break; default: g_error ("Bad parser state: Expecing MESSAGE_END or EOF or EOM, got: %u", camel_mime_parser_state (mp)); camel_mime_parser_unstep (mp); return FALSE; } err = camel_mime_parser_errno (mp); if (err != 0) { errno = err; g_set_error ( error, G_IO_ERROR, g_io_error_from_errno (errno), "%s", g_strerror (errno)); success = FALSE; } return success; }
static gint multipart_signed_skip_content (CamelMimeParser *cmp) { gchar *buf; gsize len; gint state; switch (camel_mime_parser_state (cmp)) { case CAMEL_MIME_PARSER_STATE_HEADER: /* body part */ while (camel_mime_parser_step (cmp, &buf, &len) != CAMEL_MIME_PARSER_STATE_BODY_END) /* NOOP */ ; break; case CAMEL_MIME_PARSER_STATE_MESSAGE: /* message body part */ (void) camel_mime_parser_step (cmp, &buf, &len); multipart_signed_skip_content (cmp); /* clean up followon state if any, see camel-mime-message.c */ state = camel_mime_parser_step (cmp, &buf, &len); switch (state) { case CAMEL_MIME_PARSER_STATE_EOF: case CAMEL_MIME_PARSER_STATE_FROM_END: /* these doesn't belong to us */ camel_mime_parser_unstep (cmp); case CAMEL_MIME_PARSER_STATE_MESSAGE_END: break; default: g_error ("Bad parser state: Expecting MESSAGE_END or EOF or EOM, got: %u", camel_mime_parser_state (cmp)); camel_mime_parser_unstep (cmp); return -1; } break; case CAMEL_MIME_PARSER_STATE_MULTIPART: /* embedded multipart */ while (camel_mime_parser_step (cmp, &buf, &len) != CAMEL_MIME_PARSER_STATE_MULTIPART_END) multipart_signed_skip_content (cmp); break; default: g_warning ("Invalid state encountered???: %u", camel_mime_parser_state (cmp)); } return 0; }
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; }
/* Well, since Solaris is a tad broken wrt its 'mbox' folder format, * we must convert it to a real mbox format. Thankfully this is * mostly pretty easy */ static gint camel_movemail_solaris (gint oldsfd, gint dfd, GError **error) { CamelMimeParser *mp; gchar *buffer; gint len; gint sfd; CamelMimeFilter *ffrom; gint ret = 1; gchar *from = NULL; /* need to dup as the mime parser will close on finish */ sfd = dup (oldsfd); if (sfd == -1) { g_set_error ( error, G_IO_ERROR, g_io_error_from_errno (errno), _("Error copying mail temp file: %s"), g_strerror (errno)); return -1; } mp = camel_mime_parser_new (); camel_mime_parser_scan_from (mp, TRUE); camel_mime_parser_init_with_fd (mp, sfd); ffrom = camel_mime_filter_from_new (); while (camel_mime_parser_step (mp, &buffer, &len) == CAMEL_MIME_PARSER_STATE_FROM) { g_return_val_if_fail (camel_mime_parser_from_line (mp), -1); from = g_strdup (camel_mime_parser_from_line (mp)); if (camel_mime_parser_step (mp, &buffer, &len) != CAMEL_MIME_PARSER_STATE_FROM_END) { CamelNameValueArray *headers; const gchar *cl; gint length; gint start, body; goffset newpos; ret = 0; start = camel_mime_parser_tell_start_from (mp); body = camel_mime_parser_tell (mp); if (write (dfd, from, strlen (from)) != strlen (from)) goto fail; /* write out headers, but NOT content-length header */ headers = camel_mime_parser_dup_headers (mp); if (solaris_header_write (dfd, headers) == -1) { camel_name_value_array_free (headers); goto fail; } camel_name_value_array_free (headers); cl = camel_mime_parser_header (mp, "content-length", NULL); if (cl == NULL) { g_warning ("Required Content-Length header is missing from solaris mail box @ %d", (gint) camel_mime_parser_tell (mp)); camel_mime_parser_drop_step (mp); camel_mime_parser_drop_step (mp); camel_mime_parser_step (mp, &buffer, &len); camel_mime_parser_unstep (mp); length = camel_mime_parser_tell_start_from (mp) - body; newpos = -1; } else { length = atoi (cl); camel_mime_parser_drop_step (mp); camel_mime_parser_drop_step (mp); newpos = length + body; } /* copy body->length converting From lines */ if (camel_movemail_copy_filter (sfd, dfd, body, length, ffrom) == -1) goto fail; if (newpos != -1) camel_mime_parser_seek (mp, newpos, SEEK_SET); } else { g_error ("Inalid parser state: %d", camel_mime_parser_state (mp)); } g_free (from); } g_object_unref (mp); g_object_unref (ffrom); return ret; fail: g_free (from); g_set_error ( error, G_IO_ERROR, g_io_error_from_errno (errno), _("Error copying mail temp file: %s"), g_strerror (errno)); g_object_unref (mp); g_object_unref (ffrom); return -1; }