aboutsummaryrefslogtreecommitdiffstats
path: root/mail/mail-ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'mail/mail-ops.c')
-rw-r--r--mail/mail-ops.c259
1 files changed, 142 insertions, 117 deletions
diff --git a/mail/mail-ops.c b/mail/mail-ops.c
index 1132271e08..8bfc050149 100644
--- a/mail/mail-ops.c
+++ b/mail/mail-ops.c
@@ -1091,7 +1091,7 @@ mail_transfer_messages (EMailSession *session,
struct _sync_folder_msg {
MailMsg base;
- EMailSession *session;
+ EMailBackend *backend;
CamelFolder *folder;
void (*done) (CamelFolder *folder, gpointer data);
gpointer data;
@@ -1123,10 +1123,11 @@ sync_folder_done (struct _sync_folder_msg *m)
static void
sync_folder_free (struct _sync_folder_msg *m)
{
- g_object_unref (m->folder);
+ if (m->backend)
+ g_object_unref (m->backend);
- if (m->session)
- g_object_unref (m->session);
+ if (m->folder)
+ g_object_unref (m->folder);
}
static MailMsgInfo sync_folder_info = {
@@ -1145,8 +1146,7 @@ mail_sync_folder (CamelFolder *folder,
struct _sync_folder_msg *m;
m = mail_msg_new (&sync_folder_info);
- m->folder = folder;
- g_object_ref (folder);
+ m->folder = g_object_ref (folder);
m->data = data;
m->done = done;
@@ -1222,9 +1222,8 @@ mail_sync_store (CamelStore *store,
struct _sync_store_msg *m;
m = mail_msg_new (&sync_store_info);
- m->store = store;
+ m->store = g_object_ref (store);
m->expunge = expunge;
- g_object_ref (store);
m->data = data;
m->done = done;
@@ -1267,8 +1266,7 @@ mail_refresh_folder (CamelFolder *folder,
struct _sync_folder_msg *m;
m = mail_msg_new (&refresh_folder_info);
- m->folder = folder;
- g_object_ref (folder);
+ m->folder = g_object_ref (folder);
m->data = data;
m->done = done;
@@ -1293,115 +1291,125 @@ folder_is_from_source_uid (CamelFolder *folder,
/* This is because pop3 accounts are hidden under local Inbox,
* thus whenever an expunge is done on a local trash or Inbox,
* then also all active pop3 accounts should be expunged. */
-static void
+static gboolean
expunge_pop3_stores (CamelFolder *expunging,
- EMailSession *session,
+ EMailBackend *backend,
GCancellable *cancellable,
GError **error)
{
+ GHashTable *expunging_uids;
+ EMailSession *session;
GPtrArray *uids;
- CamelFolder *folder;
EAccount *account;
EIterator *iter;
- guint i;
- GHashTable *expunging_uids = NULL;
+ gboolean success = TRUE;
+ guint ii;
- uids = camel_folder_get_uids (expunging);
- if (!uids)
- return;
-
- for (i = 0; i < uids->len; i++) {
- CamelMessageInfo *info;
+ session = e_mail_backend_get_session (backend);
- info = camel_folder_get_message_info (
- expunging, uids->pdata[i]);
+ uids = camel_folder_get_uids (expunging);
- if (!info)
- continue;
+ if (uids == NULL)
+ return TRUE;
- if ((camel_message_info_flags (info) & CAMEL_MESSAGE_DELETED) != 0) {
- CamelMimeMessage *msg;
- GError *local_error = NULL;
+ expunging_uids = g_hash_table_new_full (
+ (GHashFunc) g_str_hash,
+ (GEqualFunc) g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_free);
- /* because the UID in the local store doesn't
- * match with the UID in the pop3 store */
- msg = camel_folder_get_message_sync (
- expunging, uids->pdata[i],
- cancellable, &local_error);
- if (msg) {
- const gchar *pop3_uid;
+ for (ii = 0; ii < uids->len; ii++) {
+ CamelMessageInfo *info;
+ CamelMessageFlags flags = 0;
+ CamelMimeMessage *message;
+ const gchar *pop3_uid;
+ const gchar *source_uid;
- pop3_uid = camel_medium_get_header (
- CAMEL_MEDIUM (msg),
- "X-Evolution-POP3-UID");
- if (pop3_uid) {
- gchar *duped;
+ info = camel_folder_get_message_info (
+ expunging, uids->pdata[ii]);
- duped = g_strstrip (g_strdup (pop3_uid));
+ if (info != NULL) {
+ flags = camel_message_info_flags (info);
+ camel_folder_free_message_info (expunging, info);
+ }
- if (!expunging_uids)
- expunging_uids = g_hash_table_new_full (
- g_str_hash, g_str_equal,
+ /* Only interested in deleted messages. */
+ if ((flags & CAMEL_MESSAGE_DELETED) == 0)
+ continue;
- g_free, g_free);
+ /* because the UID in the local store doesn't
+ * match with the UID in the pop3 store */
+ message = camel_folder_get_message_sync (
+ expunging, uids->pdata[ii], cancellable, NULL);
- g_hash_table_insert (
- expunging_uids, duped,
- g_strdup (camel_mime_message_get_source (msg)));
- }
+ if (message == NULL)
+ continue;
- g_object_unref (msg);
- }
+ pop3_uid = camel_medium_get_header (
+ CAMEL_MEDIUM (message), "X-Evolution-POP3-UID");
+ source_uid = camel_mime_message_get_source (message);
- if (local_error)
- g_clear_error (&local_error);
- }
+ if (pop3_uid != NULL)
+ g_hash_table_insert (
+ expunging_uids,
+ g_strstrip (g_strdup (pop3_uid)),
+ g_strstrip (g_strdup (source_uid)));
- camel_folder_free_message_info (expunging, info);
+ g_object_unref (message);
}
camel_folder_free_uids (expunging, uids);
uids = NULL;
- if (!expunging_uids)
- return;
+ if (g_hash_table_size (expunging_uids) == 0) {
+ g_hash_table_destroy (expunging_uids);
+ return TRUE;
+ }
for (iter = e_list_get_iterator ((EList *) e_get_account_list ());
- e_iterator_is_valid (iter) && (!error || !*error);
- e_iterator_next (iter)) {
+ e_iterator_is_valid (iter); e_iterator_next (iter)) {
account = (EAccount *) e_iterator_get (iter);
if (account->enabled &&
account->source && account->source->url &&
g_str_has_prefix (account->source->url, "pop://")) {
+ CamelFolder *folder;
gboolean any_found = FALSE;
folder = e_mail_session_get_inbox_sync (
session, account->uid, cancellable, error);
- if (!folder || (error && *error))
- continue;
+
+ /* Abort the loop on error. */
+ if (folder == NULL) {
+ success = FALSE;
+ break;
+ }
uids = camel_folder_get_uids (folder);
if (uids) {
- for (i = 0; i < uids->len; i++) {
+ for (ii = 0; ii < uids->len; ii++) {
/* ensure the ID is from this account,
* as it's generated by evolution */
const gchar *source_uid;
source_uid = g_hash_table_lookup (
- expunging_uids, uids->pdata[i]);
+ expunging_uids, uids->pdata[ii]);
if (folder_is_from_source_uid (folder, source_uid)) {
any_found = TRUE;
- camel_folder_delete_message (folder, uids->pdata[i]);
+ camel_folder_delete_message (folder, uids->pdata[ii]);
}
}
camel_folder_free_uids (folder, uids);
}
if (any_found)
- camel_folder_synchronize_sync (folder, TRUE, cancellable, error);
+ success = camel_folder_synchronize_sync (folder, TRUE, cancellable, error);
g_object_unref (folder);
+
+ /* Abort the loop on error. */
+ if (!success)
+ break;
}
}
@@ -1409,6 +1417,8 @@ expunge_pop3_stores (CamelFolder *expunging,
g_object_unref (iter);
g_hash_table_destroy (expunging_uids);
+
+ return success;
}
static gchar *
@@ -1424,26 +1434,38 @@ expunge_folder_exec (struct _sync_folder_msg *m,
GCancellable *cancellable,
GError **error)
{
- gboolean is_local_inbox_or_trash =
- m->folder == e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_INBOX);
+ CamelFolder *local_inbox;
+ CamelStore *local_store;
+ CamelStore *parent_store;
+ gboolean is_local_inbox_or_trash;
+ gboolean success = TRUE;
- if (!is_local_inbox_or_trash && e_mail_local_get_store () ==
- camel_folder_get_parent_store (m->folder)) {
+ local_inbox = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_INBOX);
+ is_local_inbox_or_trash = (m->folder == local_inbox);
+
+ local_store = e_mail_local_get_store ();
+ parent_store = camel_folder_get_parent_store (m->folder);
+
+ if (!is_local_inbox_or_trash && local_store == parent_store) {
CamelFolder *trash;
- trash = e_mail_session_get_trash_sync (
- m->session, "local", cancellable, error);
+ trash = camel_store_get_trash_folder_sync (
+ parent_store, cancellable, error);
+
+ if (trash == NULL)
+ return;
- is_local_inbox_or_trash = m->folder == trash;
+ is_local_inbox_or_trash = (m->folder == trash);
g_object_unref (trash);
}
/* do this before expunge, to know which messages will be expunged */
- if (is_local_inbox_or_trash && (!error || !*error))
- expunge_pop3_stores (m->folder, m->session, cancellable, error);
+ if (is_local_inbox_or_trash)
+ success = expunge_pop3_stores (
+ m->folder, m->backend, cancellable, error);
- if (!error || !*error)
+ if (success)
camel_folder_expunge_sync (m->folder, cancellable, error);
}
@@ -1457,19 +1479,14 @@ static MailMsgInfo expunge_folder_info = {
};
void
-mail_expunge_folder (EMailSession *session,
- CamelFolder *folder,
- void (*done) (CamelFolder *folder, gpointer data),
- gpointer data)
+mail_expunge_folder (EMailBackend *backend,
+ CamelFolder *folder)
{
struct _sync_folder_msg *m;
m = mail_msg_new (&expunge_folder_info);
- m->session = g_object_ref (session);
- m->folder = folder;
- g_object_ref (folder);
- m->data = data;
- m->done = done;
+ m->backend = g_object_ref (backend);
+ m->folder = g_object_ref (folder);
mail_msg_slow_ordered_push (m);
}
@@ -1479,17 +1496,21 @@ mail_expunge_folder (EMailSession *session,
struct _empty_trash_msg {
MailMsg base;
- EMailSession *session;
- EAccount *account;
- void (*done) (EAccount *account, gpointer data);
- gpointer data;
+ EMailBackend *backend;
+ CamelStore *store;
};
static gchar *
empty_trash_desc (struct _empty_trash_msg *m)
{
- return g_strdup_printf (_("Emptying trash in '%s'"),
- m->account ? m->account->name : _("Local Folders"));
+ CamelService *service;
+ const gchar *display_name;
+
+ service = CAMEL_SERVICE (m->store);
+ display_name = camel_service_get_display_name (service);
+
+ return g_strdup_printf (
+ _("Emptying trash in '%s'"), display_name);
}
static void
@@ -1497,39 +1518,46 @@ empty_trash_exec (struct _empty_trash_msg *m,
GCancellable *cancellable,
GError **error)
{
+ CamelService *service;
CamelFolder *trash;
const gchar *uid;
+ gboolean success = TRUE;
- uid = (m->account != NULL) ? m->account->uid : "local";
+ service = CAMEL_SERVICE (m->store);
+ uid = camel_service_get_uid (service);
- trash = e_mail_session_get_trash_sync (
- m->session, uid, cancellable, error);
+ if (!em_utils_connect_service_sync (service, cancellable, error))
+ return;
- if (trash) {
- /* do this before expunge, to know which messages will be expunged */
- if (!m->account && (!error || !*error))
- expunge_pop3_stores (trash, m->session, cancellable, error);
+ trash = camel_store_get_trash_folder_sync (
+ m->store, cancellable, error);
- if (!error || !*error)
- camel_folder_expunge_sync (trash, cancellable, error);
- g_object_unref (trash);
- }
+ if (trash == NULL)
+ return;
+
+ /* do this before expunge, to know which messages will be expunged */
+ if (g_strcmp0 (uid, "local") == 0)
+ success = expunge_pop3_stores (
+ trash, m->backend, cancellable, error);
+
+ if (success)
+ camel_folder_expunge_sync (trash, cancellable, error);
+
+ g_object_unref (trash);
}
static void
empty_trash_done (struct _empty_trash_msg *m)
{
- if (m->done)
- m->done (m->account, m->data);
}
static void
empty_trash_free (struct _empty_trash_msg *m)
{
- if (m->session)
- g_object_unref (m->session);
- if (m->account)
- g_object_unref (m->account);
+ if (m->backend)
+ g_object_unref (m->backend);
+ if (m->store)
+ g_object_unref (m->store);
}
static MailMsgInfo empty_trash_info = {
@@ -1541,20 +1569,17 @@ static MailMsgInfo empty_trash_info = {
};
void
-mail_empty_trash (EMailSession *session,
- EAccount *account,
- void (*done) (EAccount *account, gpointer data),
- gpointer data)
+mail_empty_trash (EMailBackend *backend,
+ CamelStore *store)
{
struct _empty_trash_msg *m;
+ g_return_if_fail (E_IS_MAIL_BACKEND (backend));
+ g_return_if_fail (CAMEL_IS_STORE (store));
+
m = mail_msg_new (&empty_trash_info);
- m->session = g_object_ref (session);
- m->account = account;
- if (account)
- g_object_ref (account);
- m->data = data;
- m->done = done;
+ m->backend = g_object_ref (backend);
+ m->store = g_object_ref (store);
mail_msg_slow_ordered_push (m);
}