예제 #1
0
void
e_mail_store_remove_by_account (EMailBackend *backend,
                                EAccount *account)
{
	EMailSession *session;
	CamelService *service;
	CamelProvider *provider;
	const gchar *uid;

	g_return_if_fail (E_IS_MAIL_BACKEND (backend));
	g_return_if_fail (E_IS_ACCOUNT (account));

	uid = account->uid;
	session = e_mail_backend_get_session (backend);

	service = camel_session_get_service (CAMEL_SESSION (session), uid);
	g_return_if_fail (CAMEL_IS_STORE (service));

	provider = camel_service_get_provider (service);
	g_return_if_fail (provider != NULL);

	if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE))
		return;

	e_mail_store_remove (backend, CAMEL_STORE (service));
}
GtkWidget *
org_gnome_exchange_show_folder_size_factory (EPlugin *epl, EConfigHookItemFactoryData *data)
{
    EMConfigTargetFolder *target=  (EMConfigTargetFolder *)data->config->target;
    CamelFolder *cml_folder = target->folder;
    CamelService *service;
    CamelProvider *provider;
    ExchangeAccount *account;
    GtkWidget *lbl_size, *lbl_size_val;
    GtkListStore *model;
    GtkVBox *vbx;
    GtkHBox *hbx_size;
    char *folder_name, *folder_size;
    int mode;

    service = CAMEL_SERVICE (camel_folder_get_parent_store (cml_folder));
    if (!service)
        return NULL;

    provider = camel_service_get_provider (service);
    if (!provider)
        return NULL;

    if (g_ascii_strcasecmp (provider->protocol, "exchange"))
        return NULL;

    account = exchange_operations_get_exchange_account ();
    exchange_account_is_offline (account, &mode);
    if (mode == OFFLINE_MODE)
        return NULL;

    folder_name = (char*) camel_folder_get_name (cml_folder);
    if (!folder_name)
        folder_name = g_strdup ("name");

    model = exchange_account_folder_size_get_model (account);
    if (model)
        folder_size = g_strdup_printf (_("%s KB"), exchange_folder_size_get_val (model, folder_name));
    else
        folder_size = g_strdup (_("0 KB"));

    hbx_size = (GtkHBox*) gtk_hbox_new (FALSE, 0);
    vbx = (GtkVBox *)gtk_notebook_get_nth_page (GTK_NOTEBOOK (data->parent), 0);

    lbl_size = gtk_label_new_with_mnemonic (_("Size:"));
    lbl_size_val = gtk_label_new_with_mnemonic (_(folder_size));
    gtk_widget_show (lbl_size);
    gtk_widget_show (lbl_size_val);
    gtk_misc_set_alignment (GTK_MISC (lbl_size), 0.0, 0.5);
    gtk_misc_set_alignment (GTK_MISC (lbl_size_val), 0.0, 0.5);
    gtk_box_pack_start (GTK_BOX (hbx_size), lbl_size, FALSE, TRUE, 12);
    gtk_box_pack_start (GTK_BOX (hbx_size), lbl_size_val, FALSE, TRUE, 10);
    gtk_widget_show_all (GTK_WIDGET (hbx_size));

    gtk_box_pack_start (GTK_BOX (vbx), GTK_WIDGET (hbx_size), FALSE, FALSE, 0);
    g_free (folder_size);

    return GTK_WIDGET (hbx_size);
}
예제 #3
0
static gboolean
is_in_gw_account (EShellView *shell_view,
                  gboolean *is_on_store,
                  gchar **folder_full_name)
{
	EShellSidebar *shell_sidebar;
	EMFolderTree *folder_tree = NULL;
	GtkTreeSelection *selection;
	GtkTreeModel *model = NULL;
	GtkTreeIter iter;
	gboolean is_store = FALSE, res;
	CamelStore *store;
	CamelProvider *provider;
	gchar *full_name = NULL;

	if (folder_full_name)
		*folder_full_name = NULL;

	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
	g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL);
	g_return_val_if_fail (folder_tree != NULL, FALSE);

	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_tree));
	g_return_val_if_fail (selection != NULL, FALSE);

	if (!gtk_tree_selection_get_selected (selection, &model, &iter))
		return FALSE;

	gtk_tree_model_get (model, &iter,
		COL_STRING_FULL_NAME, &full_name,
		COL_POINTER_CAMEL_STORE, &store,
		COL_BOOL_IS_STORE, &is_store,
		-1);

	provider = camel_service_get_provider (CAMEL_SERVICE (store));

	res = g_strcmp0 (provider->protocol, "groupwise") == 0;

	if (is_on_store)
		*is_on_store = is_store;

	if (!is_store) {
		if (folder_full_name)
			*folder_full_name = full_name;
		else
			g_free (full_name);

	} else {
		g_free (full_name);
	}

	return res;
}
예제 #4
0
static void
send_receive_add_to_menu (SendReceiveData *data,
                          CamelService *service,
                          gint position)
{
	GtkWidget *menu_item;
	CamelProvider *provider;

	if (send_receive_find_menu_item (data, service) != NULL)
		return;

	provider = camel_service_get_provider (service);

	menu_item = gtk_menu_item_new ();
	gtk_widget_show (menu_item);

	e_binding_bind_property (
		service, "display-name",
		menu_item, "label",
		G_BINDING_SYNC_CREATE);

	if (provider && (provider->flags & CAMEL_PROVIDER_IS_REMOTE) != 0) {
		gpointer object;

		if (CAMEL_IS_OFFLINE_STORE (service))
			object = g_object_ref (service);
		else
			object = camel_service_ref_session (service);

		e_signal_connect_notify_object (
			object, "notify::online",
			G_CALLBACK (service_online_state_changed_cb), menu_item,
			0);

		g_object_unref (object);
	}

	g_hash_table_insert (
		data->menu_items, menu_item,
		g_object_ref (service));

	g_signal_connect (
		menu_item, "activate",
		G_CALLBACK (send_receive_account_item_activate_cb), data);

	/* Position is with respect to the sorted list of CamelService-s,
	 * not menu item position. */
	if (position < 0)
		gtk_menu_shell_append (data->menu, menu_item);
	else
		gtk_menu_shell_insert (data->menu, menu_item, position + 4);
}
static gboolean
is_eex_store_available (EShellView *shell_view)
{
	EShellSidebar *shell_sidebar;
	EMFolderTree *folder_tree = NULL;
	GtkTreeModel *model = NULL;
	GtkTreeIter iter;
	gboolean res = FALSE;

	g_return_val_if_fail (shell_view != NULL, FALSE);

	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
	g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL);
	g_return_val_if_fail (folder_tree != NULL, FALSE);

	model = gtk_tree_view_get_model (GTK_TREE_VIEW (folder_tree));
	g_return_val_if_fail (model != NULL, FALSE);

	if (!gtk_tree_model_get_iter_first (model, &iter))
		return FALSE;

	do {
		CamelStore *store;
		gboolean is_store;
		gboolean is_exchange_store = FALSE;

		gtk_tree_model_get (model, &iter,
			COL_POINTER_CAMEL_STORE, &store,
			COL_BOOL_IS_STORE, &is_store,
			-1);

		/* XXX Maybe move CamelExchangeStore to /server/lib so
		 *     we can query its GType directly?  Would probably
		 *     drag all the other CamelExchange classes with it,
		 *     but maybe that's okay? */
		if (CAMEL_IS_STORE (store)) {
			CamelService *service;
			CamelProvider *provider;
			const gchar *protocol;

			service = CAMEL_SERVICE (store);
			provider = camel_service_get_provider (service);
			protocol = (provider != NULL) ? provider->protocol : NULL;
			is_exchange_store = (g_strcmp0 (protocol, "exchange") == 0);
		}

		res = is_store && is_exchange_store;
	} while (!res && gtk_tree_model_iter_next (model, &iter));

	return res;
}
예제 #6
0
static send_info_t
get_receive_type (CamelService *service)
{
	CamelProvider *provider;
	CamelURL *url;
	const gchar *uid;
	gboolean is_local_delivery;

	/* Disregard CamelNullStores. */
	if (CAMEL_IS_NULL_STORE (service))
		return SEND_INVALID;

	url = camel_service_new_camel_url (service);
	is_local_delivery = em_utils_is_local_delivery_mbox_file (url);
	camel_url_free (url);

	/* mbox pointing to a file is a 'Local delivery'
	 * source which requires special processing. */
	if (is_local_delivery)
		return SEND_RECEIVE;

	provider = camel_service_get_provider (service);

	if (!provider)
		return SEND_INVALID;

	/* skip some well-known services */
	uid = camel_service_get_uid (service);
	if (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0)
		return SEND_INVALID;
	if (g_strcmp0 (uid, E_MAIL_SESSION_VFOLDER_UID) == 0)
 		return SEND_INVALID;

	if (provider->object_types[CAMEL_PROVIDER_STORE]) {
		if (provider->flags & CAMEL_PROVIDER_IS_STORAGE)
			return SEND_UPDATE;
		else
			return SEND_RECEIVE;
	}

	if (provider->object_types[CAMEL_PROVIDER_TRANSPORT])
		return SEND_SEND;

	return SEND_INVALID;
}
static GList *
smtp_transport_query_auth_types_sync (CamelService *service,
                                      GCancellable *cancellable,
                                      GError **error)
{
	CamelSmtpTransport *transport = CAMEL_SMTP_TRANSPORT (service);
	CamelServiceAuthType *authtype;
	CamelProvider *provider;
	GList *types, *t, *next;

	if (!connect_to_server (service, cancellable, error))
		return NULL;

	if (!transport->authtypes) {
		smtp_transport_disconnect_sync (
			service, TRUE, cancellable, NULL);
		return NULL;
	}

	provider = camel_service_get_provider (service);
	types = g_list_copy (provider->authtypes);

	for (t = types; t; t = next) {
		authtype = t->data;
		next = t->next;

		if (!g_hash_table_lookup (transport->authtypes, authtype->authproto)) {
			types = g_list_remove_link (types, t);
			g_list_free_1 (t);
		}
	}

	smtp_transport_disconnect_sync (service, TRUE, cancellable, NULL);

	return types;
}
예제 #8
0
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);
}
static void
mail_session_send_to_thread (GSimpleAsyncResult *simple,
                             EMailSession *session,
                             GCancellable *cancellable)
{
	AsyncContext *context;
	CamelProvider *provider;
	CamelFolder *folder = NULL;
	CamelFolder *local_sent_folder;
	CamelServiceConnectionStatus status;
	GString *error_messages;
	gboolean copy_to_sent = TRUE;
	gboolean did_connect = FALSE;
	guint ii;
	GError *error = NULL;

	context = g_simple_async_result_get_op_res_gpointer (simple);

	if (camel_address_length (context->recipients) == 0)
		goto skip_send;

	/* Send the message to all recipients. */

	/* XXX Leave this untranslated in gnome-3-8.
	 *     It was added during the string freeze,
	 *     but should rarely ever be seen by users. */
	if (context->transport == NULL) {
		g_simple_async_result_set_error (
			simple, CAMEL_SERVICE_ERROR,
			CAMEL_SERVICE_ERROR_UNAVAILABLE,
			"No mail transport service available");
		return;
	}

	status = camel_service_get_connection_status (context->transport);
	if (status != CAMEL_SERVICE_CONNECTED) {
		did_connect = TRUE;

		camel_service_connect_sync (
			context->transport, cancellable, &error);

		if (error != NULL) {
			g_simple_async_result_take_error (simple, error);
			return;
		}
	}

	provider = camel_service_get_provider (context->transport);

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

	camel_transport_send_to_sync (
		CAMEL_TRANSPORT (context->transport),
		context->message, context->from,
		context->recipients, cancellable, &error);

	if (did_connect) {
		/* Disconnect regardless of error or cancellation,
		 * but be mindful of these conditions when calling
		 * camel_service_disconnect_sync(). */
		if (g_cancellable_is_cancelled (cancellable)) {
			camel_service_disconnect_sync (
				context->transport, FALSE, NULL, NULL);
		} else if (error != NULL) {
			camel_service_disconnect_sync (
				context->transport, FALSE, cancellable, NULL);
		} else {
			camel_service_disconnect_sync (
				context->transport, TRUE, cancellable, &error);
		}

		if (error != NULL) {
			g_simple_async_result_take_error (simple, error);
			return;
		}
	}

skip_send:
	/* Post the message to requested folders. */
	for (ii = 0; ii < context->post_to_uris->len; ii++) {
		CamelFolder *folder;
		const gchar *folder_uri;

		folder_uri = g_ptr_array_index (context->post_to_uris, ii);

		folder = e_mail_session_uri_to_folder_sync (
			session, folder_uri, 0, cancellable, &error);

		if (error != NULL) {
			g_warn_if_fail (folder == NULL);
			g_simple_async_result_take_error (simple, error);
			return;
		}

		g_return_if_fail (CAMEL_IS_FOLDER (folder));

		camel_folder_append_message_sync (
			folder, context->message, context->info,
			NULL, cancellable, &error);

		g_object_unref (folder);

		if (error != NULL) {
			g_simple_async_result_take_error (simple, error);
			return;
		}
	}

	/*** Post Processing ***/

	/* This accumulates error messages during post-processing. */
	error_messages = g_string_sized_new (256);

	mail_tool_restore_xevolution_headers (context->message, context->xev);

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

		if (error != NULL) {
			g_string_append_printf (
				error_messages,
				_("Failed to apply outgoing filters: %s"),
				error->message);
			g_clear_error (&error);
		}

		if ((camel_message_info_flags (context->info) & CAMEL_MESSAGE_DELETED) != 0)
			copy_to_sent = FALSE;
	}

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

	folder = e_mail_session_get_fcc_for_message_sync (
		session, context->message, cancellable, &error);

	/* Sanity check. */
	g_return_if_fail (
		((folder != NULL) && (error == NULL)) ||
		((folder == NULL) && (error != NULL)));

	/* Append the message. */
	if (folder != NULL)
		camel_folder_append_message_sync (
			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 (folder != NULL && folder != local_sent_folder) {
		const gchar *description;

		description = camel_folder_get_description (folder);

		if (error_messages->len > 0)
			g_string_append (error_messages, "\n\n");
		g_string_append_printf (
			error_messages,
			_("Failed to append to %s: %s\n"
			"Appending to local 'Sent' folder instead."),
			description, error->message);
	}

	/* If appending to a remote Sent folder failed,
	 * try appending to the local Sent folder. */
	if (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) {
		if (error_messages->len > 0)
			g_string_append (error_messages, "\n\n");
		g_string_append_printf (
			error_messages,
			_("Failed to append to local 'Sent' folder: %s"),
			error->message);
		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_messages->len > 0) {
		g_simple_async_result_set_error (
			simple, E_MAIL_ERROR,
			E_MAIL_ERROR_POST_PROCESSING,
			"%s", error_messages->str);
	}

	/* Synchronize the Sent folder. */
	if (folder != NULL) {
		camel_folder_synchronize_sync (
			folder, FALSE, cancellable, NULL);
		g_object_unref (folder);
	}

	g_string_free (error_messages, TRUE);
}
예제 #10
0
static void
mail_session_send_to_thread (GSimpleAsyncResult *simple,
                             EMailSession *session,
                             GCancellable *cancellable)
{
	AsyncContext *context;
	CamelFolder *local_sent_folder;
	GString *error_messages;
	gboolean copy_to_sent = TRUE;
	guint ii;
	GError *error = NULL;

	context = g_simple_async_result_get_op_res_gpointer (simple);

	/* Send the message to all recipients. */
	if (camel_address_length (context->recipients) > 0) {
		CamelProvider *provider;
		CamelService *service;
		gboolean did_connect = FALSE;

		service = camel_session_get_service (
			CAMEL_SESSION (session), context->transport_uid);

		if (!CAMEL_IS_TRANSPORT (service)) {
			g_simple_async_result_set_error (simple,
				CAMEL_SERVICE_ERROR,
				CAMEL_SERVICE_ERROR_URL_INVALID,
				_("Cannot get transport for account '%s'"),
				context->transport_uid);
			return;
		}

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

			/* XXX This API does not allow for cancellation. */
			if (!em_utils_connect_service_sync (service, cancellable, &error)) {
				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;

		camel_transport_send_to_sync (
			CAMEL_TRANSPORT (service),
			context->message, context->from,
			context->recipients, cancellable, &error);

		if (did_connect)
			em_utils_disconnect_service_sync (
				service, error == NULL,
				cancellable, error ? NULL : &error);

		if (error != NULL) {
			g_simple_async_result_take_error (simple, error);
			return;
		}
	}

	/* Post the message to requested folders. */
	for (ii = 0; ii < context->post_to_uris->len; ii++) {
		CamelFolder *folder;
		const gchar *folder_uri;

		folder_uri = g_ptr_array_index (context->post_to_uris, ii);

		folder = e_mail_session_uri_to_folder_sync (
			session, folder_uri, 0, cancellable, &error);

		if (error != NULL) {
			g_warn_if_fail (folder == NULL);
			g_simple_async_result_take_error (simple, error);
			return;
		}

		g_return_if_fail (CAMEL_IS_FOLDER (folder));

		camel_folder_append_message_sync (
			folder, context->message, context->info,
			NULL, cancellable, &error);

		g_object_unref (folder);

		if (error != NULL) {
			g_simple_async_result_take_error (simple, error);
			return;
		}
	}

	/*** Post Processing ***/

	/* This accumulates error messages during post-processing. */
	error_messages = g_string_sized_new (256);

	mail_tool_restore_xevolution_headers (context->message, context->xev);

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

		if (error != NULL) {
			g_string_append_printf (
				error_messages,
				_("Failed to apply outgoing filters: %s"),
				error->message);
			g_clear_error (&error);
		}
	}

	if (!copy_to_sent)
		goto cleanup;

	/* Append the sent message to a Sent folder. */

	local_sent_folder = e_mail_local_get_folder (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);
			if (error_messages->len > 0)
				g_string_append (error_messages, "\n\n");
			g_string_append_printf (
				error_messages,
				_("Failed to append to %s: %s\n"
				  "Appending to local 'Sent' folder instead."),
				context->sent_folder_uri, error->message);
			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) {
		const gchar *description;

		description = camel_folder_get_description (
			context->sent_folder);

		if (error_messages->len > 0)
			g_string_append (error_messages, "\n\n");
		g_string_append_printf (
			error_messages,
			_("Failed to append to %s: %s\n"
			  "Appending to local 'Sent' folder instead."),
			description, error->message);
		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) {
		if (error_messages->len > 0)
			g_string_append (error_messages, "\n\n");
		g_string_append_printf (
			error_messages,
			_("Failed to append to local 'Sent' folder: %s"),
			error->message);
		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_messages->len > 0) {
		g_simple_async_result_set_error (
			simple, E_MAIL_ERROR,
			E_MAIL_ERROR_POST_PROCESSING,
			"%s", error_messages->str);
	}

	/* Synchronize the Sent folder. */
	if (context->sent_folder != NULL)
		camel_folder_synchronize_sync (
			context->sent_folder, FALSE, cancellable, NULL);

	g_string_free (error_messages, TRUE);
}
static gboolean
is_eex_folder_selected (EShellView *shell_view,
                        gchar **puri)
{
	ExchangeAccount *account = NULL;
	EShellSidebar *shell_sidebar;
	EMFolderTree *folder_tree = NULL;
	GtkTreeSelection *selection;
	GtkTreeModel *model = NULL;
	GtkTreeIter iter;
	CamelStore *store;
	gchar *folder_name;
	gboolean is_store = FALSE, res = FALSE;
	gboolean is_exchange_store = FALSE;

	g_return_val_if_fail (shell_view != NULL, FALSE);

	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
	g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL);
	g_return_val_if_fail (folder_tree != NULL, FALSE);

	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_tree));
	g_return_val_if_fail (selection != NULL, FALSE);

	if (!gtk_tree_selection_get_selected (selection, &model, &iter))
		return FALSE;

	gtk_tree_model_get (
		model, &iter,
		COL_POINTER_CAMEL_STORE, &store,
		COL_STRING_FULL_NAME, &folder_name,
		COL_BOOL_IS_STORE, &is_store,
		-1);

	/* XXX Maybe move CamelExchangeStore to /server/lib so
	 *     we can query its GType directly?  Would probably
	 *     drag all the other CamelExchange classes with it,
	 *     but maybe that's okay? */
	if (CAMEL_IS_STORE (store)) {
		CamelService *service;
		CamelProvider *provider;
		const gchar *protocol;

		service = CAMEL_SERVICE (store);
		provider = camel_service_get_provider (service);
		protocol = (provider != NULL) ? provider->protocol : NULL;
		is_exchange_store = (g_strcmp0 (protocol, "exchange") == 0);
	}

	res = !is_store && is_exchange_store;

	if (res) {
		gint mode;

		/* check for the account later, as it is connecting to the server for the first time */
		account = exchange_operations_get_exchange_account ();
		if (!account) {
			res = FALSE;
		} else {
			exchange_account_is_offline (account, &mode);
			if (mode == OFFLINE_MODE)
				res = FALSE;
		}
	}

	if (folder_name != NULL && puri != NULL) {
		*puri = folder_name;
		folder_name = NULL;
	}

	g_free (folder_name);

	return res;
}
예제 #12
0
gchar *
mail_tool_do_movemail (CamelStore *store,
                       GError **error)
{
#ifndef G_OS_WIN32
	CamelService *service;
	CamelProvider *provider;
	CamelSettings *settings;
	gchar *src_path;
	gchar *dest_path;
	struct stat sb;
	gboolean success;

	g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);

	service = CAMEL_SERVICE (store);
	provider = camel_service_get_provider (service);

	g_return_val_if_fail (provider != NULL, NULL);

	if (g_strcmp0 (provider->protocol, "mbox") != 0) {
		/* This is really only an internal error anyway */
		g_set_error (
			error, CAMEL_SERVICE_ERROR,
			CAMEL_SERVICE_ERROR_URL_INVALID,
			_("Trying to movemail a non-mbox source '%s'"),
			camel_service_get_uid (CAMEL_SERVICE (store)));
		return NULL;
	}

	settings = camel_service_ref_settings (service);

	src_path = camel_local_settings_dup_path (
		CAMEL_LOCAL_SETTINGS (settings));

	g_object_unref (settings);

	/* Set up our destination. */
	dest_path = mail_tool_get_local_movemail_path (store, error);
	if (dest_path == NULL)
		return NULL;

	/* Movemail from source to dest_path */
	success = camel_movemail (src_path, dest_path, error) != -1;

	g_free (src_path);

	if (g_stat (dest_path, &sb) < 0 || sb.st_size == 0) {
		g_unlink (dest_path); /* Clean up the movemail.foo file. */
		g_free (dest_path);
		return NULL;
	}

	if (!success) {
		g_free (dest_path);
		return NULL;
	}

	return dest_path;
#else
	/* Unclear yet whether camel-movemail etc makes any sense on
	 * Win32, at least it is not ported yet.
	 */
	g_warning ("%s: Not implemented", __FUNCTION__);
	return NULL;
#endif
}
예제 #13
0
static gchar *
format_service_name (CamelService *service)
{
	CamelProvider *provider;
	CamelSettings *settings;
	gchar *service_name = NULL;
	const gchar *display_name;
	gchar *pretty_url = NULL;
	gchar *host = NULL;
	gchar *path = NULL;
	gchar *user = NULL;
	gchar *cp;
	gboolean have_host = FALSE;
	gboolean have_path = FALSE;
	gboolean have_user = FALSE;

	provider = camel_service_get_provider (service);
	display_name = camel_service_get_display_name (service);

	settings = camel_service_ref_settings (service);

	if (CAMEL_IS_NETWORK_SETTINGS (settings)) {
		host = camel_network_settings_dup_host (
			CAMEL_NETWORK_SETTINGS (settings));
		have_host = (host != NULL) && (*host != '\0');

		user = camel_network_settings_dup_user (
			CAMEL_NETWORK_SETTINGS (settings));
		have_user = (user != NULL) && (*user != '\0');
	}

	if (CAMEL_IS_LOCAL_SETTINGS (settings)) {
		path = camel_local_settings_dup_path (
			CAMEL_LOCAL_SETTINGS (settings));
		have_path = (path != NULL) && (*path != '\0');
	}

	g_object_unref (settings);

	/* Shorten user names with '@', since multiple '@' in a
	 * 'user@host' label look weird.  This is just supposed
	 * to be a hint anyway so it doesn't matter if it's not
	 * strictly correct. */
	if (have_user && (cp = strchr (user, '@')) != NULL)
		*cp = '\0';

	g_return_val_if_fail (provider != NULL, NULL);

	/* This should never happen, but if the service has no
	 * display name, fall back to the generic service name. */
	if (display_name == NULL || *display_name == '\0') {
		service_name = camel_service_get_name (service, TRUE);
		display_name = service_name;
	}

	if (have_host && have_user) {
		pretty_url = g_markup_printf_escaped (
			"<b>%s</b> <small>(%s@%s)</small>",
			display_name, user, host);
	} else if (have_host) {
		pretty_url = g_markup_printf_escaped (
			"<b>%s</b> <small>(%s)</small>",
			display_name, host);
	} else if (have_path) {
		pretty_url = g_markup_printf_escaped (
			"<b>%s</b> <small>(%s)</small>",
			display_name, path);
	} else {
		pretty_url = g_markup_printf_escaped (
			"<b>%s</b>", display_name);
	}

	g_free (service_name);
	g_free (host);
	g_free (path);
	g_free (user);

	return pretty_url;
}
예제 #14
0
/**
 * mail_vfolder_add_folder:
 * @backend: an #EMailBackend
 * @store: a #CamelStore
 * @folder: a folder name
 * @remove: whether the folder should be removed or added
 *
 * Called when a new folder becomes (un)available.  If @store is not a
 * CamelVeeStore, the folder is added/removed from the list of cached source
 * folders.  Then each vfolder rule is checked to see if the specified folder
 * matches a source of the rule.  It builds a list of vfolders that use (or
 * would use) the specified folder as a source.  It then adds (or removes)
 * this folder to (from) those vfolders via camel_vee_folder_add/
 * remove_folder() but does not modify the actual filters or write changes
 * to disk.
 *
 * NOTE: This function must be called from the main thread.
 */
static void
mail_vfolder_add_folder (EMailBackend *backend,
                         CamelStore *store,
                         const gchar *folder_name,
                         gint remove)
{
	EMailSession *session;
	EFilterRule *rule;
	const gchar *source;
	CamelVeeFolder *vf;
	CamelProvider *provider;
	GList *folders = NULL, *link;
	GQueue *queue;
	gint remote;
	gint is_ignore;
	gchar *uri;

	session = e_mail_backend_get_session (backend);

	provider = camel_service_get_provider (CAMEL_SERVICE (store));
	remote = (provider->flags & CAMEL_PROVIDER_IS_REMOTE) != 0;
	queue = remote ? &source_folders_remote : &source_folders_local;

	if (folder_is_spethal (store, folder_name))
		return;

	g_return_if_fail (mail_in_main_thread ());

	uri = e_mail_folder_uri_build (store, folder_name);

	is_ignore = uri_is_ignore (backend, uri);

	G_LOCK (vfolder);

	/* maintain the source folders lists for changed rules later on */
	if (CAMEL_IS_VEE_STORE (store)) {
		is_ignore = TRUE;
	} else if (remove) {
		link = mv_find_folder (queue, session, uri);
		if (link != NULL) {
			g_free (link->data);
			g_queue_delete_link (queue, link);
		}
	} else if (!is_ignore) {
		/* we ignore drafts/sent/outbox here */
		if (mv_find_folder (queue, session, uri) == NULL)
			g_queue_push_tail (queue, g_strdup (uri));
	}

	if (context == NULL)
		goto done;

	rule = NULL;
	while ((rule = e_rule_context_next_rule ((ERuleContext *) context, rule, NULL))) {
		gint found = FALSE;

		if (!rule->name) {
			d(printf("invalid rule (%p): rule->name is set to NULL\n", rule));
			continue;
		}
		/* Don't auto-add any sent/drafts folders etc,
		 * they must be explictly listed as a source. */
		if (rule->source
		    && !is_ignore
		    && ((((EMVFolderRule *) rule)->with ==
				EM_VFOLDER_RULE_WITH_LOCAL && !remote)
			|| (((EMVFolderRule *) rule)->with ==
				EM_VFOLDER_RULE_WITH_REMOTE_ACTIVE && remote)
			|| (((EMVFolderRule *) rule)->with ==
				EM_VFOLDER_RULE_WITH_LOCAL_REMOTE_ACTIVE)))
			found = TRUE;

		source = NULL;
		while (!found && (source = em_vfolder_rule_next_source (
				(EMVFolderRule *) rule, source))) {
			found = e_mail_folder_uri_equal (
				CAMEL_SESSION (session), uri, source);
		}

		if (found) {
			vf = g_hash_table_lookup (vfolder_hash, rule->name);
			if (!vf) {
				g_warning ("vf is NULL for %s\n", rule->name);
				continue;
			}
			g_object_ref (vf);
			folders = g_list_prepend (folders, vf);
		}
	}

done:
	G_UNLOCK (vfolder);

	if (folders != NULL)
		vfolder_adduri (backend, uri, folders, remove);

	g_free (uri);
}