static gboolean
mbox_folder_append_message_sync (CamelFolder *folder,
                                 CamelMimeMessage *message,
                                 CamelMessageInfo *info,
                                 gchar **appended_uid,
                                 GCancellable *cancellable,
                                 GError **error)
{
	CamelLocalFolder *lf = (CamelLocalFolder *) folder;
	CamelStream *output_stream = NULL, *filter_stream = NULL;
	CamelMimeFilter *filter_from;
	CamelMboxSummary *mbs = (CamelMboxSummary *) folder->summary;
	CamelMessageInfo *mi;
	gchar *fromline = NULL;
	struct stat st;
	gint retval;
	gboolean has_attachment;
#if 0
	gchar *xev;
#endif
	/* If we can't lock, dont do anything */
	if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1)
		return FALSE;

	d (printf ("Appending message\n"));

	/* first, check the summary is correct (updates folder_size too) */
	retval = camel_local_summary_check ((CamelLocalSummary *) folder->summary, lf->changes, cancellable, error);
	if (retval == -1)
		goto fail;

	/* add it to the summary/assign the uid, etc */
	mi = camel_local_summary_add ((CamelLocalSummary *) folder->summary, message, info, lf->changes, error);
	if (mi == NULL)
		goto fail;

	d (printf ("Appending message: uid is %s\n", camel_message_info_get_uid (mi)));

	has_attachment = camel_mime_message_has_attachment (message);
	if (((camel_message_info_get_flags (mi) & CAMEL_MESSAGE_ATTACHMENTS) && !has_attachment) ||
	    ((camel_message_info_get_flags (mi) & CAMEL_MESSAGE_ATTACHMENTS) == 0 && has_attachment)) {
		camel_message_info_set_flags (mi, CAMEL_MESSAGE_ATTACHMENTS, has_attachment ? CAMEL_MESSAGE_ATTACHMENTS : 0);
	}

	output_stream = camel_stream_fs_new_with_name (
		lf->folder_path, O_WRONLY | O_APPEND |
		O_LARGEFILE, 0666, error);
	if (output_stream == NULL) {
		g_prefix_error (
			error, _("Cannot open mailbox: %s: "),
			lf->folder_path);
		goto fail;
	}

	/* and we need to set the frompos/XEV explicitly */
	((CamelMboxMessageInfo *) mi)->frompos = mbs->folder_size;
#if 0
	xev = camel_local_summary_encode_x_evolution ((CamelLocalSummary *) folder->summary, mi);
	if (xev) {
		/* the x-ev header should match the 'current' flags, no problem, so store as much */
		camel_medium_set_header ((CamelMedium *) message, "X-Evolution", xev);
		mi->flags &= ~ CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_FLAGGED;
		g_free (xev);
	}
#endif

	/* we must write this to the non-filtered stream ... */
	fromline = camel_mime_message_build_mbox_from (message);
	if (camel_stream_write (output_stream, fromline, strlen (fromline), cancellable, error) == -1)
		goto fail_write;

	/* and write the content to the filtering stream, that translates '\nFrom' into '\n>From' */
	filter_stream = camel_stream_filter_new (output_stream);
	filter_from = camel_mime_filter_from_new ();
	camel_stream_filter_add ((CamelStreamFilter *) filter_stream, filter_from);
	g_object_unref (filter_from);

	if (camel_data_wrapper_write_to_stream_sync (
		(CamelDataWrapper *) message, filter_stream, cancellable, error) == -1 ||
	    camel_stream_write (filter_stream, "\n", 1, cancellable, error) == -1 ||
	    camel_stream_flush (filter_stream, cancellable, error) == -1)
		goto fail_write;

	/* filter stream ref's the output stream itself, so we need to unref it too */
	g_object_unref (filter_stream);
	g_object_unref (output_stream);
	g_free (fromline);

	if (!((CamelMessageInfoBase *) mi)->preview && camel_folder_summary_get_need_preview (folder->summary)) {
		if (camel_mime_message_build_preview ((CamelMimePart *) message, mi) && ((CamelMessageInfoBase *) mi)->preview)
			camel_folder_summary_add_preview (folder->summary, mi);
	}

	/* now we 'fudge' the summary  to tell it its uptodate, because its idea of uptodate has just changed */
	/* the stat really shouldn't fail, we just wrote to it */
	if (g_stat (lf->folder_path, &st) == 0) {
		((CamelFolderSummary *) mbs)->time = st.st_mtime;
		mbs->folder_size = st.st_size;
	}

	/* unlock as soon as we can */
	camel_local_folder_unlock (lf);

	if (camel_folder_change_info_changed (lf->changes)) {
		camel_folder_changed (folder, lf->changes);
		camel_folder_change_info_clear (lf->changes);
	}

	if (appended_uid)
		*appended_uid = g_strdup(camel_message_info_get_uid(mi));

	return TRUE;

fail_write:
	g_prefix_error (
		error, _("Cannot append message to mbox file: %s: "),
		lf->folder_path);

	if (output_stream) {
		gint fd;

		fd = camel_stream_fs_get_fd (CAMEL_STREAM_FS (output_stream));
		if (fd != -1) {
			/* reset the file to original size */
			do {
				retval = ftruncate (fd, mbs->folder_size);
			} while (retval == -1 && errno == EINTR);
		}

		g_object_unref (output_stream);
	}

	if (filter_stream)
		g_object_unref (filter_stream);

	g_free (fromline);

	/* remove the summary info so we are not out-of-sync with the mbox */
	camel_folder_summary_remove (CAMEL_FOLDER_SUMMARY (mbs), mi);

	/* and tell the summary it's up-to-date */
	if (g_stat (lf->folder_path, &st) == 0) {
		((CamelFolderSummary *) mbs)->time = st.st_mtime;
		mbs->folder_size = st.st_size;
	}

fail:
	/* make sure we unlock the folder - before we start triggering events into appland */
	camel_local_folder_unlock (lf);

	/* cascade the changes through, anyway, if there are any outstanding */
	if (camel_folder_change_info_changed (lf->changes)) {
		camel_folder_changed (folder, lf->changes);
		camel_folder_change_info_clear (lf->changes);
	}

	return FALSE;
}
/* 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;
}