Ejemplo n.º 1
0
/**
 * mail_importer_add_line:
 * importer: A MailImporter structure.
 * str: Next line of the mbox.
 * finished: TRUE if @str is the last line of the message.
 *
 * Adds lines to the message until it is finished, and then adds
 * the complete message to the folder.
 */
void
mail_importer_add_line (MailImporter *importer,
			const char *str,
			gboolean finished)
{
	CamelMimeMessage *msg;
	CamelMessageInfo *info;
	CamelException *ex;

	if (importer->mstream == NULL)
		importer->mstream = CAMEL_STREAM_MEM (camel_stream_mem_new ());

	camel_stream_write (CAMEL_STREAM (importer->mstream), str,  strlen (str));

	if (finished == FALSE)
		return;

	camel_stream_reset (CAMEL_STREAM (importer->mstream));
	info = camel_message_info_new(NULL);
	camel_message_info_set_flags(info, CAMEL_MESSAGE_SEEN, ~0);

	msg = camel_mime_message_new ();
	camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg),
						  CAMEL_STREAM (importer->mstream));

	camel_object_unref (importer->mstream);
	importer->mstream = NULL;

	ex = camel_exception_new ();
	camel_folder_append_message (importer->folder, msg, info, NULL, ex);
	camel_object_unref (msg);

	camel_exception_free (ex);
	camel_message_info_free(info);
}
Ejemplo n.º 2
0
static void
save_snapshot_get_message_cb (EMsgComposer *composer,
                              GAsyncResult *result,
                              GSimpleAsyncResult *simple)
{
	SaveContext *context;
	CamelMimeMessage *message;
	GInputStream *input_stream;
	CamelStream *camel_stream;
	GByteArray *buffer;
	GError *local_error = NULL;

	context = g_simple_async_result_get_op_res_gpointer (simple);

	message = e_msg_composer_get_message_draft_finish (
		composer, result, &local_error);

	if (local_error != NULL) {
		g_warn_if_fail (message == NULL);
		g_simple_async_result_take_error (simple, local_error);
		g_simple_async_result_complete (simple);
		g_object_unref (simple);
		return;
	}

	g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message));

	/* Decode the message to an in-memory buffer.  We have to do this
	 * because CamelStreams are synchronous-only, and using threads is
	 * dangerous because CamelDataWrapper is not reentrant. */
	buffer = g_byte_array_new ();
	camel_stream = camel_stream_mem_new ();
	camel_stream_mem_set_byte_array (
		CAMEL_STREAM_MEM (camel_stream), buffer);
	camel_data_wrapper_decode_to_stream_sync (
		CAMEL_DATA_WRAPPER (message), camel_stream, NULL, NULL);
	g_object_unref (camel_stream);

	g_object_unref (message);

	/* Load the buffer into a GMemoryInputStream. */
	input_stream = g_memory_input_stream_new ();
	if (buffer->len > 0)
		g_memory_input_stream_add_data (
			G_MEMORY_INPUT_STREAM (input_stream),
			buffer->data, (gssize) buffer->len,
			(GDestroyNotify) g_free);
	g_byte_array_free (buffer, FALSE);

	/* Splice the input and output streams. */
	g_output_stream_splice_async (
		context->output_stream, input_stream,
		G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
		G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
		G_PRIORITY_DEFAULT, context->cancellable,
		(GAsyncReadyCallback) save_snapshot_splice_cb,
		simple);

	g_object_unref (input_stream);
}
static void
camel_stream_mem_init (CamelObject *object)
{
	CamelStreamMem *stream_mem = CAMEL_STREAM_MEM (object);

	stream_mem->owner = FALSE;
	stream_mem->buffer = NULL;
}
static gboolean
stream_eos (CamelStream *stream)
{
	CamelStreamMem *stream_mem = CAMEL_STREAM_MEM (stream);
	CamelSeekableStream *seekable_stream = CAMEL_SEEKABLE_STREAM (stream);

	return stream_mem->buffer->len <= seekable_stream->position;
}
/**
 * camel_stream_mem_new_with_byte_array:
 * @buffer: a #GByteArray to use as the stream data
 *
 * Create a new #CamelStreamMem using @buffer as the stream data.
 *
 * Note: The newly created #CamelStreamMem will destroy @buffer
 * when destroyed.
 *
 * Returns a new #CamelStreamMem
 **/
CamelStream *
camel_stream_mem_new_with_byte_array (GByteArray *buffer)
{
	CamelStreamMem *stream_mem;

	stream_mem = CAMEL_STREAM_MEM (camel_object_new (CAMEL_STREAM_MEM_TYPE));
	stream_mem->buffer = buffer;
	stream_mem->owner = TRUE;

	return CAMEL_STREAM (stream_mem);
}
static void
camel_stream_mem_finalize (CamelObject *object)
{
	CamelStreamMem *s = CAMEL_STREAM_MEM (object);

	if (s->buffer && s->owner) {
		/* TODO: we need our own bytearray type since we don't know
		   the real size of the underlying buffer :-/ */
		if (s->secure && s->buffer->len)
			clear_mem(s->buffer->data, s->buffer->len);
		g_byte_array_free(s->buffer, TRUE);
	}
}
static gboolean
data_wrapper_construct_from_stream_sync (CamelDataWrapper *data_wrapper,
                                         CamelStream *stream,
                                         GCancellable *cancellable,
                                         GError **error)
{
	CamelStream *memory_stream;
	gssize bytes_written;

	camel_data_wrapper_lock (
		data_wrapper, CAMEL_DATA_WRAPPER_STREAM_LOCK);

	/* Check for cancellation after locking. */
	if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
		camel_data_wrapper_unlock (
			data_wrapper, CAMEL_DATA_WRAPPER_STREAM_LOCK);
		return FALSE;
	}

	if (G_IS_SEEKABLE (stream)) {
		if (!g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, cancellable, error)) {
			camel_data_wrapper_unlock (data_wrapper, CAMEL_DATA_WRAPPER_STREAM_LOCK);
			return FALSE;
		}
	}

	/* Wipe any previous contents from our byte array. */
	g_byte_array_set_size (data_wrapper->priv->byte_array, 0);

	memory_stream = camel_stream_mem_new ();

	/* We retain ownership of the byte array. */
	camel_stream_mem_set_byte_array (
		CAMEL_STREAM_MEM (memory_stream),
		data_wrapper->priv->byte_array);

	/* Transfer incoming contents to our byte array. */
	bytes_written = camel_stream_write_to_stream (
		stream, memory_stream, cancellable, error);

	g_object_unref (memory_stream);

	camel_data_wrapper_unlock (
		data_wrapper, CAMEL_DATA_WRAPPER_STREAM_LOCK);

	return (bytes_written >= 0);
}
static ssize_t
stream_read (CamelStream *stream, char *buffer, size_t n)
{
	CamelStreamMem *camel_stream_mem = CAMEL_STREAM_MEM (stream);
	CamelSeekableStream *seekable = CAMEL_SEEKABLE_STREAM (stream);
	ssize_t nread;

	if (seekable->bound_end != CAMEL_STREAM_UNBOUND)
		n = MIN(seekable->bound_end - seekable->position, n);

	nread = MIN (n, camel_stream_mem->buffer->len - seekable->position);
	if (nread > 0) {
		memcpy (buffer, camel_stream_mem->buffer->data + seekable->position, nread);
		seekable->position += nread;
	} else
		nread = 0;

	return nread;
}
static ssize_t
stream_write (CamelStream *stream, const char *buffer, size_t n)
{
	CamelStreamMem *stream_mem = CAMEL_STREAM_MEM (stream);
	CamelSeekableStream *seekable = CAMEL_SEEKABLE_STREAM (stream);
	ssize_t nwrite = n;

	if (seekable->bound_end != CAMEL_STREAM_UNBOUND)
		nwrite = MIN(seekable->bound_end - seekable->position, n);

	/* FIXME: we shouldn't use g_byte_arrays or g_malloc perhaps? */
	if (seekable->position == stream_mem->buffer->len) {
		g_byte_array_append(stream_mem->buffer, (const guint8 *)buffer, nwrite);
	} else {
		g_byte_array_set_size(stream_mem->buffer, nwrite + stream_mem->buffer->len);
		memcpy(stream_mem->buffer->data + seekable->position, buffer, nwrite);
	}
	seekable->position += nwrite;

	return nwrite;
}
static off_t
stream_seek (CamelSeekableStream *stream, off_t offset,
	     CamelStreamSeekPolicy policy)
{
	off_t position;
	CamelStreamMem *stream_mem = CAMEL_STREAM_MEM (stream);

	switch  (policy) {
	case CAMEL_STREAM_SET:
		position = offset;
		break;
	case CAMEL_STREAM_CUR:
		position = stream->position + offset;
		break;
	case CAMEL_STREAM_END:
		position = (stream_mem->buffer)->len + offset;
		break;
	default:
		position = offset;
		break;
	}

	if (stream->bound_end != CAMEL_STREAM_UNBOUND)
		position = MIN (position, stream->bound_end);
	if (stream->bound_start != CAMEL_STREAM_UNBOUND)
		position = MAX (position, 0);
	else
		position = MAX (position, stream->bound_start);

	if (position > stream_mem->buffer->len) {
		int oldlen = stream_mem->buffer->len;
		g_byte_array_set_size (stream_mem->buffer, position);
		memset (stream_mem->buffer->data + oldlen, 0,
			position - oldlen);
	}

	stream->position = position;

	return position;
}
static gssize
data_wrapper_write_to_stream_sync (CamelDataWrapper *data_wrapper,
                                   CamelStream *stream,
                                   GCancellable *cancellable,
                                   GError **error)
{
	CamelStream *memory_stream;
	gssize ret;

	camel_data_wrapper_lock (
		data_wrapper, CAMEL_DATA_WRAPPER_STREAM_LOCK);

	/* Check for cancellation after locking. */
	if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
		camel_data_wrapper_unlock (
			data_wrapper, CAMEL_DATA_WRAPPER_STREAM_LOCK);
		return -1;
	}

	memory_stream = camel_stream_mem_new ();

	/* We retain ownership of the byte array. */
	camel_stream_mem_set_byte_array (
		CAMEL_STREAM_MEM (memory_stream),
		data_wrapper->priv->byte_array);

	ret = camel_stream_write_to_stream (
		memory_stream, stream, cancellable, error);

	g_object_unref (memory_stream);

	camel_data_wrapper_unlock (
		data_wrapper, CAMEL_DATA_WRAPPER_STREAM_LOCK);

	return ret;
}
Ejemplo n.º 12
0
int main (int argc, char **argv)
{
	CamelSession *session;
	CamelCipherContext *ctx;
	CamelException *ex;
	CamelCipherValidity *valid;
	CamelStream *stream1, *stream2;
	struct _CamelMimePart *sigpart, *conpart, *encpart, *outpart;
	CamelDataWrapper *dw;
	GPtrArray *recipients;
	GByteArray *buf;
	char *before, *after;
	int ret;

	if (getenv("CAMEL_TEST_GPG") == NULL)
		return 77;

	camel_test_init (argc, argv);

	/* clear out any camel-test data */
	system ("/bin/rm -rf /tmp/camel-test");
	system ("/bin/mkdir /tmp/camel-test");
	setenv ("GNUPGHOME", "/tmp/camel-test/.gnupg", 1);

	/* import the gpg keys */
	if ((ret = system ("gpg < /dev/null > /dev/null 2>&1")) == -1)
		return 77;
	else if (WEXITSTATUS (ret) == 127)
		return 77;

	g_message ("gpg --import " TEST_DATA_DIR "/camel-test.gpg.pub > /dev/null 2>&1");
	system ("gpg --import " TEST_DATA_DIR "/camel-test.gpg.pub > /dev/null 2>&1");
	g_message ("gpg --import " TEST_DATA_DIR "/camel-test.gpg.sec > /dev/null 2>&1");
	system ("gpg --import " TEST_DATA_DIR "/camel-test.gpg.sec > /dev/null 2>&1");

	session = camel_pgp_session_new ("/tmp/camel-test");

	ex = camel_exception_new ();

	ctx = camel_gpg_context_new (session);
	camel_gpg_context_set_always_trust (CAMEL_GPG_CONTEXT (ctx), TRUE);

	camel_test_start ("Test of PGP functions");

	stream1 = camel_stream_mem_new ();
	camel_stream_write (stream1, "Hello, I am a test stream.\n", 27);
	camel_stream_reset (stream1);

	conpart = camel_mime_part_new();
	dw = camel_data_wrapper_new();
	camel_data_wrapper_construct_from_stream(dw, stream1);
	camel_medium_set_content_object((CamelMedium *)conpart, dw);
	camel_object_unref(stream1);
	camel_object_unref(dw);

	sigpart = camel_mime_part_new();

	camel_test_push ("PGP signing");
	camel_cipher_sign (ctx, "*****@*****.**", CAMEL_CIPHER_HASH_SHA1, conpart, sigpart, ex);
	if (camel_exception_is_set(ex)) {
		printf("PGP signing failed assuming non-functional environment\n%s", camel_exception_get_description (ex));
		camel_test_pull();
		return 77;
	}
	camel_test_pull ();

	camel_exception_clear (ex);

	camel_test_push ("PGP verify");
	valid = camel_cipher_verify (ctx, sigpart, ex);
	check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex));
	check_msg (camel_cipher_validity_get_valid (valid), "%s", camel_cipher_validity_get_description (valid));
	camel_cipher_validity_free (valid);
	camel_test_pull ();

	camel_object_unref(conpart);
	camel_object_unref(sigpart);

	stream1 = camel_stream_mem_new ();
	camel_stream_write (stream1, "Hello, I am a test of encryption/decryption.", 44);
	camel_stream_reset (stream1);

	conpart = camel_mime_part_new();
	dw = camel_data_wrapper_new();
	camel_stream_reset(stream1);
	camel_data_wrapper_construct_from_stream(dw, stream1);
	camel_medium_set_content_object((CamelMedium *)conpart, dw);
	camel_object_unref(stream1);
	camel_object_unref(dw);

	encpart = camel_mime_part_new();

	camel_exception_clear (ex);

	camel_test_push ("PGP encrypt");
	recipients = g_ptr_array_new ();
	g_ptr_array_add (recipients, "*****@*****.**");
	camel_cipher_encrypt (ctx, "*****@*****.**", recipients, conpart, encpart, ex);
	check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex));
	g_ptr_array_free (recipients, TRUE);
	camel_test_pull ();

	camel_exception_clear (ex);

	camel_test_push ("PGP decrypt");
	outpart = camel_mime_part_new();
	valid = camel_cipher_decrypt (ctx, encpart, outpart, ex);
	check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex));
	check_msg (valid->encrypt.status == CAMEL_CIPHER_VALIDITY_ENCRYPT_ENCRYPTED, "%s", valid->encrypt.description);

	stream1 = camel_stream_mem_new();
	stream2 = camel_stream_mem_new();

	camel_data_wrapper_write_to_stream((CamelDataWrapper *)conpart, stream1);
	camel_data_wrapper_write_to_stream((CamelDataWrapper *)outpart, stream2);

	buf = CAMEL_STREAM_MEM (stream1)->buffer;
	before = g_strndup (buf->data, buf->len);
	buf = CAMEL_STREAM_MEM (stream2)->buffer;
	after = g_strndup (buf->data, buf->len);
	check_msg (string_equal (before, after), "before = '%s', after = '%s'", before, after);
	g_free (before);
	g_free (after);

	camel_object_unref(stream1);
	camel_object_unref(stream2);
	camel_object_unref(conpart);
	camel_object_unref(encpart);
	camel_object_unref(outpart);

	camel_test_pull ();

	camel_object_unref (CAMEL_OBJECT (ctx));
	camel_object_unref (CAMEL_OBJECT (session));

	camel_test_end ();

	return 0;
}
Ejemplo n.º 13
0
gint main (gint argc, gchar **argv)
{
	CamelSession *session;
	CamelSMimeContext *ctx;
	GError **error;
	CamelCipherValidity *valid;
	CamelStream *stream1, *stream2, *stream3;
	GPtrArray *recipients;
	GByteArray *buf;
	gchar *before, *after;

	camel_test_init (argc, argv);

	ex = camel_exception_new ();

	/* clear out any camel-test data */
	system ("/bin/rm -rf /tmp/camel-test");

	session = camel_test_session_new ("/tmp/camel-test");

	ctx = camel_smime_context_new (session);

	camel_test_start ("Test of S/MIME PKCS7 functions");

	stream1 = camel_stream_mem_new ();
	camel_stream_write (stream1, "Hello, I am a test stream.", 25);
	g_seekable_seek (G_SEEKABLE (stream1), 0, G_SEEK_SET, NULL, NULL);

	stream2 = camel_stream_mem_new ();

	camel_test_push ("PKCS7 signing");
	camel_smime_sign (ctx, "*****@*****.**", CAMEL_CIPHER_HASH_SHA1,
			  stream1, stream2, ex);
	check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex));
	camel_test_pull ();

	camel_exception_clear (ex);

	camel_test_push ("PKCS7 verify");
	g_seekable_seek (G_SEEKABLE (stream1), 0, G_SEEK_SET, NULL, NULL);
	g_seekable_seek (G_SEEKABLE (stream2), 0, G_SEEK_SET, NULL, NULL);
	valid = camel_smime_verify (ctx, CAMEL_CIPHER_HASH_SHA1, stream1, stream2, ex);
	check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex));
	check_msg (camel_cipher_validity_get_valid (valid), "%s", camel_cipher_validity_get_description (valid));
	camel_cipher_validity_free (valid);
	camel_test_pull ();

	g_object_unref (stream1);
	g_object_unref (stream2);

	stream1 = camel_stream_mem_new ();
	stream2 = camel_stream_mem_new ();
	stream3 = camel_stream_mem_new ();

	camel_stream_write (stream1, "Hello, I am a test of encryption/decryption.", 44);
	g_seekable_seek (G_SEEKABLE (stream1), 0, G_SEEK_SET, NULL, NULL);

	camel_exception_clear (ex);

	camel_test_push ("PKCS7 encrypt");
	recipients = g_ptr_array_new ();
	g_ptr_array_add (recipients, "*****@*****.**");
	camel_smime_encrypt (ctx, FALSE, "*****@*****.**", recipients,
			     stream1, stream2, ex);
	check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex));
	g_ptr_array_free (recipients, TRUE);
	camel_test_pull ();

	g_seekable_seek (G_SEEKABLE (stream2), 0, G_SEEK_SET, NULL, NULL);
	camel_exception_clear (ex);

	camel_test_push ("PKCS7 decrypt");
	camel_smime_decrypt (ctx, stream2, stream3, ex);
	check_msg (!camel_exception_is_set (ex), "%s", camel_exception_get_description (ex));
	buf = CAMEL_STREAM_MEM (stream1)->buffer;
	before = g_strndup (buf->data, buf->len);
	buf = CAMEL_STREAM_MEM (stream3)->buffer;
	after = g_strndup (buf->data, buf->len);
	check_msg (string_equal (before, after), "before = '%s', after = '%s'", before, after);
	g_free (before);
	g_free (after);
	camel_test_pull ();

	g_object_unref (ctx);
	g_object_unref (session);

	camel_test_end ();

	return 0;
}
Ejemplo n.º 14
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;
}
Ejemplo n.º 15
0
static void
create_mime_message_cb (ESoapMessage *msg,
                        gpointer user_data)
{
	struct _create_mime_msg_data *create_data = user_data;
	CamelStream *mem, *filtered;
	CamelMimeFilter *filter;
	CamelContentType *content_type;
	GByteArray *bytes;
	gchar *base64;
	gint msgflag;
	guint32 message_camel_flags = 0;

	if (create_data->info)
		message_camel_flags = camel_message_info_flags (create_data->info);
		
	e_soap_message_start_element (msg, "Message", NULL, NULL);
	e_soap_message_start_element (msg, "MimeContent", NULL, NULL);

	/* This is horrid. We really need to extend ESoapMessage to allow us
	 * to stream this directly rather than storing it in RAM. Which right
	 * now we are doing about four times: the GByteArray in the mem stream,
	 * then the base64 version, then the xmlDoc, then the soup request. */
	camel_mime_message_set_best_encoding (
		create_data->message,
		CAMEL_BESTENC_GET_ENCODING,
		CAMEL_BESTENC_8BIT);

	mem = camel_stream_mem_new ();
	filtered = camel_stream_filter_new (mem);

	filter = camel_mime_filter_crlf_new (
		CAMEL_MIME_FILTER_CRLF_ENCODE,
		CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
	camel_stream_filter_add (CAMEL_STREAM_FILTER (filtered), filter);
	g_object_unref (filter);

	camel_data_wrapper_write_to_stream_sync (
		CAMEL_DATA_WRAPPER (create_data->message),
		filtered, NULL, NULL);
	camel_stream_flush (filtered, NULL, NULL);
	camel_stream_flush (mem, NULL, NULL);
	bytes = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (mem));

	base64 = g_base64_encode (bytes->data, bytes->len);
	g_object_unref (mem);
	g_object_unref (filtered);

	e_soap_message_write_string (msg, base64);
	g_free (base64);

	e_soap_message_end_element (msg); /* MimeContent */

	content_type = camel_mime_part_get_content_type (CAMEL_MIME_PART (create_data->message));
	if (content_type && camel_content_type_is (content_type, "multipart", "report") &&
	    camel_content_type_param (content_type, "report-type") &&
	    g_ascii_strcasecmp (camel_content_type_param (content_type, "report-type"), "disposition-notification") == 0) {
		/* it's a disposition notification reply, set ItemClass too */
		e_soap_message_start_element (msg, "ItemClass", NULL, NULL);
		e_soap_message_write_string (msg, "REPORT.IPM.NOTE.IPNRN");
		e_soap_message_end_element (msg); /* ItemClass */
	}

	e_ews_message_write_string_parameter_with_attribute (
			msg,
			"Importance",
			NULL,
			(message_camel_flags & CAMEL_MESSAGE_FLAGGED) != 0 ? "High" : "Normal",
			NULL,
			NULL);

	/* more MAPI crap.  You can't just set the IsDraft property
	 * here you have to use the MAPI MSGFLAG_UNSENT extended
	 * property Further crap is that Exchange 2007 assumes when it
	 * sees this property that you're setting the value to 0
	 * ... it never checks */
	msgflag = MAPI_MSGFLAG_READ; /* draft or sent is always read */
	if ((message_camel_flags & CAMEL_MESSAGE_DRAFT) != 0)
		msgflag |= MAPI_MSGFLAG_UNSENT;

	e_ews_message_add_extended_property_tag_int (msg, 0x0e07, msgflag);

	if ((message_camel_flags & (CAMEL_MESSAGE_FORWARDED | CAMEL_MESSAGE_ANSWERED)) != 0) {
		gint icon;

		icon = (message_camel_flags & CAMEL_MESSAGE_ANSWERED) != 0 ? 0x105 : 0x106;

		e_ews_message_add_extended_property_tag_int (msg, 0x1080, icon);
	}

	if (create_data->info) {
		const gchar *followup, *completed, *dueby;
		time_t completed_tt = (time_t) 0 , dueby_tt = (time_t) 0;

		/* follow-up flags */
		followup = camel_message_info_user_tag (create_data->info, "follow-up");
		completed = camel_message_info_user_tag (create_data->info, "completed-on");
		dueby = camel_message_info_user_tag (create_data->info, "due-by");

		if (followup && !*followup)
			followup = NULL;

		if (completed && *completed)
			completed_tt = camel_header_decode_date (completed, NULL);

		if (dueby && *dueby)
			dueby_tt = camel_header_decode_date (dueby, NULL);

		/* PidTagFlagStatus */
		e_ews_message_add_extended_property_tag_int (msg, 0x1090,
			followup ? (completed_tt != (time_t) 0 ? 0x01 /* followupComplete */: 0x02 /* followupFlagged */) : 0x0);

		if (followup) {
			/* PidLidFlagRequest */
			e_ews_message_add_extended_property_distinguished_tag_string (msg, "Common", 0x8530, followup);

			/* PidTagToDoItemFlags */
			e_ews_message_add_extended_property_tag_int (msg, 0x0e2b, 1);
		}

		if (followup && completed_tt != (time_t) 0) {
			/* minute precision */
			completed_tt = completed_tt - (completed_tt % 60);

			/* PidTagFlagCompleteTime */
			e_ews_message_add_extended_property_tag_time (msg, 0x1091, completed_tt);

			/* PidLidTaskDateCompleted */
			e_ews_message_add_extended_property_distinguished_tag_time (msg, "Task", 0x810f, completed_tt);

			/* PidLidTaskStatus */
			e_ews_message_add_extended_property_distinguished_tag_int (msg, "Task", 0x8101, 2);

			/* PidLidPercentComplete */
			e_ews_message_add_extended_property_distinguished_tag_double (msg, "Task", 0x8102, 1.0);

			/* PidLidTaskComplete */
			e_ews_message_add_extended_property_distinguished_tag_boolean (msg, "Task", 0x811c, TRUE);
		}

		if (followup && dueby_tt != (time_t) 0 && completed_tt == (time_t) 0) {
			/* PidLidTaskStatus */
			e_ews_message_add_extended_property_distinguished_tag_int (msg, "Task", 0x8101, 0);

			/* PidLidPercentComplete */
			e_ews_message_add_extended_property_distinguished_tag_double (msg, "Task", 0x8102, 0.0);

			/* PidLidTaskDueDate */
			e_ews_message_add_extended_property_distinguished_tag_time (msg, "Task", 0x8105, dueby_tt);

			/* PidLidTaskComplete */
			e_ews_message_add_extended_property_distinguished_tag_boolean (msg, "Task", 0x811c, FALSE);
		}
	}

	if (create_data->recipients) {
		GHashTable *recip_to, *recip_cc, *recip_bcc;

		recip_to = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
		recip_cc = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
		recip_bcc = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
	
		filter_recipients (create_data->message, create_data->recipients, recip_to, recip_cc, recip_bcc);

		write_recipients (msg, "ToRecipients", recip_to);
		write_recipients (msg, "CcRecipients", recip_cc);
		write_recipients (msg, "BccRecipients", recip_bcc);

		g_hash_table_destroy (recip_to);
		g_hash_table_destroy (recip_cc);
		g_hash_table_destroy (recip_bcc);
	}

	e_ews_message_write_string_parameter_with_attribute (
			msg,
			"IsRead",
			NULL,
			(message_camel_flags & CAMEL_MESSAGE_SEEN) != 0 ? "true" : "false",
			NULL,
			NULL);

	e_soap_message_end_element (msg); /* Message */

	g_free (create_data);
}
Ejemplo n.º 16
0
static void
attachment_button_expand_drag_data_get_cb (EAttachmentButton *button,
                                           GdkDragContext *context,
                                           GtkSelectionData *selection,
                                           guint info,
                                           guint time)
{
	EAttachmentView *view;
	EAttachment *attachment;
	gchar *mime_type = NULL;

	attachment = e_attachment_button_get_attachment (button);

	if (attachment != NULL)
		mime_type = e_attachment_dup_mime_type (attachment);

	if (mime_type != NULL) {
		gboolean processed = FALSE;
		GdkAtom atom;
		gchar *atom_name;

		atom = gtk_selection_data_get_target (selection);
		atom_name = gdk_atom_name (atom);

		if (g_strcmp0 (atom_name, mime_type) == 0) {
			CamelMimePart *mime_part;

			mime_part = e_attachment_ref_mime_part (attachment);

			if (mime_part != NULL) {
				CamelDataWrapper *wrapper;
				CamelStream *stream;
				GByteArray *buffer;

				buffer = g_byte_array_new ();
				stream = camel_stream_mem_new ();
				camel_stream_mem_set_byte_array (
					CAMEL_STREAM_MEM (stream),
					buffer);
				wrapper = camel_medium_get_content (
					CAMEL_MEDIUM (mime_part));
				camel_data_wrapper_decode_to_stream_sync (
					wrapper, stream, NULL, NULL);
				g_object_unref (stream);

				gtk_selection_data_set (
					selection, atom, 8,
					buffer->data, buffer->len);
				processed = TRUE;

				g_byte_array_free (buffer, TRUE);

				g_object_unref (mime_part);
			}
		}

		g_free (atom_name);
		g_free (mime_type);

		if (processed)
			return;
	}

	view = e_attachment_button_get_view (button);

	e_attachment_view_drag_data_get (
		view, context, selection, info, time);
}
Ejemplo n.º 17
0
static CamelMimePart *
multipart_signed_get_part (CamelMultipart *multipart,
                           guint index)
{
	CamelMultipartSigned *mps = (CamelMultipartSigned *) multipart;
	CamelDataWrapper *data_wrapper;
	CamelStream *stream;
	GByteArray *byte_array;

	data_wrapper = CAMEL_DATA_WRAPPER (multipart);
	byte_array = camel_data_wrapper_get_byte_array (data_wrapper);

	switch (index) {
	case CAMEL_MULTIPART_SIGNED_CONTENT:
		if (mps->content)
			return mps->content;
		if (mps->contentraw) {
			g_return_val_if_fail (
				G_IS_SEEKABLE (mps->contentraw), NULL);
			stream = g_object_ref (mps->contentraw);
		} else if (mps->start1 == -1
			   && multipart_signed_parse_content (mps) == -1
			   && byte_array->len == 0) {
			g_warning ("Trying to get content on an invalid multipart/signed");
			return NULL;
		} else if (byte_array->len == 0) {
			return NULL;
		} else if (mps->start1 == -1) {
			stream = camel_stream_mem_new ();
			camel_stream_mem_set_byte_array (
				CAMEL_STREAM_MEM (stream), byte_array);
		} else {
			stream = multipart_signed_clip_stream (
				mps, mps->start1, mps->end1);
		}
		g_seekable_seek (
			G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, NULL);
		mps->content = camel_mime_part_new ();
		camel_data_wrapper_construct_from_stream_sync (
			CAMEL_DATA_WRAPPER (mps->content), stream, NULL, NULL);
		g_object_unref (stream);
		return mps->content;
	case CAMEL_MULTIPART_SIGNED_SIGNATURE:
		if (mps->signature)
			return mps->signature;
		if (mps->start1 == -1
		    && multipart_signed_parse_content (mps) == -1) {
			g_warning ("Trying to get signature on invalid multipart/signed");
			return NULL;
		} else if (byte_array->len == 0) {
			return NULL;
		}
		stream = multipart_signed_clip_stream (
			mps, mps->start2, mps->end2);
		g_seekable_seek (
			G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, NULL);
		mps->signature = camel_mime_part_new ();
		camel_data_wrapper_construct_from_stream_sync (
			CAMEL_DATA_WRAPPER (mps->signature),
			stream, NULL, NULL);
		g_object_unref (stream);
		return mps->signature;
	default:
		g_warning ("trying to get object out of bounds for multipart");
	}

	return NULL;
}