static CamelMimeMessage *
maildir_folder_get_message_sync (CamelFolder *folder,
                                 const gchar *uid,
                                 GCancellable *cancellable,
                                 GError **error)
{
	CamelLocalFolder *lf = (CamelLocalFolder *) folder;
	CamelStream *message_stream = NULL;
	CamelMimeMessage *message = NULL;
	gchar *name = NULL;

	d (printf ("getting message: %s\n", uid));

	if (!lf || camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1)
		return NULL;

	name = maildir_folder_get_filename (folder, uid, error);
	if (!name)
		goto fail;

	message_stream = camel_stream_fs_new_with_name (
		name, O_RDONLY, 0, error);
	if (message_stream == NULL) {
		g_prefix_error (
			error, _("Cannot get message %s from folder %s: "),
			uid, lf->folder_path);
		goto fail;
	}

	message = camel_mime_message_new ();
	if (!camel_data_wrapper_construct_from_stream_sync (
		(CamelDataWrapper *) message,
		message_stream, cancellable, error)) {
		g_prefix_error (
			error, _("Cannot get message %s from folder %s: "),
			uid, lf->folder_path);
		g_object_unref (message);
		message = NULL;

	}
	g_object_unref (message_stream);
 fail:
	g_free (name);

	camel_local_folder_unlock (lf);

	camel_local_folder_claim_changes (lf);

	return message;
}
Example #2
0
CamelMimeMessage *
test_message_read_file (const gchar *name)
{
	CamelStream *stream;
	CamelMimeMessage *msg2;

	stream = camel_stream_fs_new_with_name (name, O_RDONLY, 0, NULL);
	msg2 = camel_mime_message_new ();

	camel_data_wrapper_construct_from_stream_sync (
		CAMEL_DATA_WRAPPER (msg2), stream, NULL, NULL);
	/* stream's refcount may be > 1 if the message is real big */
	check (G_OBJECT (stream)->ref_count >=1);
	g_object_unref (stream);

	return msg2;
}
Example #3
0
gint
test_message_write_file (CamelMimeMessage *msg,
                         const gchar *name)
{
	CamelStream *stream;
	gint ret;

	stream = camel_stream_fs_new_with_name (
		name, O_CREAT | O_WRONLY, 0600, NULL);
	camel_data_wrapper_write_to_stream_sync (
		CAMEL_DATA_WRAPPER (msg), stream, NULL, NULL);
	ret = camel_stream_close (stream, NULL, NULL);

	check (G_OBJECT (stream)->ref_count == 1);
	g_object_unref (stream);

	return ret;
}
/**
 * camel_imap_message_cache_get:
 * @cache: the cache
 * @uid: the UID of the data to get
 * @part_spec: the part_spec of the data to get
 * @ex: exception
 *
 * Return value: a CamelStream containing the cached data (which the
 * caller must unref), or %NULL if that data is not cached.
 **/
CamelStream *
camel_imap_message_cache_get (CamelImapMessageCache *cache, const char *uid,
			      const char *part_spec, CamelException *ex)
{
	CamelStream *stream;
	char *path, *key;

	if (uid[0] == 0)
		return NULL;

#ifdef G_OS_WIN32
	/* See comment in insert_setup() */
	if (!*part_spec)
		part_spec = "~";
#endif
	path = g_strdup_printf ("%s/%s.%s", cache->path, uid, part_spec);
	key = strrchr (path, '/') + 1;

	stream = g_hash_table_lookup (cache->parts, key);
	if (stream) {
		camel_stream_reset (CAMEL_STREAM (stream));
		camel_object_ref (CAMEL_OBJECT (stream));
		g_free (path);
		return stream;
	}

	stream = camel_stream_fs_new_with_name (path, O_RDONLY, 0);
	if (stream) {
		cache_put (cache, uid, key, stream);
	} else {
		camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
				      _("Failed to cache %s: %s"),
				      part_spec, g_strerror (errno));
	}

	g_free (path);

	return stream;
}
static GtkWidget *
mbox_get_preview (EImport *ei,
                  EImportTarget *target,
                  EImportImporter *im)
{
	GtkWidget *preview = NULL;
	EImportTargetURI *s = (EImportTargetURI *) target;
	gchar *filename;
	gint fd;
	CamelMimeParser *mp;
	GtkListStore *store = NULL;
	GtkTreeIter iter;
	GtkWidget *preview_widget = NULL;
	gboolean any_read = FALSE;

	if (!create_preview_func || !fill_preview_func)
		return NULL;

	filename = g_filename_from_uri (s->uri_src, NULL, NULL);
	if (!filename) {
		g_message (G_STRLOC ": Couldn't get filename from URI '%s'", s->uri_src);
		return NULL;
	}

	fd = g_open (filename, O_RDONLY | O_BINARY, 0);
	if (fd == -1) {
		g_warning (
			"Cannot find source file to import '%s': %s",
			filename, g_strerror (errno));
		g_free (filename);
		return NULL;
	}

	mp = camel_mime_parser_new ();
	camel_mime_parser_scan_from (mp, TRUE);
	if (camel_mime_parser_init_with_fd (mp, fd) == -1) {
		goto cleanup;
	}

	while (camel_mime_parser_step (mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM) {
		CamelMimeMessage *msg;

		any_read = TRUE;

		msg = camel_mime_message_new ();
		if (!camel_mime_part_construct_from_parser_sync (
			(CamelMimePart *) msg, mp, NULL, NULL)) {
			g_object_unref (msg);
			break;
		}

		mbox_preview_add_message (msg, &store);

		g_object_unref (msg);

		camel_mime_parser_step (mp, NULL, NULL);
	}

	if (!any_read) {
		CamelStream *stream;

		stream = camel_stream_fs_new_with_name (filename, O_RDONLY, 0, NULL);
		if (stream) {
			CamelMimeMessage *msg;

			msg = camel_mime_message_new ();

			if (camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) msg, stream, NULL, NULL))
				mbox_preview_add_message (msg, &store);

			g_object_unref (msg);
			g_object_unref (stream);
		}
	}

	if (store) {
		GtkTreeView *tree_view;
		GtkTreeSelection *selection;

		preview = e_web_view_preview_new ();
		gtk_widget_show (preview);

		tree_view = e_web_view_preview_get_tree_view (
			E_WEB_VIEW_PREVIEW (preview));
		if (!tree_view) {
			g_warn_if_reached ();
			gtk_widget_destroy (preview);
			preview = NULL;
			goto cleanup;
		}

		gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (store));
		g_object_unref (store);

		/* Translators: Column header for a message subject */
		gtk_tree_view_insert_column_with_attributes (
			tree_view, -1, C_("mboxImp", "Subject"),
			gtk_cell_renderer_text_new (), "text", 0, NULL);

		/* Translators: Column header for a message From address */
		gtk_tree_view_insert_column_with_attributes (
			tree_view, -1, C_("mboxImp", "From"),
			gtk_cell_renderer_text_new (), "text", 1, NULL);

		if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) > 1)
			e_web_view_preview_show_tree_view (
				E_WEB_VIEW_PREVIEW (preview));

		create_preview_func (G_OBJECT (preview), &preview_widget);
		if (!preview_widget) {
			g_warn_if_reached ();
			goto cleanup;
		}

		e_web_view_preview_set_preview (
			E_WEB_VIEW_PREVIEW (preview), preview_widget);
		gtk_widget_show (preview_widget);

		selection = gtk_tree_view_get_selection (tree_view);
		if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) {
			g_warn_if_reached ();
			goto cleanup;
		}
		gtk_tree_selection_select_iter (selection, &iter);

		g_signal_connect (
			selection, "changed",
			G_CALLBACK (preview_selection_changed_cb), preview);

		preview_selection_changed_cb (
			selection, E_WEB_VIEW_PREVIEW (preview));
	}

 cleanup:
	g_object_unref (mp);
	g_free (filename);

	/* 'fd' is freed together with 'mp' */
	/* coverity[leaked_handle] */
	return preview;
}
static gboolean
mbox_supported (EImport *ei,
                EImportTarget *target,
                EImportImporter *im)
{
	gchar signature[1024];
	gboolean ret = FALSE;
	gint fd, n;
	EImportTargetURI *s;
	gchar *filename;

	if (target->type != E_IMPORT_TARGET_URI)
		return FALSE;

	s = (EImportTargetURI *) target;
	if (s->uri_src == NULL)
		return TRUE;

	if (strncmp (s->uri_src, "file:///", strlen ("file:///")) != 0)
		return FALSE;

	filename = g_filename_from_uri (s->uri_src, NULL, NULL);
	fd = g_open (filename, O_RDONLY, 0);
	if (fd != -1) {
		n = read (fd, signature, 1024);
		ret = n >= 5 && memcmp (signature, "From ", 5) == 0;
		close (fd);

		/* An artificial number, at least 256 bytes message
		   to be able to try to import it as an MBOX */
		if (!ret && n >= 256) {
			gint ii;

			ret = (signature[0] >= 'a' && signature[0] <= 'z') ||
			      (signature[0] >= 'A' && signature[0] <= 'Z');

			for (ii = 0; ii < n && ret; ii++) {
				ret = signature[ii] == '-' ||
				      signature[ii] == ' ' ||
				      signature[ii] == '\t' ||
				     (signature[ii] >= 'a' && signature[ii] <= 'z') ||
				     (signature[ii] >= 'A' && signature[ii] <= 'Z') ||
				     (signature[ii] >= '0' && signature[ii] <= '9');
			}

			/* It's probably a header name which starts with ASCII letter and
			   contains only [a..z][A..Z][\t, ,-] and the read stopped on ':'. */
			if (ii > 0 && ii < n && !ret && signature[ii - 1] == ':') {
				CamelStream *stream;

				stream = camel_stream_fs_new_with_name (filename, O_RDONLY, 0, NULL);
				if (stream) {
					CamelMimeMessage *msg;

					msg = camel_mime_message_new ();

					/* Check whether the message can be parsed and whether
					   it contains any mandatory fields. */
					ret = camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) msg, stream, NULL, NULL) &&
					      camel_mime_message_get_message_id (msg) &&
					      camel_mime_message_get_subject (msg) &&
					      camel_mime_message_get_from (msg) &&
					      (camel_mime_message_get_recipients (msg, CAMEL_RECIPIENT_TYPE_TO) ||
					       camel_mime_message_get_recipients (msg, CAMEL_RECIPIENT_TYPE_RESENT_TO));

					g_object_unref (msg);
					g_object_unref (stream);
				}
			}
		}
	}

	g_free (filename);

	return ret;
}
gint
main (gint argc,
      gchar **argv)
{
	CamelStream *source;
	CamelStream *correct;
	CamelStream *stream;
	CamelMimeFilter *sh;
	gchar *work;
	gint i;
	gssize comp_progress, comp_correct_chunk, comp_filter_chunk;
	gint comp_i;
	gchar comp_correct[CHUNK_SIZE], comp_filter[CHUNK_SIZE];

	camel_test_init (argc, argv);

	for (i = 0; i < NUM_CASES; i++) {
		gint j;

		work = g_strdup_printf ("CRLF/DOT filter, test case %d", i);
		camel_test_start (work);
		g_free (work);

		for (j = CRLF_ENCODE; j < CRLF_DONE; j++) {
			CamelMimeFilterCRLFDirection direction;
			gchar *infile = NULL, *outfile = NULL;

			switch (j) {
			case CRLF_ENCODE:
				camel_test_push ("Test of the encoder");
				direction = CAMEL_MIME_FILTER_CRLF_ENCODE;
				infile = g_strdup_printf ("%s/crlf-%d.in", SOURCEDIR, i + 1);
				outfile = g_strdup_printf ("%s/crlf-%d.out", SOURCEDIR, i + 1);
				break;
			case CRLF_DECODE:
				camel_test_push ("Test of the decoder");
				direction = CAMEL_MIME_FILTER_CRLF_DECODE;
				infile = g_strdup_printf ("%s/crlf-%d.out", SOURCEDIR, i + 1);
				outfile = g_strdup_printf ("%s/crlf-%d.in", SOURCEDIR, i + 1);
				break;
			default:
				break;
			}

			camel_test_push ("Initializing objects");
			source = camel_stream_fs_new_with_name (infile, 0, O_RDONLY, NULL);
			if (!source) {
				camel_test_fail ("Failed to open input case in \"%s\"", infile);
				g_free (infile);
				continue;
			}
			g_free (infile);

			correct = camel_stream_fs_new_with_name (outfile, 0, O_RDONLY, NULL);
			if (!correct) {
				camel_test_fail ("Failed to open correct output in \"%s\"", outfile);
				g_free (outfile);
				continue;
			}
			g_free (outfile);

			stream = camel_stream_filter_new (source);
			if (!stream) {
				camel_test_fail ("Couldn't create CamelStreamFilter??");
				continue;
			}

			sh = camel_mime_filter_crlf_new (direction, CAMEL_MIME_FILTER_CRLF_MODE_CRLF_DOTS);
			if (!sh) {
				camel_test_fail ("Couldn't create CamelMimeFilterCrlf??");
				continue;
			}

			camel_stream_filter_add (
				CAMEL_STREAM_FILTER (stream), sh);
			camel_test_pull ();

			camel_test_push ("Running filter and comparing to correct result");

			comp_progress = 0;

			while (1) {
				comp_correct_chunk = camel_stream_read (
					correct, comp_correct,
					CHUNK_SIZE, NULL, NULL);
				comp_filter_chunk = 0;

				if (comp_correct_chunk == 0)
					break;

				while (comp_filter_chunk < comp_correct_chunk) {
					gssize delta;

					delta = camel_stream_read (
						stream,
						comp_filter + comp_filter_chunk,
						CHUNK_SIZE - comp_filter_chunk,
						NULL, NULL);

					if (delta == 0) {
						camel_test_fail ("Chunks are different sizes: correct is %d, "
								 "filter is %d, %d bytes into stream",
								 comp_correct_chunk, comp_filter_chunk, comp_progress);
					}

					comp_filter_chunk += delta;
				}

				for (comp_i = 0; comp_i < comp_filter_chunk; comp_i++) {
					if (comp_correct[comp_i] != comp_filter[comp_i]) {
						camel_test_fail ("Difference: correct is %c, filter is %c, "
								 "%d bytes into stream",
								 comp_correct[comp_i],
								 comp_filter[comp_i],
								 comp_progress + comp_i);
					}
				}

				comp_progress += comp_filter_chunk;
			}

			camel_test_pull ();

			/* inefficient */
			camel_test_push ("Cleaning up");
			g_object_unref (stream);
			g_object_unref (correct);
			g_object_unref (source);
			g_object_unref (sh);
			camel_test_pull ();

			camel_test_pull ();
		}

		camel_test_end ();
	}

	return 0;
}
Example #8
0
gint main (gint argc, gchar **argv)
{
	CamelService *service;
	CamelSession *session;
	CamelStore *store;
	CamelFolder *folder;
	CamelMimeMessage *msg;
	gint i, j;
	CamelStream *mbox;
	CamelFilterDriver *driver;
	GError *error = NULL;

	camel_test_init (argc, argv);
	camel_test_provider_init (1, local_drivers);

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

	camel_test_start ("Simple filtering of mbox");

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

	/* todo: cross-check everything with folder_info checks as well */
	/* todo: work out how to do imap/pop/nntp tests */

	push ("getting store");
	service = camel_session_add_service (
		session, "test-uid", "mbox:///tmp/camel-test/mbox",
		CAMEL_PROVIDER_STORE, &error);
	check_msg (error == NULL, "getting store: %s", error->message);
	check (CAMEL_IS_STORE (service));
	store = CAMEL_STORE (service);
	g_clear_error (&error);
	pull ();

	push ("Creating output folders");
	for (i = 0; i < G_N_ELEMENTS (mailboxes); i++) {
		push ("creating %s", mailboxes[i].name);
		mailboxes[i].folder = folder = camel_store_get_folder_sync (
			store, mailboxes[i].name,
			CAMEL_STORE_FOLDER_CREATE, NULL, &error);
		check_msg (error == NULL, "%s", error->message);
		check (folder != NULL);

		/* we need an empty folder for this to work */
		test_folder_counts (folder, 0, 0);
		g_clear_error (&error);
		pull ();
	}
	pull ();

	/* append a bunch of messages with specific content */
	push ("creating 100 test message mbox");
	mbox = camel_stream_fs_new_with_name ("/tmp/camel-test/inbox", O_WRONLY|O_CREAT|O_EXCL, 0600, NULL);
	for (j = 0; j < 100; j++) {
		gchar *content, *subject;

		push ("creating test message");
		msg = test_message_create_simple ();
		content = g_strdup_printf ("data%d content\n", j);
		test_message_set_content_simple ((CamelMimePart *)msg, 0, "text/plain",
						content, strlen (content));
		test_free (content);
		subject = g_strdup_printf ("Test%d message%d subject", j, 100-j);
		camel_mime_message_set_subject (msg, subject);

		camel_mime_message_set_date (msg, j * 60 * 24, 0);
		pull ();

		camel_stream_write_string (mbox, "From \n", NULL, NULL);
		check (camel_data_wrapper_write_to_stream_sync (
			CAMEL_DATA_WRAPPER (msg), mbox, NULL, NULL) != -1);
#if 0
		push ("appending simple message %d", j);
		camel_folder_append_message (folder, msg, NULL, ex);
		check_msg (error == NULL, "%s", error->message);
		g_clear_error (&error);
		pull ();
#endif
		test_free (subject);

		check_unref (msg, 1);
	}
	check (camel_stream_close (mbox, NULL, NULL) != -1);
	check_unref (mbox, 1);
	pull ();

	push ("Building filters");
	driver = camel_filter_driver_new (session);
	camel_filter_driver_set_folder_func (driver, get_folder, NULL);
	for (i = 0; i < G_N_ELEMENTS (rules); i++) {
		camel_filter_driver_add_rule (driver, rules[i].name, rules[i].match, rules[i].action);
	}
	pull ();

	push ("Executing filters");
	camel_filter_driver_set_default_folder (driver, mailboxes[0].folder);
#if 0  /* FIXME We no longer filter mbox files. */
	camel_filter_driver_filter_mbox (
		driver, "/tmp/camel-test/inbox", NULL, NULL, &error);
#endif
	check_msg (error == NULL, "%s", error->message);

	/* now need to check the folder counts/etc */

	check_unref (driver, 1);
	g_clear_error (&error);
	pull ();

	/* this tests that invalid rules are caught */
	push ("Testing broken match rules");
	for (i = 0; i < G_N_ELEMENTS (brokens); i++) {
		push ("rule %s", brokens[i].match);
		driver = camel_filter_driver_new (session);
		camel_filter_driver_set_folder_func (driver, get_folder, NULL);
		camel_filter_driver_add_rule (driver, brokens[i].name, brokens[i].match, brokens[i].action);
#if 0  /* FIXME We no longer filter mbox files. */
		camel_filter_driver_filter_mbox (
			driver, "/tmp/camel-test/inbox", NULL, NULL, &error);
#endif
		check (error != NULL);
		check_unref (driver, 1);
		g_clear_error (&error);
		pull ();
	}
	pull ();

	push ("Testing broken action rules");
	for (i = 0; i < G_N_ELEMENTS (brokena); i++) {
		push ("rule %s", brokena[i].action);
		driver = camel_filter_driver_new (session);
		camel_filter_driver_set_folder_func (driver, get_folder, NULL);
		camel_filter_driver_add_rule (driver, brokena[i].name, brokena[i].match, brokena[i].action);
#if 0  /* FIXME We no longer filter mbox files. */
		camel_filter_driver_filter_mbox (
			driver, "/tmp/camel-test/inbox", NULL, NULL, &error);
#endif
		check (error != NULL);
		check_unref (driver, 1);
		g_clear_error (&error);
		pull ();
	}
	pull ();

	for (i = 0; i < G_N_ELEMENTS (mailboxes); i++) {
		check_unref (mailboxes[i].folder, 1);
	}

	check_unref (store, 1);

	check_unref (session, 1);

	camel_test_end ();

	return 0;
}
static gboolean
maildir_folder_append_message_sync (CamelFolder *folder,
                                    CamelMimeMessage *message,
                                    CamelMessageInfo *info,
                                    gchar **appended_uid,
                                    GCancellable *cancellable,
                                    GError **error)
{
	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
	CamelStream *output_stream;
	CamelMessageInfo *mi;
	CamelMaildirMessageInfo *mdi;
	gchar *name, *dest = NULL;
	gboolean success = TRUE;

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

	/* If we can't lock, don't do anything */
	if (camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1)
		return FALSE;

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

	if ((camel_message_info_flags (mi) & CAMEL_MESSAGE_ATTACHMENTS) && !camel_mime_message_has_attachment (message))
		camel_message_info_set_flags (mi, CAMEL_MESSAGE_ATTACHMENTS, 0);

	mdi = (CamelMaildirMessageInfo *)mi;

	d(printf("Appending message: uid is %s filename is %s\n", camel_message_info_uid(mi), mdi->filename));

	/* write it out to tmp, use the uid we got from the summary */
	name = g_strdup_printf ("%s/tmp/%s", lf->folder_path, camel_message_info_uid(mi));
	output_stream = camel_stream_fs_new_with_name (
		name, O_WRONLY|O_CREAT, 0600, error);
	if (output_stream == NULL)
		goto fail_write;

	if (camel_data_wrapper_write_to_stream_sync (
		(CamelDataWrapper *)message, output_stream, cancellable, error) == -1
	    || camel_stream_close (output_stream, cancellable, error) == -1)
		goto fail_write;

	/* now move from tmp to cur (bypass new, does it matter?) */
	dest = g_strdup_printf("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi));
	if (g_rename (name, dest) == -1) {
		g_set_error (
			error, G_IO_ERROR,
			g_io_error_from_errno (errno),
			"%s", g_strerror (errno));
		goto fail_write;
	}

	g_free (dest);
	g_free (name);

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

	if (output_stream)
		g_object_unref (output_stream);

	goto check_changed;

 fail_write:

	/* remove the summary info so we are not out-of-sync with the mh folder */
	camel_folder_summary_remove_uid (CAMEL_FOLDER_SUMMARY (folder->summary),
					 camel_message_info_uid (mi));

	g_prefix_error (
		error, _("Cannot append message to maildir folder: %s: "),
		name);

	if (output_stream) {
		g_object_unref (CAMEL_OBJECT (output_stream));
		unlink (name);
	}

	g_free (name);
	g_free (dest);

	success = FALSE;

 check_changed:
	camel_local_folder_unlock (lf);

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

	return success;
}
static void
test_filter(CamelMimeFilter *f, const char *inname, const char *outname)
{
	CamelStreamMem *in, *out;
	CamelStream *indisk, *outdisk, *filter;
	int id;

	camel_test_push("Data file `%s'", inname);

	camel_test_push("setup");

	indisk = camel_stream_fs_new_with_name(inname, O_RDONLY, 0);
	check(indisk);
	outdisk = camel_stream_fs_new_with_name(outname, O_RDONLY, 0);
	check(outdisk);

	out = (CamelStreamMem *)camel_stream_mem_new();
	check(camel_stream_write_to_stream(outdisk, (CamelStream *)out) > 0);

	camel_test_pull();

	camel_test_push("reading through filter stream");

	in = (CamelStreamMem *)camel_stream_mem_new();

	filter = (CamelStream *)camel_stream_filter_new_with_stream(indisk);
	check_count(indisk, 2);
	id = camel_stream_filter_add((CamelStreamFilter *)filter, f);
	check_count(f, 2);

	check(camel_stream_write_to_stream(filter, (CamelStream *)in) > 0);
	check_msg(in->buffer->len == out->buffer->len
		  && memcmp(in->buffer->data, out->buffer->data, in->buffer->len) == 0,
		  "Buffer content mismatch, %d != %d, in = '%.*s' != out = '%.*s'", in->buffer->len, out->buffer->len,
		  in->buffer->len, in->buffer->data, out->buffer->len, out->buffer->data);

	camel_test_pull();

	camel_stream_filter_remove((CamelStreamFilter *)filter, id);
	check_count(f, 1);
	camel_mime_filter_reset(f);

	check_unref(filter, 1);
	check_count(indisk, 1);
	check_count(f, 1);
	check_unref(in, 1);

	check(camel_stream_reset(indisk) == 0);

	camel_test_push("writing through filter stream");

	in = (CamelStreamMem *)camel_stream_mem_new();
	filter = (CamelStream *)camel_stream_filter_new_with_stream((CamelStream *)in);
	check_count(in, 2);
	id = camel_stream_filter_add((CamelStreamFilter *)filter, f);
	check_count(f, 2);

	check(camel_stream_write_to_stream(indisk, filter) > 0);
	check(camel_stream_flush(filter) == 0);
	check_msg(in->buffer->len == out->buffer->len
		  && memcmp(in->buffer->data, out->buffer->data, in->buffer->len) == 0,
		  "Buffer content mismatch, %d != %d, in = '%.*s' != out = '%.*s'", in->buffer->len, out->buffer->len,
		  in->buffer->len, in->buffer->data, out->buffer->len, out->buffer->data);

	camel_stream_filter_remove((CamelStreamFilter *)filter, id);
	check_unref(filter, 1);
	check_unref(in, 1);
	check_unref(indisk, 1);
	check_unref(outdisk, 1);
	check_unref(out, 1);

	camel_test_pull();

	camel_test_pull();
}
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;
}
static gboolean
mh_folder_append_message_sync (CamelFolder *folder,
                               CamelMimeMessage *message,
                               CamelMessageInfo *info,
                               gchar **appended_uid,
                               GCancellable *cancellable,
                               GError **error)
{
	CamelLocalFolder *lf = (CamelLocalFolder *) folder;
	CamelStream *output_stream;
	CamelMessageInfo *mi;
	gchar *name;
	gboolean has_attachment;

	/* FIXME: probably needs additional locking (although mh doesn't appear do do it) */

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

	/* If we can't lock, don't do anything */
	if (!lf || camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1)
		return FALSE;

	/* 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 check_changed;

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

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

	/* write it out, use the uid we got from the summary */
	name = g_strdup_printf("%s/%s", lf->folder_path, camel_message_info_uid(mi));
	output_stream = camel_stream_fs_new_with_name (
		name, O_WRONLY | O_CREAT, 0600, error);
	if (output_stream == NULL)
		goto fail_write;

	if (camel_data_wrapper_write_to_stream_sync (
		(CamelDataWrapper *) message, output_stream, cancellable, error) == -1
	    || camel_stream_close (output_stream, cancellable, error) == -1)
		goto fail_write;

	/* close this? */
	g_object_unref (output_stream);

	g_free (name);

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

	goto check_changed;

 fail_write:

	/* remove the summary info so we are not out-of-sync with the mh folder */
	camel_folder_summary_remove_uid (CAMEL_FOLDER_SUMMARY (folder->summary),
					 camel_message_info_uid (mi));

	g_prefix_error (
		error, _("Cannot append message to mh folder: %s: "), name);

	if (output_stream) {
		g_object_unref (output_stream);
		unlink (name);
	}

	g_free (name);

 check_changed:
	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);
	}

	return TRUE;
}
static CamelMimeMessage *
mh_folder_get_message_sync (CamelFolder *folder,
                            const gchar *uid,
                            GCancellable *cancellable,
                            GError **error)
{
	CamelLocalFolder *lf = (CamelLocalFolder *) folder;
	CamelStream *message_stream = NULL;
	CamelMimeMessage *message = NULL;
	CamelMessageInfo *info;
	gchar *name = NULL;

	d(printf("getting message: %s\n", uid));

	if (!lf || camel_local_folder_lock (lf, CAMEL_LOCK_WRITE, error) == -1)
		return NULL;

	/* get the message summary info */
	if ((info = camel_folder_summary_get (folder->summary, uid)) == NULL) {
		set_cannot_get_message_ex (
			error, CAMEL_FOLDER_ERROR_INVALID_UID,
			uid, lf->folder_path, _("No such message"));
		goto fail;
	}

	/* we only need it to check the message exists */
	camel_message_info_free (info);

	name = g_strdup_printf("%s/%s", lf->folder_path, uid);
	message_stream = camel_stream_fs_new_with_name (
		name, O_RDONLY, 0, error);
	if (message_stream == NULL) {
		g_prefix_error (
			error, _("Cannot get message %s from folder %s: "),
			name, lf->folder_path);
		goto fail;
	}

	message = camel_mime_message_new ();
	if (!camel_data_wrapper_construct_from_stream_sync (
		(CamelDataWrapper *) message,
		message_stream, cancellable, error)) {
		g_prefix_error (
			error, _("Cannot get message %s from folder %s: "),
			name, lf->folder_path);
		g_object_unref (message);
		message = NULL;

	}
	g_object_unref (message_stream);

 fail:
	g_free (name);

	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);
	}

	return message;
}
static gint
do_perf (gint argc,
         gchar **argv)
{
	CamelIndex *idx;
	DIR *dir;
	const gchar *path = "/home/notzed/evolution/local/Inbox/mbox/cur";
	struct dirent *d;
	CamelStream *null, *filter, *stream;
	CamelMimeFilter *filter_index;
	gchar *name;
	CamelIndexName *idn;

	dir = opendir (path);
	if (dir == NULL) {
		perror("open dir");
		return 1;
	}

	idx = (CamelIndex *) camel_text_index_new (
		"/tmp/index", O_TRUNC|O_CREAT|O_RDWR);
	if (idx == NULL) {
		perror("open index");
		closedir (dir);
		return 1;
	}

	null = camel_stream_null_new ();
	filter = camel_stream_filter_new (null);
	g_object_unref (null);
	filter_index = camel_mime_filter_index_new (idx);
	camel_stream_filter_add ((CamelStreamFilter *) filter, filter_index);

	while ((d = readdir (dir))) {
		printf("indexing '%s'\n", d->d_name);

		idn = camel_index_add_name (idx, d->d_name);
		camel_mime_filter_index_set_name (
			CAMEL_MIME_FILTER_INDEX (filter_index), idn);
		name = g_strdup_printf("%s/%s", path, d->d_name);
		stream = camel_stream_fs_new_with_name (name, O_RDONLY, 0, NULL);
		camel_stream_write_to_stream (stream, filter, NULL, NULL);
		g_object_unref (stream);
		g_free (name);

		camel_index_write_name (idx, idn);
		g_object_unref (idn);
		camel_mime_filter_index_set_name (
			CAMEL_MIME_FILTER_INDEX (filter_index), NULL);
	}

	closedir (dir);

	camel_index_sync (idx);
	g_object_unref (idx);

	g_object_unref (filter);
	g_object_unref (filter_index);

	return 0;
}
Example #15
0
void
org_gnome_format_tnef(void *ep, EMFormatHookTarget *t)
{
	char *tmpdir = NULL, *name = NULL;
	CamelStream *out;
	struct dirent *d;
	DIR *dir;
	CamelMultipart *mp;
	CamelMimePart *mainpart;
	CamelDataWrapper *content;
	int len;
	TNEFStruct *tnef;
	tnef = (TNEFStruct *) g_malloc(sizeof(TNEFStruct));

	tmpdir = e_mkdtemp("tnef-attachment-XXXXXX");
	if (tmpdir == NULL)
		return;

	filepath = tmpdir;

	name = g_build_filename(tmpdir, ".evo-attachment.tnef", NULL);

	out = camel_stream_fs_new_with_name(name, O_RDWR|O_CREAT, 0666);
	if (out == NULL)
	    goto fail;
	content = camel_medium_get_content_object((CamelMedium *)t->part);
	if (content == NULL)
		goto fail;
	if (camel_data_wrapper_decode_to_stream(content, out) == -1
	    || camel_stream_close(out) == -1) {
		camel_object_unref(out);
 		goto fail;
	}
	camel_object_unref(out);

	/* Extracting the winmail.dat */
        TNEFInitialize(tnef);
	tnef->Debug = verbose;
        if (TNEFParseFile(name, tnef) == -1) {
            printf("ERROR processing file\n");
        }
	processTnef(tnef);

        TNEFFree(tnef);
	/* Extraction done */

	dir = opendir(tmpdir);
	if (dir == NULL)
	    goto fail;

	mainpart = camel_mime_part_new();

	mp = camel_multipart_new();
	camel_data_wrapper_set_mime_type((CamelDataWrapper *)mp, "multipart/mixed");
	camel_multipart_set_boundary(mp, NULL);

	camel_medium_set_content_object((CamelMedium *)mainpart, (CamelDataWrapper *)mp);

	while ((d = readdir(dir))) {
		CamelMimePart *part;
		CamelDataWrapper *content;
		CamelStream *stream;
		char *path;
		const char *type;

		if (!strcmp(d->d_name, ".")
		    || !strcmp(d->d_name, "..")
		    || !strcmp(d->d_name, ".evo-attachment.tnef"))
		    continue;

		path = g_build_filename(tmpdir, d->d_name, NULL);

		stream = camel_stream_fs_new_with_name(path, O_RDONLY, 0);
		content = camel_data_wrapper_new();
		camel_data_wrapper_construct_from_stream(content, stream);
		camel_object_unref(stream);

		part = camel_mime_part_new();
		camel_mime_part_set_encoding(part, CAMEL_TRANSFER_ENCODING_BINARY);

		camel_medium_set_content_object((CamelMedium *)part, content);
		camel_object_unref(content);

		type = em_utils_snoop_type(part);
		if (type)
		    camel_data_wrapper_set_mime_type((CamelDataWrapper *)part, type);

		camel_mime_part_set_filename(part, d->d_name);

		g_free(path);

		camel_multipart_add_part(mp, part);
	}

	closedir(dir);

	len = t->format->part_id->len;
	g_string_append_printf(t->format->part_id, ".tnef");

	if (camel_multipart_get_number(mp) > 0)
		em_format_part_as(t->format, t->stream, mainpart, "multipart/mixed");
	else if (t->item->handler.old)
	    t->item->handler.old->handler(t->format, t->stream, t->part, t->item->handler.old);

	g_string_truncate(t->format->part_id, len);

	camel_object_unref(mainpart);

	goto ok;
 fail:
	if (t->item->handler.old)
	    t->item->handler.old->handler(t->format, t->stream, t->part, t->item->handler.old);
 ok:
	g_free(name);
	g_free(tmpdir);
}
Example #16
0
static void
import_mbox_exec (struct _import_mbox_msg *m,
                  GCancellable *cancellable,
                  GError **error)
{
	CamelFolder *folder;
	CamelMimeParser *mp = NULL;
	struct stat st;
	gint fd;

	if (g_stat (m->path, &st) == -1) {
		g_warning (
			"cannot find source file to import '%s': %s",
			m->path, g_strerror (errno));
		return;
	}

	if (m->uri == NULL || m->uri[0] == 0)
		folder = e_mail_session_get_local_folder (
			m->session, E_MAIL_LOCAL_FOLDER_INBOX);
	else
		folder = e_mail_session_uri_to_folder_sync (
			m->session, m->uri, CAMEL_STORE_FOLDER_CREATE,
			cancellable, error);

	if (folder == NULL)
		return;

	if (S_ISREG (st.st_mode)) {
		gboolean any_read = FALSE;

		fd = g_open (m->path, O_RDONLY | O_BINARY, 0);
		if (fd == -1) {
			g_warning (
				"cannot find source file to import '%s': %s",
				m->path, g_strerror (errno));
			goto fail1;
		}

		mp = camel_mime_parser_new ();
		camel_mime_parser_scan_from (mp, TRUE);
		if (camel_mime_parser_init_with_fd (mp, fd) == -1) {
			/* will never happen - 0 is unconditionally returned */
			goto fail2;
		}

		camel_operation_push_message (
			cancellable, _("Importing '%s'"),
			camel_folder_get_display_name (folder));
		camel_folder_freeze (folder);
		while (camel_mime_parser_step (mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM &&
		       !g_cancellable_is_cancelled (cancellable)) {

			CamelMimeMessage *msg;
			gint pc = 0;

			any_read = TRUE;

			if (st.st_size > 0)
				pc = (gint) (100.0 * ((gdouble)
					camel_mime_parser_tell (mp) /
					(gdouble) st.st_size));
			camel_operation_progress (cancellable, pc);

			msg = camel_mime_message_new ();
			if (!camel_mime_part_construct_from_parser_sync (
				(CamelMimePart *) msg, mp, NULL, NULL)) {
				/* set exception? */
				g_object_unref (msg);
				break;
			}

			import_mbox_add_message (folder, msg, cancellable, error);

			g_object_unref (msg);

			if (error && *error != NULL)
				break;

			camel_mime_parser_step (mp, NULL, NULL);
		}

		if (!any_read && !g_cancellable_is_cancelled (cancellable)) {
			CamelStream *stream;

			stream = camel_stream_fs_new_with_name (m->path, O_RDONLY, 0, NULL);
			if (stream) {
				CamelMimeMessage *msg;

				msg = camel_mime_message_new ();

				if (camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) msg, stream, NULL, NULL))
					import_mbox_add_message (folder, msg, cancellable, error);

				g_object_unref (msg);
				g_object_unref (stream);
			}
		}
		/* Not passing a GCancellable or GError here. */
		camel_folder_synchronize_sync (folder, FALSE, NULL, NULL);
		camel_folder_thaw (folder);
		camel_operation_pop_message (cancellable);
	fail2:
		g_object_unref (mp);
	}
fail1:
	/* Not passing a GCancellable or GError here. */
	camel_folder_synchronize_sync (folder, FALSE, NULL, NULL);
	g_object_unref (folder);
	/* 'fd' is freed together with 'mp' */
	/* coverity[leaked_handle] */
}