Ejemplo n.º 1
0
static ssize_t
mime_part_write_to_stream (GMimeObject *object, GMimeStream *stream)
{
	GMimePart *mime_part = (GMimePart *) object;
	ssize_t nwritten, total = 0;
	
	/* write the content headers */
	if ((nwritten = g_mime_header_list_write_to_stream (object->headers, stream)) == -1)
		return -1;
	
	total += nwritten;
	
	/* terminate the headers */
	if (g_mime_stream_write (stream, "\n", 1) == -1)
		return -1;
	
	total++;
	
	if ((nwritten = write_content (mime_part, stream)) == -1)
		return -1;
	
	total += nwritten;
	
	return total;
}
/**
 * g_mime_stream_writev:
 * @stream: a #GMimeStream
 * @vector: a #GMimeStreamIOVector
 * @count: number of vector elements
 *
 * Writes at most @count blocks described by @vector to @stream.
 *
 * Returns: the number of bytes written or %-1 on fail.
 **/
ssize_t
g_mime_stream_writev (GMimeStream *stream, GMimeStreamIOVector *vector, size_t count)
{
	ssize_t total = 0;
	size_t i;
	
	g_return_val_if_fail (GMIME_IS_STREAM (stream), -1);
	
	for (i = 0; i < count; i++) {
		char *buffer = vector[i].data;
		size_t nwritten = 0;
		ssize_t n;
		
		while (nwritten < vector[i].len) {
			if ((n = g_mime_stream_write (stream, buffer + nwritten,
						      vector[i].len - nwritten)) < 0)
				return -1;
			
			nwritten += n;
		}
		
		total += nwritten;
	}
	
	return total;
}
/**
 * g_mime_stream_write_to_stream:
 * @src: source stream
 * @dest: destination stream
 *
 * Attempts to write the source stream to the destination stream.
 *
 * Returns: the number of bytes written or %-1 on fail.
 **/
ssize_t
g_mime_stream_write_to_stream (GMimeStream *src, GMimeStream *dest)
{
	ssize_t nread, nwritten, total = 0;
	char buf[4096];
	
	g_return_val_if_fail (GMIME_IS_STREAM (src), -1);
	g_return_val_if_fail (GMIME_IS_STREAM (dest), -1);
	
	while (!g_mime_stream_eos (src)) {
		if ((nread = g_mime_stream_read (src, buf, sizeof (buf))) < 0)
			return -1;
		
		if (nread > 0) {
			nwritten = 0;
			while (nwritten < nread) {
				ssize_t len;
				
				if ((len = g_mime_stream_write (dest, buf + nwritten, nread - nwritten)) < 0)
					return -1;
				
				nwritten += len;
			}
			
			total += nwritten;
		}
	}
	
	return total;
}
Ejemplo n.º 4
0
static ssize_t
write_content_type (GMimeStream *stream, const char *name, const char *value)
{
	GMimeContentType *content_type;
	ssize_t nwritten;
	GString *out;
	char *val;
	
	out = g_string_new ("");
	g_string_printf (out, "%s: ", name);
	
	content_type = g_mime_content_type_new_from_string (value);
	
	val = g_mime_content_type_to_string (content_type);
	g_string_append (out, val);
	g_free (val);
	
	g_mime_param_write_to_string (content_type->params, TRUE, out);
	g_object_unref (content_type);
	
	nwritten = g_mime_stream_write (stream, out->str, out->len);
	g_string_free (out, TRUE);
	
	return nwritten;
}
Ejemplo n.º 5
0
static void
test_html (const char *datadir, const char *input, const char *output, guint32 citation)
{
	guint32 flags = GMIME_FILTER_HTML_CONVERT_NL | GMIME_FILTER_HTML_CONVERT_SPACES |
		GMIME_FILTER_HTML_CONVERT_URLS | GMIME_FILTER_HTML_CONVERT_ADDRESSES;
	const char *what = "GMimeFilterHtml", *mode;
	GByteArray *expected, *actual;
	GMimeStream *stream;
	GMimeFilter *filter;
	char *path;
	
	switch (citation) {
	case GMIME_FILTER_HTML_BLOCKQUOTE_CITATION: mode = "blockquote"; break;
	case GMIME_FILTER_HTML_MARK_CITATION: mode = "mark"; break;
	case GMIME_FILTER_HTML_CITE: mode = "cite"; break;
	default: mode = "none"; break;
	}
	
	testsuite_check ("%s (%s %s)", what, input, mode);
	
	actual = g_byte_array_new ();
	stream = g_mime_stream_mem_new_with_byte_array (actual);
	g_mime_stream_mem_set_owner ((GMimeStreamMem *) stream, FALSE);
	
	filter = g_mime_filter_html_new (flags | citation, 0x008888);
	
	path = g_build_filename (datadir, input, NULL);
	pump_data_through_filter (filter, path, stream, TRUE, TRUE);
	g_mime_filter_reset (filter);
	g_object_unref (stream);
	g_object_unref (filter);
	g_free (path);
	
	path = g_build_filename (datadir, output, NULL);
	expected = read_all_bytes (path, TRUE);
	g_free (path);
	
	if (actual->len != expected->len) {
		testsuite_check_failed ("%s failed: stream lengths do not match: expected=%u; actual=%u",
					what, expected->len, actual->len);
		stream = g_mime_stream_fs_open (output, O_WRONLY | O_CREAT, 0644, NULL);
		g_mime_stream_write (stream, (const char *) actual->data, actual->len);
		g_mime_stream_flush (stream);
		g_object_unref (stream);
		goto error;
	}
	
	if (memcmp (actual->data, expected->data, actual->len) != 0) {
		testsuite_check_failed ("%s failed: stream contents do not match", what);
		goto error;
	}
	
	testsuite_check_passed ();
	
error:
	
	g_byte_array_free (expected, TRUE);
	g_byte_array_free (actual, TRUE);
}
Ejemplo n.º 6
0
static void
print_depth (GMimeStream *stream, int depth)
{
	int i;
	
	for (i = 0; i < depth; i++)
		g_mime_stream_write (stream, INDENT, strlen (INDENT));
}
/**
 * g_mime_stream_write_string:
 * @stream: a #GMimeStream
 * @str: string to write
 *
 * Writes @string to @stream.
 *
 * Returns: the number of bytes written or %-1 on fail.
 **/
ssize_t
g_mime_stream_write_string (GMimeStream *stream, const char *str)
{
	g_return_val_if_fail (GMIME_IS_STREAM (stream), -1);
	g_return_val_if_fail (str != NULL, -1);
	
	return g_mime_stream_write (stream, str, strlen (str));
}
Ejemplo n.º 8
0
static void
test_gzip (const char *datadir, const char *filename)
{
	char *name = g_strdup_printf ("%s.gz", filename);
	char *path = g_build_filename (datadir, filename, NULL);
	const char *what = "GMimeFilterGzip::zip";
	GByteArray *actual, *expected;
	GMimeStream *stream;
	GMimeFilter *filter;
	
	testsuite_check ("%s", what);
	
	actual = g_byte_array_new ();
	stream = g_mime_stream_mem_new_with_byte_array (actual);
	g_mime_stream_mem_set_owner ((GMimeStreamMem *) stream, FALSE);
	
	filter = g_mime_filter_gzip_new (GMIME_FILTER_GZIP_MODE_ZIP, 9);
	g_mime_filter_gzip_set_filename ((GMimeFilterGZip *) filter, filename);
	g_mime_filter_gzip_set_comment ((GMimeFilterGZip *) filter, "This is a comment.");
	
	pump_data_through_filter (filter, path, stream, TRUE, TRUE);
	g_mime_filter_reset (filter);
	g_object_unref (stream);
	g_object_unref (filter);
	g_free (path);
	
	path = g_build_filename (datadir, name, NULL);
	expected = read_all_bytes (path, FALSE);
	g_free (name);
	g_free (path);
	
	if (actual->len != 1233 && (actual->len != expected->len || memcmp (actual->data, expected->data, actual->len) != 0)) {
		if (actual->len != expected->len)
			testsuite_check_failed ("%s failed: streams are not the same length: %u", what, actual->len);
		else
			testsuite_check_failed ("%s failed: streams do not match", what);
		
		name = g_strdup_printf ("%s.1.gz", filename);
		path = g_build_filename (datadir, name, NULL);
		g_free (name);
		
		stream = g_mime_stream_fs_open (path, O_WRONLY | O_CREAT | O_TRUNC, 0644, NULL);
		g_free (path);
		
		g_mime_stream_write (stream, (const char *) actual->data, actual->len);
		g_mime_stream_flush (stream);
		g_object_unref (stream);
	} else {
		testsuite_check_passed ();
	}
	
	g_byte_array_free (expected, TRUE);
	g_byte_array_free (actual, TRUE);
}
Ejemplo n.º 9
0
static GMimeStream *
random_whole_stream (const char *datadir, char **filename)
{
	size_t nwritten, buflen, total = 0, size, i;
	GMimeStream *stream;
	char buf[4096];
	ssize_t n;
	int fd;
	
	/* read between 4k and 14k bytes */
	size = 4096 + (size_t) (10240.0 * (rand () / (RAND_MAX + 1.0)));
	v(fprintf (stdout, "Generating %zu bytes of random data... ", size));
	v(fflush (stdout));
	
	g_mkdir_with_parents (datadir, 0755);
	
	g_snprintf (buf, sizeof (buf), "%s%cstream.%u", datadir, G_DIR_SEPARATOR, getpid ());
	if ((fd = open (buf, O_CREAT | O_TRUNC | O_RDWR, 0666)) == -1) {
		fprintf (stderr, "Error: Cannot create `%s': %s\n", buf, g_strerror (errno));
		exit (EXIT_FAILURE);
	}
	
	*filename = g_strdup (buf);
	
	stream = g_mime_stream_fs_new (fd);
	
	while (total < size) {
		buflen = size - total > sizeof (buf) ? sizeof (buf) : size - total;
		for (i = 0; i < buflen; i++)
			buf[i] = (char) (255 * (rand () / (RAND_MAX + 1.0)));
		
		nwritten = 0;
		do {
			if ((n = g_mime_stream_write (stream, buf + nwritten, buflen - nwritten)) <= 0)
				break;
			nwritten += n;
			total += n;
		} while (nwritten < buflen);
		
		if (nwritten < buflen)
			break;
	}
	
	g_mime_stream_flush (stream);
	g_mime_stream_reset (stream);
	
	v(fputs ("done\n", stdout));
	
	return stream;
}
Ejemplo n.º 10
0
static ssize_t
write_disposition (GMimeStream *stream, const char *name, const char *value)
{
	GMimeContentDisposition *disposition;
	ssize_t nwritten;
	GString *out;
	
	out = g_string_new ("");
	g_string_printf (out, "%s: ", name);
	
	disposition = g_mime_content_disposition_new_from_string (value);
	g_string_append (out, disposition->disposition);
	
	g_mime_param_write_to_string (disposition->params, TRUE, out);
	g_object_unref (disposition);
	
	nwritten = g_mime_stream_write (stream, out->str, out->len);
	g_string_free (out, TRUE);
	
	return nwritten;
}
Ejemplo n.º 11
0
/**
 * g_mime_stream_printf:
 * @stream: a #GMimeStream
 * @fmt: format
 * @Varargs: arguments
 *
 * Write formatted output to a stream.
 *
 * Returns: the number of bytes written or %-1 on fail.
 **/
ssize_t
g_mime_stream_printf (GMimeStream *stream, const char *fmt, ...)
{
	va_list args;
	char *string;
	ssize_t ret;
	
	g_return_val_if_fail (GMIME_IS_STREAM (stream), -1);
	g_return_val_if_fail (fmt != NULL, -1);
	
	va_start (args, fmt);
	string = g_strdup_vprintf (fmt, args);
	va_end (args);
	
	if (!string)
		return -1;
	
	ret = g_mime_stream_write (stream, string, strlen (string));
	g_free (string);
	
	return ret;
}
Ejemplo n.º 12
0
static void
read_msg (SpruceFolder *folder, GPtrArray *uids, int cursor)
{
	GMimeMessage *message;
	GMimeStream *stream;
	GError *err = NULL;
	
	if (!(message = spruce_folder_get_message (folder, uids->pdata[cursor], &err))) {
		fprintf (stderr, "can't get message: %s\n", err ? err->message : "(null)");
		g_error_free (err);
		return;
	}
	
	stream = g_mime_stream_fs_new (dup (fileno (stdout)));
	g_mime_object_write_to_stream ((GMimeObject *) message, stream);
	g_mime_stream_write (stream, "\n", 1);
	g_mime_stream_flush (stream);
	g_object_unref (message);
	g_object_unref (stream);
	
	mark_msgs (folder, uids, NULL, cursor, SPRUCE_MESSAGE_SEEN, SPRUCE_MESSAGE_SEEN);
}
Ejemplo n.º 13
0
static void
lsv_escape_change_state(GSimpleAction * action,
                        GVariant      * state,
                        gpointer        user_data)
{
    LibBalsaSourceViewerInfo *lsvi =
        g_object_get_data(G_OBJECT(user_data), "lsvi");
    LibBalsaMessage *msg = lsvi->msg;
    GMimeStream *msg_stream;
    GMimeStream *mem_stream;
    char *raw_message;

    if (!msg->mailbox) {
	libbalsa_information(LIBBALSA_INFORMATION_WARNING,
			     _("Mailbox closed"));
	return;
    }
    msg_stream = libbalsa_mailbox_get_message_stream(msg->mailbox, msg->msgno,
						     TRUE);
    if (msg_stream == NULL)
	return;

    mem_stream = g_mime_stream_mem_new();
    libbalsa_mailbox_lock_store(msg->mailbox);
    g_mime_stream_write_to_stream(msg_stream, mem_stream);
    libbalsa_mailbox_unlock_store(msg->mailbox);
    g_mime_stream_write(mem_stream, "", 1); /* close string */
    raw_message = (char *) GMIME_STREAM_MEM(mem_stream)->buffer->data;

    *(lsvi->escape_specials) = g_variant_get_boolean(state);
    lsv_show_message(raw_message, lsvi, *(lsvi->escape_specials));

    g_object_unref(msg_stream);
    g_object_unref(mem_stream);

    g_simple_action_set_state(action, state);
}
Ejemplo n.º 14
0
static size_t
gen_random_stream (GMimeStream *stream)
{
	size_t nwritten, buflen, total = 0, size, i;
	char buf[4096];
	ssize_t n;
	
	/* read between 4k and 14k bytes */
	size = 4096 + (size_t) (10240.0 * (rand () / (RAND_MAX + 1.0)));
	v(fprintf (stdout, "Generating %" G_GSIZE_FORMAT " bytes of random data... ", size));
	v(fflush (stdout));
	
	while (total < size) {
		buflen = size - total > sizeof (buf) ? sizeof (buf) : size - total;
		for (i = 0; i < buflen; i++)
			buf[i] = (char) (255 * (rand () / (RAND_MAX + 1.0)));
		
		nwritten = 0;
		do {
			if ((n = g_mime_stream_write (stream, buf + nwritten, buflen - nwritten)) <= 0)
				break;
			nwritten += n;
			total += n;
		} while (nwritten < buflen);
		
		if (nwritten < buflen)
			break;
	}
	
	g_mime_stream_flush (stream);
	g_mime_stream_reset (stream);
	
	v(fputs ("done\n", stdout));

	return size;
}
Ejemplo n.º 15
0
static ssize_t
message_part_write_to_stream (GMimeObject *object, GMimeFormatOptions *options, gboolean content_only, GMimeStream *stream)
{
	GMimeMessagePart *part = (GMimeMessagePart *) object;
	GMimeMessage *message = part->message;
	ssize_t nwritten, total = 0;
	const char *newline, *eoln;
	gboolean match;
	size_t len;
	
	newline = g_mime_format_options_get_newline (options);
	
	if (!content_only) {
		/* write the content headers */
		if ((nwritten = g_mime_header_list_write_to_stream (object->headers, options, stream)) == -1)
			return -1;
		
		total += nwritten;
		
		/* terminate the headers */
		if ((nwritten = g_mime_stream_write_string (stream, newline)) == -1)
			return -1;
		
		total += nwritten;
	}
	
	/* write the message */
	if (message) {
		if (message->marker && (len = strlen (message->marker)) > 0) {
			if (*(eoln = message->marker + (len - 1)) == '\n') {
				if (eoln > message->marker && eoln[-1] == '\r')
					eoln--;
				
				/* check if newline sequences match... */
				if (!(match = !strcmp (eoln, newline))) {
					/* they don't match... trim off the eoln sequence */
					len = (size_t) (eoln - message->marker);
				}
			} else {
				match = FALSE;
			}
			
			if ((nwritten = g_mime_stream_write (stream, message->marker, len)) == -1)
				return -1;
			
			total += nwritten;
			
			if (!match) {
				if ((nwritten = g_mime_stream_write_string (stream, newline)) == -1)
					return -1;
				
				total += nwritten;
			}
		}
		
		if ((nwritten = g_mime_object_write_to_stream ((GMimeObject *) message, options, stream)) == -1)
			return -1;
		
		total += nwritten;
	}
	
	return total;
}
Ejemplo n.º 16
0
static void
test_parser (GMimeParser *parser, GMimeStream *mbox, GMimeStream *summary)
{
	gint64 message_begin, message_end, headers_begin, headers_end;
	GMimeFormatOptions *format = g_mime_format_options_get_default ();
	InternetAddressList *list;
	GMimeMessage *message;
	char *marker, *buf;
	const char *subject;
	GMimeObject *body;
	GDateTime *date;
	int nmsg = 0;
	
	while (!g_mime_parser_eos (parser)) {
		message_begin = g_mime_parser_tell (parser);
		if (!(message = g_mime_parser_construct_message (parser, NULL)))
			throw (exception_new ("failed to parse message #%d", nmsg));
		
		message_end = g_mime_parser_tell (parser);
		
		headers_begin = g_mime_parser_get_headers_begin (parser);
		headers_end = g_mime_parser_get_headers_end (parser);
		
		g_mime_stream_printf (summary, "message offsets: %" G_GINT64_FORMAT ", %" G_GINT64_FORMAT "\n",
				      message_begin, message_end);
		g_mime_stream_printf (summary, "header offsets: %" G_GINT64_FORMAT ", %" G_GINT64_FORMAT "\n",
				      headers_begin, headers_end);
		
		marker = g_mime_parser_get_mbox_marker (parser);
		g_mime_stream_printf (summary, "%s\n", marker);
		
		if ((list = g_mime_message_get_from (message)) != NULL &&
		    internet_address_list_length (list) > 0) {
			buf = internet_address_list_to_string (list, format, FALSE);
			g_mime_stream_printf (summary, "From: %s\n", buf);
			g_free (buf);
		}
		
		if ((list = g_mime_message_get_addresses (message, GMIME_ADDRESS_TYPE_TO)) != NULL &&
		    internet_address_list_length (list) > 0) {
			buf = internet_address_list_to_string (list, format, FALSE);
			g_mime_stream_printf (summary, "To: %s\n", buf);
			g_free (buf);
		}
		
		if (!(subject = g_mime_message_get_subject (message)))
			subject = "";
		g_mime_stream_printf (summary, "Subject: %s\n", subject);
		
		if (!(date = g_mime_message_get_date (message))) {
			date = g_date_time_new_from_unix_utc (0);
		} else {
			g_date_time_ref (date);
		}
		buf = g_mime_utils_header_format_date (date);
		g_mime_stream_printf (summary, "Date: %s\n", buf);
		g_date_time_unref (date);
		g_free (buf);
		
		body = g_mime_message_get_mime_part (message);
		print_mime_struct (summary, body, 0);
		g_mime_stream_write (summary, "\n", 1);
		
		if (mbox) {
			if (nmsg > 0)
				g_mime_stream_write (mbox, "\n", 1);
			
			g_mime_stream_printf (mbox, "%s\n", marker);
			g_mime_object_write_to_stream ((GMimeObject *) message, format, mbox);
		}
		
		g_object_unref (message);
		g_free (marker);
		nmsg++;
	}
}
Ejemplo n.º 17
0
static ssize_t
write_content (GMimePart *part, GMimeStream *stream)
{
	ssize_t nwritten, total = 0;
	
	if (!part->content)
		return 0;
	
	/* Evil Genius's "slight" optimization: Since GMimeDataWrapper::write_to_stream()
	 * decodes its content stream to the raw format, we can cheat by requesting its
	 * content stream and not doing any encoding on the data if the source and
	 * destination encodings are identical.
	 */
	
	if (part->encoding != g_mime_data_wrapper_get_encoding (part->content)) {
		GMimeStream *filtered_stream;
		const char *filename;
		GMimeFilter *filter;
		
		switch (part->encoding) {
		case GMIME_CONTENT_ENCODING_UUENCODE:
			filename = g_mime_part_get_filename (part);
			nwritten = g_mime_stream_printf (stream, "begin 0644 %s\n",
							 filename ? filename : "unknown");
			if (nwritten == -1)
				return -1;
			
			total += nwritten;
			
			/* fall thru... */
		case GMIME_CONTENT_ENCODING_QUOTEDPRINTABLE:
		case GMIME_CONTENT_ENCODING_BASE64:
			filtered_stream = g_mime_stream_filter_new (stream);
			filter = g_mime_filter_basic_new (part->encoding, TRUE);
			g_mime_stream_filter_add (GMIME_STREAM_FILTER (filtered_stream), filter);
			g_object_unref (filter);
			break;
		default:
			filtered_stream = stream;
			g_object_ref (stream);
			break;
		}
		
		nwritten = g_mime_data_wrapper_write_to_stream (part->content, filtered_stream);
		g_mime_stream_flush (filtered_stream);
		g_object_unref (filtered_stream);
		
		if (nwritten == -1)
			return -1;
		
		total += nwritten;
		
		if (part->encoding == GMIME_CONTENT_ENCODING_UUENCODE) {
			/* FIXME: get rid of this special-case x-uuencode crap */
			nwritten = g_mime_stream_write (stream, "end\n", 4);
			if (nwritten == -1)
				return -1;
			
			total += nwritten;
		}
	} else {
		GMimeStream *content_stream;
		
		content_stream = g_mime_data_wrapper_get_stream (part->content);
		g_mime_stream_reset (content_stream);
		nwritten = g_mime_stream_write_to_stream (content_stream, stream);
		g_mime_stream_reset (content_stream);
		
		if (nwritten == -1)
			return -1;
		
		total += nwritten;
	}
	
	return total;
}
Ejemplo n.º 18
0
static ssize_t
pkcs7_stream_write (void *stream, const void *buffer, size_t size)
{
	return g_mime_stream_write ((GMimeStream *) stream, (const char *) buffer, size);
}
Ejemplo n.º 19
0
static ssize_t
multipart_write_to_stream (GMimeObject *object, GMimeStream *stream)
{
	GMimeMultipart *multipart = (GMimeMultipart *) object;
	ssize_t nwritten, total = 0;
	const char *boundary;
	GMimeObject *part;
	guint i;
	
	/* make sure a boundary is set unless we are writing out a raw
	 * header (in which case it should already be set... or if
	 * not, then it's a broken multipart and so we don't want to
	 * alter it or we'll completely break the output) */
	boundary = g_mime_object_get_content_type_parameter (object, "boundary");
	if (!boundary && !g_mime_header_list_get_stream (object->headers)) {
		g_mime_multipart_set_boundary (multipart, NULL);
		boundary = g_mime_object_get_content_type_parameter (object, "boundary");
	}
	
	/* write the content headers */
	if ((nwritten = g_mime_header_list_write_to_stream (object->headers, stream)) == -1)
		return -1;
	
	total += nwritten;
	
	/* write the preface */
	if (multipart->preface) {
		/* terminate the headers */
		if (g_mime_stream_write (stream, "\n", 1) == -1)
			return -1;
		
		total++;
		
		if ((nwritten = g_mime_stream_write_string (stream, multipart->preface)) == -1)
			return -1;
		
		total += nwritten;
	}
	
	for (i = 0; i < multipart->children->len; i++) {
		part = multipart->children->pdata[i];
		
		/* write the boundary */
		if ((nwritten = g_mime_stream_printf (stream, "\n--%s\n", boundary)) == -1)
			return -1;
		
		total += nwritten;
		
		/* write this part out */
		if ((nwritten = g_mime_object_write_to_stream (part, stream)) == -1)
			return -1;
		
		total += nwritten;
	}
	
	/* write the end-boundary (but only if a boundary is set) */
	if (boundary) {
		if ((nwritten = g_mime_stream_printf (stream, "\n--%s--\n", boundary)) == -1)
			return -1;
		
		total += nwritten;
	}
	
	/* write the postface */
	if (multipart->postface) {
		if ((nwritten = g_mime_stream_write_string (stream, multipart->postface)) == -1)
			return -1;
		
		total += nwritten;
	}
	
	return total;
}
Ejemplo n.º 20
0
/*
 * callback to write data to a stream
 */
static ssize_t
g_mime_gpgme_stream_wr(GMimeStream * stream, void *buffer, size_t size)
{
    return g_mime_stream_write(stream, buffer, size);
}