gboolean e_mail_store_go_offline_sync (CamelStore *store, GCancellable *cancellable, GError **error) { CamelService *service; const gchar *display_name; gboolean success = TRUE; g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE); service = CAMEL_SERVICE (store); display_name = camel_service_get_display_name (service); if (display_name == NULL || *display_name == '\0') display_name = G_OBJECT_TYPE_NAME (service); camel_operation_push_message ( cancellable, _("Disconnecting from “%s”"), display_name); if (CAMEL_IS_OFFLINE_STORE (store)) { success = camel_offline_store_set_online_sync ( CAMEL_OFFLINE_STORE (store), FALSE, cancellable, error); } else { success = camel_service_disconnect_sync ( service, TRUE, cancellable, error); } camel_operation_pop_message (cancellable); return success; }
static void pop3_store_dispose (GObject *object) { CamelPOP3StorePrivate *priv; priv = CAMEL_POP3_STORE_GET_PRIVATE (object); /* Force disconnect so we dont have it run * later, after we've cleaned up some stuff. */ camel_service_disconnect_sync ( CAMEL_SERVICE (object), TRUE, NULL, NULL); g_clear_object (&priv->cache); g_clear_object (&priv->engine); /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (camel_pop3_store_parent_class)->dispose (object); }
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); }
/* this should probably take a folder instead of a session ... */ void test_folder_message_ops (CamelSession *session, const gchar *name, gint local, const gchar *mailbox) { CamelStore *store; CamelService *service; CamelFolder *folder; CamelMimeMessage *msg; gint j; gint indexed, max; GPtrArray *uids; CamelMessageInfo *info; GError *error = NULL; max = local ? 2 : 1; for (indexed = 0; indexed < max; indexed++) { gchar *what = g_strdup_printf ("folder ops: %s %s", name, local ? (indexed?"indexed":"non-indexed"):""); gint flags; camel_test_start (what); test_free (what); push ("getting store"); service = camel_session_add_service ( session, name, name, CAMEL_PROVIDER_STORE, &error); check_msg (error == NULL, "adding store: %s", error->message); check (CAMEL_IS_STORE (service)); store = CAMEL_STORE (service); g_clear_error (&error); pull (); push ("creating %sindexed folder", indexed?"":"non-"); if (indexed) flags = CAMEL_STORE_FOLDER_CREATE | CAMEL_STORE_FOLDER_BODY_INDEX; else flags = CAMEL_STORE_FOLDER_CREATE; folder = camel_store_get_folder_sync ( store, mailbox, flags, NULL, &error); /* we can't create mailbox outside of namespace, since we have no api for it, try * using inbox namespace, works for courier */ if (folder == NULL) { gchar *mbox = g_strdup_printf ("INBOX/%s", mailbox); mailbox = mbox; g_clear_error (&error); folder = camel_store_get_folder_sync ( store, mailbox, flags, NULL, &error); } check_msg (error == NULL, "%s", error->message); check (folder != NULL); /* verify empty/can't get nonexistant stuff */ test_folder_counts (folder, 0, 0); test_folder_not_message (folder, "0"); test_folder_not_message (folder, ""); for (j = 0; j < 10; j++) { gchar *content, *subject; push ("creating test message"); msg = test_message_create_simple (); content = g_strdup_printf ("Test message %d contents\n\n", j); test_message_set_content_simple ( (CamelMimePart *) msg, 0, "text/plain", content, strlen (content)); test_free (content); subject = g_strdup_printf ("Test message %d", j); camel_mime_message_set_subject (msg, subject); pull (); push ("appending simple message %d", j); camel_folder_append_message_sync ( folder, msg, NULL, NULL, NULL, &error); check_msg (error == NULL, "%s", error->message); #if 0 /* sigh, this shouldn't be required, but the imap code is too dumb to do it itself */ if (!local) { push ("forcing a refresh of folder updates"); camel_folder_refresh_info (folder, ex); check_msg (error == NULL, "%s", error->message); pull (); } #endif /*if (!local) camel_test_nonfatal ("unread counts dont seem right for imap");*/ test_folder_counts (folder, j + 1, j + 1); /*if (!local) camel_test_fatal ();*/ push ("checking it is in the right uid slot & exists"); uids = camel_folder_get_uids (folder); check (uids != NULL); check (uids->len == j + 1); if (uids->len > j) test_folder_message (folder, uids->pdata[j]); pull (); push ("checking it is the right message (subject): %s", subject); if (uids->len > j) { info = camel_folder_get_message_info (folder, uids->pdata[j]); check (info != NULL); check_msg ( strcmp (camel_message_info_get_subject (info), subject) == 0, "info->subject %s", camel_message_info_get_subject (info)); camel_message_info_unref (info); } camel_folder_free_uids (folder, uids); pull (); test_free (subject); /*if (!local) camel_test_fatal ();*/ check_unref (msg, 1); pull (); } if (local) check_unref (folder, 1); else check_unref (folder, 2); pull (); #if 0 push ("deleting test folder, with messages in it"); camel_store_delete_folder (store, mailbox, ex); check (camel_exception_is_set (ex)); camel_exception_clear (ex); pull (); #endif push ("re-opening folder"); folder = camel_store_get_folder_sync ( store, mailbox, flags, NULL, &error); check_msg (error == NULL, "%s", error->message); check (folder != NULL); g_clear_error (&error); /* verify counts */ test_folder_counts (folder, 10, 10); /* re-check uid's, after a reload */ uids = camel_folder_get_uids (folder); check (uids != NULL); check (uids->len == 10); for (j = 0; j < 10; j++) { gchar *subject = g_strdup_printf ("Test message %d", j); push ("verify reload of %s", subject); test_folder_message (folder, uids->pdata[j]); info = camel_folder_get_message_info (folder, uids->pdata[j]); check_msg ( strcmp (camel_message_info_get_subject (info), subject) == 0, "info->subject %s", camel_message_info_get_subject (info)); test_free (subject); camel_message_info_unref (info); pull (); } push ("deleting first message & expunging"); camel_folder_delete_message (folder, uids->pdata[0]); test_folder_counts (folder, 10, 9); camel_folder_expunge_sync (folder, NULL, &error); check_msg (error == NULL, "%s", error->message); g_clear_error (&error); test_folder_not_message (folder, uids->pdata[0]); test_folder_counts (folder, 9, 9); camel_folder_free_uids (folder, uids); uids = camel_folder_get_uids (folder); check (uids != NULL); check (uids->len == 9); for (j = 0; j < 9; j++) { gchar *subject = g_strdup_printf ("Test message %d", j + 1); push ("verify after expunge of %s", subject); test_folder_message (folder, uids->pdata[j]); info = camel_folder_get_message_info (folder, uids->pdata[j]); check_msg ( strcmp (camel_message_info_get_subject (info), subject) == 0, "info->subject %s", camel_message_info_get_subject (info)); test_free (subject); camel_message_info_unref (info); pull (); } pull (); push ("deleting last message & expunging"); camel_folder_delete_message (folder, uids->pdata[8]); /* sync? */ test_folder_counts (folder, 9, 8); camel_folder_expunge_sync (folder, NULL, &error); check_msg (error == NULL, "%s", error->message); g_clear_error (&error); test_folder_not_message (folder, uids->pdata[8]); test_folder_counts (folder, 8, 8); camel_folder_free_uids (folder, uids); uids = camel_folder_get_uids (folder); check (uids != NULL); check (uids->len == 8); for (j = 0; j < 8; j++) { gchar *subject = g_strdup_printf ("Test message %d", j + 1); push ("verify after expunge of %s", subject); test_folder_message (folder, uids->pdata[j]); info = camel_folder_get_message_info (folder, uids->pdata[j]); check_msg ( strcmp (camel_message_info_get_subject (info), subject) == 0, "info->subject %s", camel_message_info_get_subject (info)); test_free (subject); camel_message_info_unref (info); pull (); } pull (); push ("deleting all messages & expunging"); for (j = 0; j < 8; j++) { camel_folder_delete_message (folder, uids->pdata[j]); } /* sync? */ test_folder_counts (folder, 8, 0); camel_folder_expunge_sync (folder, NULL, &error); check_msg (error == NULL, "%s", error->message); g_clear_error (&error); for (j = 0; j < 8; j++) { test_folder_not_message (folder, uids->pdata[j]); } test_folder_counts (folder, 0, 0); camel_folder_free_uids (folder, uids); pull (); if (local) check_unref (folder, 1); else check_unref (folder, 2); pull (); /* re-opening folder */ if (g_ascii_strcasecmp (mailbox, "INBOX") != 0) { push ("deleting test folder, with no messages in it"); camel_store_delete_folder_sync ( store, mailbox, NULL, &error); check_msg (error == NULL, "%s", error->message); g_clear_error (&error); pull (); } if (!local) { push ("disconneect service"); camel_service_disconnect_sync ( CAMEL_SERVICE (store), TRUE, NULL, &error); check_msg (error == NULL, "%s", error->message); g_clear_error (&error); pull (); } check_unref (store, 1); camel_test_end (); } }
static gboolean groupwise_connect_sync (CamelService *service, GCancellable *cancellable, GError **error) { CamelGroupwiseStore *store = CAMEL_GROUPWISE_STORE (service); CamelGroupwiseStorePrivate *priv = store->priv; CamelGroupwiseStoreNamespace *ns; CamelSession *session = service->session; d("in groupwise store connect\n"); if (service->status == CAMEL_SERVICE_DISCONNECTED) return FALSE; if (!priv) { store->priv = g_new0 (CamelGroupwiseStorePrivate, 1); priv = store->priv; camel_service_construct (service, service->session, service->provider, service->url, error); } camel_service_lock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); if (priv->cnc) { camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); return TRUE; } if (!check_for_connection (service, cancellable, error) || !groupwise_auth_loop (service, cancellable, error)) { camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); camel_service_disconnect_sync (service, TRUE, NULL); return FALSE; } service->status = CAMEL_SERVICE_CONNECTED; camel_offline_store_set_online_sync ( CAMEL_OFFLINE_STORE (store), TRUE, cancellable, NULL); if (!e_gw_connection_get_version (priv->cnc)) { camel_session_alert_user (session, CAMEL_SESSION_ALERT_WARNING, _("Some features may not work correctly with your current server version"), FALSE); } ns = camel_groupwise_store_summary_namespace_new (store->summary, priv->storage_path, '/'); camel_groupwise_store_summary_namespace_set (store->summary, ns); if (camel_store_summary_count ((CamelStoreSummary *)store->summary) == 0) { /*Settting the refresh stamp to the current time*/ store->refresh_stamp = time (NULL); } camel_store_summary_save ((CamelStoreSummary *) store->summary); camel_service_unlock (service, CAMEL_SERVICE_REC_CONNECT_LOCK); if (E_IS_GW_CONNECTION (priv->cnc)) { return TRUE; } return FALSE; }