static void
refresh_folders_exec (struct _refresh_folders_msg *m,
                      GCancellable *cancellable,
                      GError **error)
{
	CamelFolder *folder;
	EMailSession *session;
	gint i;
	GError *local_error = NULL;
	gulong handler_id = 0;

	if (cancellable)
		handler_id = g_signal_connect (
			m->info->cancellable, "cancelled",
			G_CALLBACK (main_op_cancelled_cb), cancellable);

	get_folders (m->store, m->folders, m->finfo);

	camel_operation_push_message (m->info->cancellable, _("Updating..."));

	session = m->info->session;

	for (i = 0; i < m->folders->len; i++) {
		folder = e_mail_session_uri_to_folder_sync (
			session,
			m->folders->pdata[i], 0,
			cancellable, &local_error);
		if (folder) {
			/* FIXME Not passing a GError here. */
			camel_folder_synchronize_sync (
				folder, FALSE, cancellable, NULL);
			camel_folder_refresh_info_sync (folder, cancellable, NULL);
			g_object_unref (folder);
		} else if (local_error != NULL) {
			g_warning ("Failed to refresh folders: %s", local_error->message);
			g_clear_error (&local_error);
		}

		if (g_cancellable_is_cancelled (m->info->cancellable))
			break;

		if (m->info->state != SEND_CANCELLED)
			camel_operation_progress (
				m->info->cancellable, 100 * i / m->folders->len);
	}

	camel_operation_pop_message (m->info->cancellable);

	if (cancellable)
		g_signal_handler_disconnect (m->info->cancellable, handler_id);
}
static void
offline_folder_downsync (CamelOfflineFolder *offline, const char *expression, CamelException *ex)
{
	CamelFolder *folder = (CamelFolder *) offline;
	CamelMimeMessage *message;
	GPtrArray *uids;
	int i;

	camel_operation_start (NULL, _("Syncing messages in folder '%s' to disk"), folder->full_name);

	if (expression)
		uids = camel_folder_search_by_expression (folder, expression, ex);
	else
		uids = camel_folder_get_uids (folder);

	if (!uids) {
		camel_operation_end (NULL);
		return;
	}

	for (i = 0; i < uids->len; i++) {
		int pc = i * 100 / uids->len;

		message = camel_folder_get_message (folder, uids->pdata[i], ex);
		camel_operation_progress (NULL, pc);
		if (message == NULL)
			break;

		camel_object_unref (message);
	}

	if (expression)
		camel_folder_search_free (folder, uids);
	else
		camel_folder_free_uids (folder, uids);

	camel_operation_end (NULL);
}
static void
offline_downsync_sync (CamelSession *session, CamelSessionThreadMsg *mm)
{
	struct _offline_downsync_msg *m = (struct _offline_downsync_msg *) mm;
	CamelMimeMessage *message;
	int i;

	camel_operation_start (NULL, _("Downloading new messages for offline mode"));

	if (m->changes) {
		for (i = 0; i < m->changes->uid_added->len; i++) {
			int pc = i * 100 / m->changes->uid_added->len;

			camel_operation_progress (NULL, pc);
			if ((message = camel_folder_get_message (m->folder, m->changes->uid_added->pdata[i], &mm->ex)))
				camel_object_unref (message);
		}
	} else {
		camel_offline_folder_downsync ((CamelOfflineFolder *) m->folder, "(match-all)", &mm->ex);
	}

	camel_operation_end (NULL);
}
static void
mail_send_short_to_thread (GSimpleAsyncResult *simple, EMailSession *session,
						GCancellable *cancellable)
{
	SendAsyncContext *context;
	CamelFolder *local_sent_folder;
	CamelProvider *provider;
	CamelService *service;
	CamelInternetAddress *cia;
	const gchar *addr;
	gint i, len;
	gboolean copy_to_sent = TRUE;
	GError *error = NULL;
	gboolean success = FALSE;
	gboolean did_connect = FALSE;
	gboolean cancelled = FALSE;

	context = g_simple_async_result_get_op_res_gpointer (simple);

	/* Connect transport service */

	service = context->transport;

	if (camel_service_get_connection_status (service) !=
						CAMEL_SERVICE_CONNECTED) {
		did_connect = TRUE;

		if (!camel_service_connect_sync (service, &error)) {
			mail_send_short_connection_fail (context);
			g_simple_async_result_take_error (simple, error);
			return;
		}
	}

	provider = camel_service_get_provider (service);

	if (provider->flags & CAMEL_PROVIDER_DISABLE_SENT_FOLDER)
		copy_to_sent = FALSE;

	/* Send the message to each individual recipient. */

	len = camel_address_length (context->recipients);
	for (i = 0; i < len; i++) {
		if (!cancelled) {
			if (!camel_internet_address_get(
				CAMEL_INTERNET_ADDRESS(context->recipients),
				i, NULL, &addr))
					continue;

			cia = camel_internet_address_new ();
			camel_internet_address_add (cia, NULL, addr);
			camel_transport_send_to_sync (
				CAMEL_TRANSPORT (service), context->message,
				context->from, CAMEL_ADDRESS(cia),
				cancellable, &error);
			g_object_unref(cia);
		}

		if (error) {
			g_variant_builder_add (context->result, "(sssi)", addr,
					error->message,
					g_quark_to_string(error->domain),
					error->code);
			if (g_error_matches (error, G_IO_ERROR,
							G_IO_ERROR_CANCELLED))
				cancelled = TRUE;
			else
				g_clear_error (&error);
		} else {
			g_variant_builder_add (context->result, "(sssi)", addr,
								"", "", 0);
			success = TRUE;
		}

		camel_operation_progress (cancellable, (i+1)*100/len);
	}

	g_clear_error (&error);

	if (did_connect)
		camel_service_disconnect_sync (service, FALSE, NULL);

	/*** Post Processing ***/

	if (!success) {
		g_simple_async_result_set_error (
					simple, E_MAIL_ERROR,
					E_MAIL_ERROR_POST_PROCESSING,
					_("All recipients failed"));
		return;
	}

	/* Run filters on the outgoing message. */
	if (context->driver != NULL) {
		camel_filter_driver_filter_message (
			context->driver, context->message, context->info,
			NULL, NULL, NULL, "", cancellable, &error);

		if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
			goto exit;
		g_clear_error (&error);
	}

	if (!copy_to_sent)
		goto cleanup;

	/* Append the sent message to a Sent folder. */
	local_sent_folder = e_mail_session_get_local_folder (session,
						E_MAIL_LOCAL_FOLDER_SENT);

	/* Try to extract a CamelFolder from the Sent folder URI. */
	if (context->sent_folder_uri != NULL) {
		context->sent_folder = e_mail_session_uri_to_folder_sync (
					session, context->sent_folder_uri, 0,
					cancellable, &error);
		if (error != NULL) {
			g_warn_if_fail (context->sent_folder == NULL);
			g_clear_error (&error);
		}
	}

	/* Fall back to the local Sent folder. */
	if (context->sent_folder == NULL)
		context->sent_folder = g_object_ref (local_sent_folder);

	/* Append the message. */
	camel_folder_append_message_sync (
				context->sent_folder, context->message,
				context->info, NULL, cancellable, &error);

	if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
		goto exit;

	if (error == NULL)
		goto cleanup;

	/* If appending to a remote Sent folder failed,
	 * try appending to the local Sent folder. */
	if (context->sent_folder != local_sent_folder) {
		g_clear_error (&error);
		camel_folder_append_message_sync (local_sent_folder,
					context->message, context->info, NULL,
					cancellable, &error);
	}

	if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
		goto exit;

	/* We can't even append to the local Sent folder?
	 * In that case just leave the message in Outbox. */
	if (error != NULL) {
		g_clear_error (&error);
		goto exit;
	}

cleanup:

	/* The send operation was successful; ignore cleanup errors. */

	/* Mark the draft message for deletion, if present. */
	e_mail_session_handle_draft_headers_sync (session, context->message,
							cancellable, &error);
	if (error != NULL) {
		g_warning ("%s", error->message);
		g_clear_error (&error);
	}

	/* Set flags on the original source message, if present.
	 * Source message refers to the message being forwarded
	 * or replied to. */
	e_mail_session_handle_source_headers_sync (session, context->message,
							cancellable, &error);
	if (error != NULL) {
		g_warning ("%s", error->message);
		g_clear_error (&error);
	}

exit:

	/* If we were cancelled, disregard any other errors. */
	if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
		g_simple_async_result_take_error (simple, error);

	/* Stuff the accumulated error messages in a GError. */
	} else if (error != NULL) {
		g_simple_async_result_set_error (simple, E_MAIL_ERROR,
			E_MAIL_ERROR_POST_PROCESSING, "%s", error->message);
	}

	/* Synchronize the Sent folder. */
	if (context->sent_folder != NULL)
		camel_folder_synchronize_sync (context->sent_folder, FALSE,
							cancellable, NULL);
}
/**
 * camel_operation_progress_count:
 * @cc: operation context
 * @sofar:
 *
 **/
void
camel_operation_progress_count (CamelOperation *cc, int sofar)
{
	camel_operation_progress(cc, sofar);
}
void
camel_disco_diary_replay (CamelDiscoDiary *diary, CamelException *ex)
{
	guint32 action;
	off_t size;
	double pc;

	d(printf("disco diary replay\n"));

	fseek (diary->file, 0, SEEK_END);
	size = ftell (diary->file);
	g_return_if_fail (size != 0);
	rewind (diary->file);

	camel_operation_start (NULL, _("Resynchronizing with server"));
	while (!camel_exception_is_set (ex)) {
		pc = ftell (diary->file) / size;
		camel_operation_progress (NULL, pc * 100);

		if (camel_file_util_decode_uint32 (diary->file, &action) == -1)
			break;
		if (action == CAMEL_DISCO_DIARY_END)
			break;

		switch (action) {
		case CAMEL_DISCO_DIARY_FOLDER_EXPUNGE:
		{
			CamelFolder *folder;
			GPtrArray *uids;

			folder = diary_decode_folder (diary);
			uids = diary_decode_uids (diary);
			if (!uids)
				goto lose;

			if (folder)
				camel_disco_folder_expunge_uids (folder, uids, ex);
			free_uids (uids);
			break;
		}

		case CAMEL_DISCO_DIARY_FOLDER_APPEND:
		{
			CamelFolder *folder;
			char *uid, *ret_uid;
			CamelMimeMessage *message;
			CamelMessageInfo *info;

			folder = diary_decode_folder (diary);
			if (camel_file_util_decode_string (diary->file, &uid) == -1)
				goto lose;

			if (!folder) {
				g_free (uid);
				continue;
			}

			message = camel_folder_get_message (folder, uid, NULL);
			if (!message) {
				/* The message was appended and then deleted. */
				g_free (uid);
				continue;
			}
			info = camel_folder_get_message_info (folder, uid);

			camel_folder_append_message (folder, message, info, &ret_uid, ex);
			camel_folder_free_message_info (folder, info);

			if (ret_uid) {
				camel_disco_diary_uidmap_add (diary, uid, ret_uid);
				g_free (ret_uid);
			}
			g_free (uid);

			break;
		}

		case CAMEL_DISCO_DIARY_FOLDER_TRANSFER:
		{
			CamelFolder *source, *destination;
			GPtrArray *uids, *ret_uids;
			guint32 delete_originals;
			int i;

			source = diary_decode_folder (diary);
			destination = diary_decode_folder (diary);
			uids = diary_decode_uids (diary);
			if (!uids)
				goto lose;
			if (camel_file_util_decode_uint32 (diary->file, &delete_originals) == -1)
				goto lose;

			if (!source || !destination) {
				free_uids (uids);
				continue;
			}

			camel_folder_transfer_messages_to (source, uids, destination, &ret_uids, delete_originals, ex);

			if (ret_uids) {
				for (i = 0; i < uids->len; i++) {
					if (!ret_uids->pdata[i])
						continue;
					camel_disco_diary_uidmap_add (diary, uids->pdata[i], ret_uids->pdata[i]);
					g_free (ret_uids->pdata[i]);
				}
				g_ptr_array_free (ret_uids, TRUE);
			}
			free_uids (uids);
			break;
		}

		}
	}

 lose:
	camel_operation_end (NULL);

	/* Close folders */
	g_hash_table_foreach (diary->folders, close_folder, diary);
	g_hash_table_destroy (diary->folders);
	diary->folders = NULL;

	/* Truncate the log */
	ftruncate (fileno (diary->file), 0);
}
static void
import_mbox_exec (struct _import_mbox_msg *m)
{
	CamelFolder *folder;
	CamelMimeParser *mp = NULL;
	struct stat st;
	int fd;
	CamelMessageInfo *info;

	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 = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_INBOX);
	else
		folder = mail_tool_uri_to_folder(m->uri, CAMEL_STORE_FOLDER_CREATE, &m->base.ex);

	if (folder == NULL)
		return;

	if (S_ISREG(st.st_mode)) {
		CamelOperation *oldcancel = NULL;

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

		if (m->cancel)
			oldcancel = camel_operation_register(m->cancel);

		camel_operation_start(NULL, _("Importing `%s'"), folder->full_name);
		camel_folder_freeze(folder);
		while (camel_mime_parser_step(mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM) {
			CamelMimeMessage *msg;
			const char *tmp;
			int pc = 0;
			guint32 flags = 0;

			if (st.st_size > 0)
				pc = (int)(100.0 * ((double)camel_mime_parser_tell(mp) / (double)st.st_size));
			camel_operation_progress(NULL, pc);

			msg = camel_mime_message_new();
			if (camel_mime_part_construct_from_parser((CamelMimePart *)msg, mp) == -1) {
				/* set exception? */
				camel_object_unref(msg);
				break;
			}

			info = camel_message_info_new(NULL);

			tmp = camel_medium_get_header((CamelMedium *)msg, "X-Mozilla-Status");
			if (tmp)
				flags |= decode_mozilla_status(tmp);
			tmp = camel_medium_get_header((CamelMedium *)msg, "Status");
			if (tmp)
				flags |= decode_status(tmp);
			tmp = camel_medium_get_header((CamelMedium *)msg, "X-Status");
			if (tmp)
				flags |= decode_status(tmp);

			camel_message_info_set_flags(info, flags, ~0);
			camel_folder_append_message(folder, msg, info, NULL, &m->base.ex);
			camel_message_info_free(info);
			camel_object_unref(msg);

			if (camel_exception_is_set(&m->base.ex))
				break;

			camel_mime_parser_step(mp, NULL, NULL);
		}
		camel_folder_sync(folder, FALSE, NULL);
		camel_folder_thaw(folder);
		camel_operation_end(NULL);
		/* TODO: these api's are a bit weird, registering the old is the same as deregistering */
		if (m->cancel)
			camel_operation_register(oldcancel);
	fail2:
		camel_object_unref(mp);
	}
fail1:
	camel_folder_sync(folder, FALSE, NULL);
	camel_object_unref(folder);
}
Exemple #8
0
static void
dbx_import_file (DbxImporter *m)
{
	EShell *shell;
	EShellBackend *shell_backend;
	EMailSession *session;
	GCancellable *cancellable;
	gchar *filename;
	CamelFolder *folder;
	gint tmpfile;
	gint i;
	gint missing = 0;
	m->status_what = NULL;
	filename = g_filename_from_uri (
		((EImportTargetURI *) m->target)->uri_src, NULL, NULL);

	/* Destination folder, was set in our widget */
	m->parent_uri = g_strdup (((EImportTargetURI *) m->target)->uri_dest);

	cancellable = m->base.cancellable;

	/* XXX Dig up the EMailSession from the default EShell.
	 *     Since the EImport framework doesn't allow for user
	 *     data, I don't see how else to get to it. */
	shell = e_shell_get_default ();
	shell_backend = e_shell_get_backend_by_name (shell, "mail");
	session = e_mail_backend_get_session (E_MAIL_BACKEND (shell_backend));

	camel_operation_push_message (NULL, _("Importing “%s”"), filename);
	folder = e_mail_session_uri_to_folder_sync (
		session, m->parent_uri, CAMEL_STORE_FOLDER_CREATE,
		cancellable, &m->base.error);
	if (!folder)
		return;
	d (printf ("importing to %s\n", camel_folder_get_full_name (folder)));

	camel_folder_freeze (folder);

	filename = g_filename_from_uri (
		((EImportTargetURI *) m->target)->uri_src, NULL, NULL);
	m->dbx_fd = g_open (filename, O_RDONLY, 0);
	g_free (filename);

	if (m->dbx_fd == -1) {
		g_set_error (
			&m->base.error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			"Failed to open import file");
		goto out;
	}

	if (!dbx_load_indices (m))
		goto out;

	tmpfile = e_mkstemp ("dbx-import-XXXXXX");
	if (tmpfile == -1) {
		g_set_error (
			&m->base.error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			"Failed to create temporary file for import");
		goto out;
	}

	for (i = 0; i < m->index_count; i++) {
		CamelMessageInfo *info;
		CamelMimeMessage *msg;
		CamelMimeParser *mp;
		gint dbx_flags = 0;
		gint flags = 0;
		gboolean success;

		camel_operation_progress (NULL, 100 * i / m->index_count);
		camel_operation_progress (cancellable, 100 * i / m->index_count);

		if (!dbx_read_email (m, m->indices[i], tmpfile, &dbx_flags)) {
			d (
				printf ("Cannot read email index %d at %x\n",
				i, m->indices[i]));
			if (m->base.error != NULL)
				goto out;
			missing++;
			continue;
		}
		if (dbx_flags & 0x40)
			flags |= CAMEL_MESSAGE_DELETED;
		if (dbx_flags & 0x80)
			flags |= CAMEL_MESSAGE_SEEN;
		if (dbx_flags & 0x80000)
			flags |= CAMEL_MESSAGE_ANSWERED;

		mp = camel_mime_parser_new ();

		lseek (tmpfile, 0, SEEK_SET);
		camel_mime_parser_init_with_fd (mp, tmpfile);

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

		info = camel_message_info_new (NULL);
		camel_message_info_set_flags (info, flags, ~0);
		success = camel_folder_append_message_sync (
			folder, msg, info, NULL,
			cancellable, &m->base.error);
		g_clear_object (&info);
		g_object_unref (msg);

		if (!success) {
			g_object_unref (mp);
			break;
		}
	}
 out:
	if (m->dbx_fd != -1)
		close (m->dbx_fd);
	if (m->indices)
		g_free (m->indices);
	/* FIXME Not passing GCancellable or GError here. */
	camel_folder_synchronize_sync (folder, FALSE, NULL, NULL);
	camel_folder_thaw (folder);
	g_object_unref (folder);
	if (missing && m->base.error == NULL) {
		g_set_error (
			&m->base.error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			"%d messages imported correctly; %d message "
			"bodies were not present in the DBX file",
			m->index_count - missing, missing);
	}
	camel_operation_pop_message (NULL);
}
Exemple #9
0
static void
import_kmail_folder (struct _import_mbox_msg *m,
                     gchar *k_path_in,
                     GCancellable *cancellable,
                     GError **error)
{
	const gchar *special_folders []= {"cur", "tmp", "new", NULL};
	gchar *special_path;
	const CamelStore *store;
	CamelFolder *folder;
	CamelMimeParser *mp = NULL;
	CamelMessageInfo *info;
	CamelMimeMessage *msg;
	guint32 flags = 0;

	gchar *e_uri, *e_path;
	gchar *k_path;
	const gchar *d;
	gchar *mail_url;
	GDir *dir;
	struct stat st;
	gint fd, i;

	e_uri = kuri_to_euri (k_path_in);
	/* we need to drop some folders, like: Trash */
	if (!e_uri)
		return;

	/* In case we using async way in the future */
	k_path = g_strdup (k_path_in);
	store = evolution_get_local_store ();
	e_path = e_uri + strlen (EVOLUTION_LOCAL_BASE) + 1;
	e_mail_store_create_folder_sync ((CamelStore *)store, e_path, NULL, NULL);
	folder = e_mail_session_uri_to_folder_sync (
			m->session, e_uri, CAMEL_STORE_FOLDER_CREATE,
			cancellable, NULL);

	if (folder == NULL) {
		g_free (k_path);
		g_warning ("evolution error: cannot get the folder\n");
		return;
	}

	camel_operation_push_message (
			cancellable, _("Importing '%s'"),
			camel_folder_get_display_name (folder));
	camel_folder_freeze (folder);

	for (i = 0; special_folders [i]; i++) {
		camel_operation_progress (cancellable, 100*i/3);
		special_path = g_build_filename (k_path, special_folders[i], NULL);
		dir = g_dir_open (special_path, 0, NULL);
		while ((d = g_dir_read_name (dir))) {
			if ((strcmp (d, ".") == 0) || (strcmp (d, "..") == 0)) {
				continue;
			}
			mail_url = g_build_filename (special_path, d, NULL);
			if (g_stat (mail_url, &st) == -1) {
				g_free (mail_url);
				continue;
			}
			if (S_ISREG (st.st_mode)) {
				fd = g_open (mail_url, O_RDONLY | O_BINARY, 0);
				g_free (mail_url);
				if (fd == -1) {
					continue;
				}
				mp = camel_mime_parser_new ();
				camel_mime_parser_scan_from (mp, FALSE);
				if (camel_mime_parser_init_with_fd (mp, fd) == -1) {
					/* will never happen - 0 is unconditionally returned */
					g_object_unref (mp);
					continue;
				}
				msg = camel_mime_message_new ();
				if (!camel_mime_part_construct_from_parser_sync (
						(CamelMimePart *) msg, mp, NULL, NULL)) {
					/* set exception? */
					g_object_unref (mp);
					g_object_unref (msg);
					continue;
				}
				info = camel_message_info_new (NULL);
				if (strcmp (special_folders[i], "cur") == 0) {
					flags |= CAMEL_MESSAGE_SEEN;
				} else if (strcmp (special_folders[i], "tmp") == 0) {
					flags |= CAMEL_MESSAGE_DELETED; /* Mark the 'tmp' mails as 'deleted' */
				}
				camel_message_info_set_flags (info, flags, ~0);
				camel_folder_append_message_sync (
					folder, msg, info, NULL,
					cancellable, error);
				camel_message_info_unref (info);
				g_object_unref (msg);
				g_object_unref (mp);
			} else {
				g_free (mail_url);
			}
		}
	}
	camel_operation_progress (cancellable, 100);
	camel_folder_synchronize_sync (folder, FALSE, NULL, NULL);
	camel_folder_thaw (folder);
	camel_operation_pop_message (cancellable);

	g_free (k_path);
}
Exemple #10
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] */
}