From 38c252cb336ba78b256f74e051591e9cf3142144 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 29 Apr 2022 10:23:57 +0200 Subject: [PATCH] build: Limit which parts link to the evolution libraries (and gtk+) Due to linking with Evolution in libraries not being used only in Evolution, the code could bring the GUI libraries into processes unexpectedly, especially gtk3 into a gtk4 application, which cannot be done. This change limits the linkage to the Evolution to necessary minimum, for a price of a small code duplication. Related to https://gitlab.gnome.org/GNOME/gnome-contacts/-/issues/222 --- src/EWS/camel/CMakeLists.txt | 12 -- src/EWS/camel/camel-ews-search.c | 35 +++- src/EWS/camel/camel-ews-store.c | 37 +--- src/EWS/camel/camel-ews-transport.c | 175 ++++++++++++++++-- src/EWS/camel/camel-ews-utils.c | 20 +- src/EWS/common/CMakeLists.txt | 3 - src/EWS/common/e-ews-calendar-utils.c | 23 ++- src/EWS/common/e-ews-folder.c | 30 +-- src/EWS/common/e-ews-folder.h | 6 +- src/Microsoft365/camel/CMakeLists.txt | 6 - src/Microsoft365/camel/camel-m365-store.c | 13 +- src/Microsoft365/camel/camel-m365-transport.c | 175 ++++++++++++++++-- src/Microsoft365/camel/camel-m365-utils.c | 17 +- 13 files changed, 402 insertions(+), 150 deletions(-) diff --git a/src/EWS/camel/CMakeLists.txt b/src/EWS/camel/CMakeLists.txt index e734a3b5..d9b5c202 100644 --- a/src/EWS/camel/CMakeLists.txt +++ b/src/EWS/camel/CMakeLists.txt @@ -50,8 +50,6 @@ target_compile_definitions(camelews-priv PRIVATE target_compile_options(camelews-priv PUBLIC ${CAMEL_CFLAGS} - ${EVOLUTION_SHELL_CFLAGS} - ${EVOLUTION_MAIL_CFLAGS} ${LIBEDATASERVER_CFLAGS} ${LIBECAL_CFLAGS} ${SOUP_CFLAGS} @@ -65,8 +63,6 @@ target_include_directories(camelews-priv PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CAMEL_INCLUDE_DIRS} - ${EVOLUTION_SHELL_INCLUDE_DIRS} - ${EVOLUTION_MAIL_INCLUDE_DIRS} ${LIBEDATASERVER_INCLUDE_DIRS} ${LIBECAL_INCLUDE_DIRS} ${SOUP_INCLUDE_DIRS} @@ -75,8 +71,6 @@ target_include_directories(camelews-priv PUBLIC target_link_libraries(camelews-priv ${DEPENDENCIES} ${CAMEL_LDFLAGS} - ${EVOLUTION_SHELL_LDFLAGS} - ${EVOLUTION_MAIL_LDFLAGS} ${LIBEDATASERVER_LDFLAGS} ${LIBECAL_LDFLAGS} ${SOUP_LDFLAGS} @@ -114,8 +108,6 @@ target_compile_definitions(camelews PRIVATE target_compile_options(camelews PUBLIC ${CAMEL_CFLAGS} - ${EVOLUTION_SHELL_CFLAGS} - ${EVOLUTION_MAIL_CFLAGS} ${LIBEDATASERVER_CFLAGS} ${LIBECAL_CFLAGS} ${SOUP_CFLAGS} @@ -128,8 +120,6 @@ target_include_directories(camelews PUBLIC ${CMAKE_SOURCE_DIR}/src/EWS ${CMAKE_CURRENT_BINARY_DIR} ${CAMEL_INCLUDE_DIRS} - ${EVOLUTION_SHELL_INCLUDE_DIRS} - ${EVOLUTION_MAIL_INCLUDE_DIRS} ${LIBEDATASERVER_INCLUDE_DIRS} ${LIBECAL_INCLUDE_DIRS} ${SOUP_INCLUDE_DIRS} @@ -138,8 +128,6 @@ target_include_directories(camelews PUBLIC target_link_libraries(camelews ${DEPENDENCIES} ${CAMEL_LDFLAGS} - ${EVOLUTION_SHELL_LDFLAGS} - ${EVOLUTION_MAIL_LDFLAGS} ${LIBEDATASERVER_LDFLAGS} ${LIBECAL_LDFLAGS} ${SOUP_LDFLAGS} diff --git a/src/EWS/camel/camel-ews-search.c b/src/EWS/camel/camel-ews-search.c index 30d76cbf..f42c4420 100644 --- a/src/EWS/camel/camel-ews-search.c +++ b/src/EWS/camel/camel-ews-search.c @@ -9,7 +9,6 @@ #include #include #include -#include #include "common/e-ews-query-to-restriction.h" @@ -190,6 +189,38 @@ ews_search_describe_criteria (const GPtrArray *words) return g_string_free (desc, FALSE); } +/* This is copy of e_str_replace_string(), to not depend on the evolution code + in the library code (and to not bring gtk+ into random processes). */ +static GString * +ews_str_replace_string (const gchar *text, + const gchar *before, + const gchar *after) +{ + const gchar *p, *next; + GString *str; + gint find_len; + + g_return_val_if_fail (text != NULL, NULL); + g_return_val_if_fail (before != NULL, NULL); + g_return_val_if_fail (*before, NULL); + + find_len = strlen (before); + str = g_string_new (""); + + p = text; + while (next = strstr (p, before), next) { + if (p < next) + g_string_append_len (str, p, next - p); + + if (after && *after) + g_string_append (str, after); + + p = next + find_len; + } + + return g_string_append (str, p); +} + static CamelSExpResult * ews_search_process_criteria (CamelSExp *sexp, CamelFolderSearch *search, @@ -254,7 +285,7 @@ ews_search_process_criteria (CamelSExp *sexp, for (ii = 0; ii < words->len; ii++) { GString *word; - word = e_str_replace_string (g_ptr_array_index (words, ii), "\"", "\\\""); + word = ews_str_replace_string (g_ptr_array_index (words, ii), "\"", "\\\""); g_string_append (expression, "(body-contains \""); g_string_append (expression, word->str); diff --git a/src/EWS/camel/camel-ews-store.c b/src/EWS/camel/camel-ews-store.c index 205ea02b..439d61e3 100644 --- a/src/EWS/camel/camel-ews-store.c +++ b/src/EWS/camel/camel-ews-store.c @@ -18,8 +18,6 @@ #include #include -#include - #include "common/camel-ews-settings.h" #include "common/e-ews-item-change.h" #include "common/e-ews-message.h" @@ -2545,23 +2543,17 @@ folder_info_from_store_summary (CamelEwsStore *store, if (!(fi->flags & CAMEL_FOLDER_SUBSCRIBED) && e_ews_folder_get_folder_type (folder) != E_EWS_FOLDER_TYPE_MAILBOX) { if (!hosturl && !username && !esources) { - CamelSession *session; CamelSettings *settings; CamelEwsSettings *ews_settings; - ESourceRegistry *registry = NULL; settings = camel_service_ref_settings (CAMEL_SERVICE (store)); ews_settings = CAMEL_EWS_SETTINGS (settings); - session = camel_service_ref_session (CAMEL_SERVICE (store)); - if (E_IS_MAIL_SESSION (session)) - registry = e_mail_session_get_registry (E_MAIL_SESSION (session)); hosturl = camel_ews_settings_dup_hosturl (ews_settings); username = camel_network_settings_dup_user (CAMEL_NETWORK_SETTINGS (ews_settings)); - esources = e_ews_folder_utils_get_esources (registry, hosturl, username, cancellable, NULL); + esources = e_ews_folder_utils_get_esources (hosturl, username, cancellable, NULL); g_object_unref (settings); - g_object_unref (session); } if (e_ews_folder_utils_is_subscribed_as_esource (esources, hosturl, username, fid->id)) @@ -3711,18 +3703,13 @@ ews_store_subscribe_folder_sync (CamelSubscribable *subscribable, } if (e_ews_folder_get_folder_type (folder) != E_EWS_FOLDER_TYPE_MAILBOX) { - CamelSession *session; CamelSettings *settings; CamelEwsSettings *ews_settings; - ESourceRegistry *registry = NULL; settings = camel_service_ref_settings (CAMEL_SERVICE (ews_store)); ews_settings = CAMEL_EWS_SETTINGS (settings); - session = camel_service_ref_session (CAMEL_SERVICE (ews_store)); - if (E_IS_MAIL_SESSION (session)) - registry = e_mail_session_get_registry (E_MAIL_SESSION (session)); - res = e_ews_folder_utils_add_as_esource (registry, + res = e_ews_folder_utils_add_as_esource (NULL, camel_ews_settings_get_hosturl (ews_settings), camel_network_settings_get_user (CAMEL_NETWORK_SETTINGS (ews_settings)), folder, @@ -3731,7 +3718,6 @@ ews_store_subscribe_folder_sync (CamelSubscribable *subscribable, cancellable, error); - g_object_unref (session); g_object_unref (settings); } @@ -3846,25 +3832,19 @@ ews_store_unsubscribe_folder_sync (CamelSubscribable *subscribable, } if (folder_type != E_EWS_FOLDER_TYPE_MAILBOX) { - CamelSession *session; CamelSettings *settings; CamelEwsSettings *ews_settings; - ESourceRegistry *registry = NULL; settings = camel_service_ref_settings (CAMEL_SERVICE (ews_store)); ews_settings = CAMEL_EWS_SETTINGS (settings); - session = camel_service_ref_session (CAMEL_SERVICE (ews_store)); - if (E_IS_MAIL_SESSION (session)) - registry = e_mail_session_get_registry (E_MAIL_SESSION (session)); - res = e_ews_folder_utils_remove_as_esource (registry, + res = e_ews_folder_utils_remove_as_esource ( camel_ews_settings_get_hosturl (ews_settings), camel_network_settings_get_user (CAMEL_NETWORK_SETTINGS (ews_settings)), fid, cancellable, error); - g_object_unref (session); g_object_unref (settings); } @@ -3932,16 +3912,12 @@ camel_ews_store_maybe_disconnect (CamelEwsStore *store, camel_service_disconnect_sync (service, FALSE, NULL, NULL); if (is_auth_failed) { - CamelSession *session; - ESourceRegistry *registry = NULL; + ESourceRegistry *registry; error->domain = CAMEL_SERVICE_ERROR; error->code = CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE; - session = camel_service_ref_session (service); - - if (E_IS_MAIL_SESSION (session)) - registry = e_mail_session_get_registry (E_MAIL_SESSION (session)); + registry = e_source_registry_new_sync (NULL, NULL); if (registry) { ESource *source, *collection = NULL; @@ -3957,9 +3933,8 @@ camel_ews_store_maybe_disconnect (CamelEwsStore *store, g_clear_object (&collection); g_clear_object (&source); + g_clear_object (®istry); } - - g_clear_object (&session); } } diff --git a/src/EWS/camel/camel-ews-transport.c b/src/EWS/camel/camel-ews-transport.c index 3c877f6d..478dbbd1 100644 --- a/src/EWS/camel/camel-ews-transport.c +++ b/src/EWS/camel/camel-ews-transport.c @@ -12,8 +12,6 @@ #include -#include - #include "common/camel-ews-settings.h" #include "common/e-ews-camel-common.h" @@ -31,12 +29,166 @@ struct _CamelEwsTransportPrivate G_DEFINE_TYPE_WITH_PRIVATE (CamelEwsTransport, camel_ews_transport, CAMEL_TYPE_TRANSPORT) +/* This is copy of e_mail_folder_uri_parse(), to not depend on the evolution code + in the library code (and to not bring gtk+ into random processes). */ +static gboolean +ews_transport_mail_folder_uri_parse (CamelSession *session, + const gchar *folder_uri, + CamelStore **out_store, + gchar **out_folder_name, + GError **error) +{ + CamelURL *url; + CamelService *service = NULL; + gchar *folder_name = NULL; + gboolean success = FALSE; + + g_return_val_if_fail (CAMEL_IS_SESSION (session), FALSE); + g_return_val_if_fail (folder_uri != NULL, FALSE); + + url = camel_url_new (folder_uri, error); + if (url == NULL) + return FALSE; + + /* Current URI Format: 'folder://' STORE_UID '/' FOLDER_PATH */ + if (g_strcmp0 (url->protocol, "folder") == 0) { + + if (url->host != NULL) { + gchar *uid; + + if (url->user == NULL || *url->user == '\0') + uid = g_strdup (url->host); + else + uid = g_strconcat ( + url->user, "@", url->host, NULL); + + service = camel_session_ref_service (session, uid); + g_free (uid); + } + + if (url->path != NULL && *url->path == '/') + folder_name = camel_url_decode_path (url->path + 1); + + /* This style was used to reference accounts by UID before + * CamelServices themselves had UIDs. Some examples are: + * + * Special cases: + * + * 'email://local@local/' FOLDER_PATH + * 'email://vfolder@local/' FOLDER_PATH + * + * General case: + * + * 'email://' ACCOUNT_UID '/' FOLDER_PATH + * + * Note: ACCOUNT_UID is now equivalent to STORE_UID, and + * the STORE_UIDs for the special cases are 'local' + * and 'vfolder'. + */ + } else if (g_strcmp0 (url->protocol, "email") == 0) { + gchar *uid = NULL; + + /* Handle the special cases. */ + if (g_strcmp0 (url->host, "local") == 0) { + if (g_strcmp0 (url->user, "local") == 0) + uid = g_strdup ("local"); + if (g_strcmp0 (url->user, "vfolder") == 0) + uid = g_strdup ("vfolder"); + } + + /* Handle the general case. */ + if (uid == NULL && url->host != NULL) { + if (url->user == NULL) + uid = g_strdup (url->host); + else + uid = g_strdup_printf ( + "%s@%s", url->user, url->host); + } + + if (uid != NULL) { + service = camel_session_ref_service (session, uid); + g_free (uid); + } + + if (url->path != NULL && *url->path == '/') + folder_name = camel_url_decode_path (url->path + 1); + + /* CamelFolderInfo URIs used to embed the store's URI, so the + * folder name is appended as either a path part or a fragment + * part, depending whether the store's URI used the path part. + * To determine which it is, you have to check the provider + * flags for CAMEL_URL_FRAGMENT_IS_PATH. */ + } else { + gboolean local_mbox_folder; + + /* In Evolution 2.x, the local mail store used mbox + * format. camel_session_ref_service_by_url() won't + * match "mbox:///.../mail/local" folder URIs, since + * the local mail store is now Maildir format. Test + * for this corner case and work around it. + * + * The folder path is kept in the fragment part of the + * URL which makes it easy to test the filesystem path. + * The suffix "evolution/mail/local" should match both + * the current XDG-compliant location and the old "dot + * folder" location (~/.evolution/mail/local). */ + local_mbox_folder = + (g_strcmp0 (url->protocol, "mbox") == 0) && + (url->path != NULL) && + g_str_has_suffix (url->path, "evolution/mail/local"); + + if (local_mbox_folder) { + service = camel_session_ref_service (session, "local"); + } else { + service = camel_session_ref_service_by_url ( + session, url, CAMEL_PROVIDER_STORE); + } + + if (CAMEL_IS_STORE (service)) { + CamelProvider *provider; + + provider = camel_service_get_provider (service); + + if (provider->url_flags & CAMEL_URL_FRAGMENT_IS_PATH) + folder_name = g_strdup (url->fragment); + else if (url->path != NULL && *url->path == '/') + folder_name = g_strdup (url->path + 1); + } + } + + if (CAMEL_IS_STORE (service) && folder_name != NULL) { + if (out_store != NULL) + *out_store = CAMEL_STORE (g_object_ref (service)); + + if (out_folder_name != NULL) { + *out_folder_name = folder_name; + folder_name = NULL; + } + + success = TRUE; + } else { + g_set_error ( + error, CAMEL_FOLDER_ERROR, + CAMEL_FOLDER_ERROR_INVALID, + _("Invalid folder URI ā€œ%sā€"), + folder_uri); + } + + if (service != NULL) + g_object_unref (service); + + g_free (folder_name); + + camel_url_free (url); + + return success; +} + static gboolean ews_transport_can_server_side_sent_folder (CamelService *service, EwsFolderId **folder_id, GCancellable *cancellable) { - CamelSession *session; ESourceRegistry *registry; ESource *sibling, *source = NULL; gboolean is_server_side = FALSE; @@ -44,21 +196,16 @@ ews_transport_can_server_side_sent_folder (CamelService *service, g_return_val_if_fail (CAMEL_IS_EWS_TRANSPORT (service), FALSE); g_return_val_if_fail (folder_id != NULL, FALSE); - session = camel_service_ref_session (service); - if (session && E_IS_MAIL_SESSION (session)) - registry = g_object_ref (e_mail_session_get_registry (E_MAIL_SESSION (session))); - else - registry = e_source_registry_new_sync (cancellable, NULL); - - if (!registry) { - g_clear_object (&session); + registry = e_source_registry_new_sync (cancellable, NULL); + if (!registry) return FALSE; - } sibling = e_source_registry_ref_source (registry, camel_service_get_uid (service)); if (sibling) { + CamelSession *session; GList *sources, *siter; + session = camel_service_ref_session (service); sources = e_source_registry_list_sources (registry, E_SOURCE_EXTENSION_MAIL_SUBMISSION); for (siter = sources; siter; siter = siter->next) { source = siter->data; @@ -85,7 +232,7 @@ ews_transport_can_server_side_sent_folder (CamelService *service, by the evolution itself. */ if (!e_source_mail_submission_get_replies_to_origin_folder (subm_extension) && e_source_mail_submission_get_sent_folder (subm_extension) && - e_mail_folder_uri_parse (session, + ews_transport_mail_folder_uri_parse (session, e_source_mail_submission_get_sent_folder (subm_extension), &store, &folder_name, NULL) & CAMEL_IS_EWS_STORE (store)) { CamelEwsStore *ews_store = CAMEL_EWS_STORE (store); @@ -112,10 +259,10 @@ ews_transport_can_server_side_sent_folder (CamelService *service, g_list_free_full (sources, g_object_unref); g_object_unref (sibling); + g_clear_object (&session); } g_object_unref (registry); - g_clear_object (&session); return is_server_side; } diff --git a/src/EWS/camel/camel-ews-utils.c b/src/EWS/camel/camel-ews-utils.c index 736efd2d..d7097c01 100644 --- a/src/EWS/camel/camel-ews-utils.c +++ b/src/EWS/camel/camel-ews-utils.c @@ -14,9 +14,6 @@ #include #include -#include -#include - #include "common/camel-ews-settings.h" #include "common/e-ews-camel-common.h" #include "common/e-ews-item-change.h" @@ -1467,23 +1464,12 @@ ESource * camel_ews_utils_ref_corresponding_source (CamelService *service, GCancellable *cancellable) { - ESourceRegistry *registry = NULL; - CamelSession *session; + ESourceRegistry *registry; ESource *source = NULL; g_return_val_if_fail (CAMEL_IS_SERVICE (service), NULL); - session = camel_service_ref_session (service); - if (E_IS_MAIL_SESSION (session)) { - registry = e_mail_session_get_registry (E_MAIL_SESSION (session)); - if (registry) - g_object_ref (registry); - } - - g_clear_object (&session); - - if (!registry) - registry = e_source_registry_new_sync (cancellable, NULL); + registry = e_source_registry_new_sync (cancellable, NULL); if (registry) { source = e_source_registry_ref_source (registry, camel_service_get_uid (service)); @@ -1566,7 +1552,7 @@ ews_utils_save_category_changes (GHashTable *old_categories, /* gchar *guid ~> C evo_labels = g_ptr_array_new_full (5, g_free); - settings = e_util_ref_settings ("org.gnome.evolution.mail"); + settings = g_settings_new ("org.gnome.evolution.mail"); strv = g_settings_get_strv (settings, "labels"); for (ii = 0; strv && strv[ii]; ii++) { diff --git a/src/EWS/common/CMakeLists.txt b/src/EWS/common/CMakeLists.txt index 40ba90f8..2622d248 100644 --- a/src/EWS/common/CMakeLists.txt +++ b/src/EWS/common/CMakeLists.txt @@ -54,7 +54,6 @@ target_compile_definitions(evolution-ews PRIVATE target_compile_options(evolution-ews PUBLIC ${CAMEL_CFLAGS} - ${EVOLUTION_CALENDAR_CFLAGS} ${LIBEBACKEND_CFLAGS} ${LIBECAL_CFLAGS} ${LIBEDATACAL_CFLAGS} @@ -70,7 +69,6 @@ target_include_directories(evolution-ews PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CAMEL_INCLUDE_DIRS} - ${EVOLUTION_CALENDAR_INCLUDE_DIRS} ${LIBEBACKEND_INCLUDE_DIRS} ${LIBECAL_INCLUDE_DIRS} ${LIBEDATACAL_INCLUDE_DIRS} @@ -80,7 +78,6 @@ target_include_directories(evolution-ews PUBLIC target_link_libraries(evolution-ews ${CAMEL_LDFLAGS} - ${EVOLUTION_CALENDAR_LDFLAGS} ${LIBEBACKEND_LDFLAGS} ${LIBECAL_LDFLAGS} ${LIBEDATACAL_LDFLAGS} diff --git a/src/EWS/common/e-ews-calendar-utils.c b/src/EWS/common/e-ews-calendar-utils.c index 82224b6a..f821dc3a 100644 --- a/src/EWS/common/e-ews-calendar-utils.c +++ b/src/EWS/common/e-ews-calendar-utils.c @@ -8,7 +8,6 @@ #include #include -#include #include "e-ews-message.h" #include "ews-errors.h" @@ -405,6 +404,26 @@ e_ews_cal_utils_prepare_free_busy_request (ESoapMessage *msg, return TRUE; } +/* This corresponds to calendar_config_get_icaltimezone(), to not depend on the evolution code + in the library code (and to not bring gtk+ into random processes). */ +static ICalTimezone * +ews_get_configured_icaltimezone (void) +{ + GSettings *settings; + gchar *location; + ICalTimezone *zone = NULL; + + settings = g_settings_new ("org.gnome.evolution.calendar"); + location = g_settings_get_string (settings, "timezone"); + if (location) { + zone = i_cal_timezone_get_builtin_timezone (location); + + g_free (location); + } + g_object_unref (settings); + return zone; +} + void e_ews_cal_utils_set_time (ESoapMessage *msg, const gchar *name, @@ -444,7 +463,7 @@ e_ews_cal_utils_set_time (ESoapMessage *msg, if (i_cal_time_is_date (tt)) { ICalTimezone *cfg_zone; - cfg_zone = calendar_config_get_icaltimezone (); + cfg_zone = ews_get_configured_icaltimezone (); local_tt = i_cal_time_new_from_timet_with_zone (i_cal_time_as_timet_with_zone (tt, cfg_zone), FALSE, i_cal_timezone_get_utc_timezone ()); tt = local_tt; } diff --git a/src/EWS/common/e-ews-folder.c b/src/EWS/common/e-ews-folder.c index aeaf3702..04e6a1a3 100644 --- a/src/EWS/common/e-ews-folder.c +++ b/src/EWS/common/e-ews-folder.c @@ -846,8 +846,7 @@ e_ews_folder_utils_add_as_esource (ESourceRegistry *pregistry, } gboolean -e_ews_folder_utils_remove_as_esource (ESourceRegistry *pregistry, - const gchar *master_hosturl, +e_ews_folder_utils_remove_as_esource (const gchar *master_hosturl, const gchar *master_username, const gchar *folder_id, GCancellable *cancellable, @@ -858,12 +857,9 @@ e_ews_folder_utils_remove_as_esource (ESourceRegistry *pregistry, GList *sources; gboolean res = TRUE; - registry = pregistry; - if (!registry) { - registry = e_source_registry_new_sync (cancellable, perror); - if (!registry) - return FALSE; - } + registry = e_source_registry_new_sync (cancellable, perror); + if (!registry) + return FALSE; sources = e_source_registry_list_sources (registry, NULL); source = e_ews_folder_utils_get_source_for_folder (sources, master_hosturl, master_username, folder_id); @@ -876,15 +872,13 @@ e_ews_folder_utils_remove_as_esource (ESourceRegistry *pregistry, } g_list_free_full (sources, g_object_unref); - if (!pregistry) - g_object_unref (registry); + g_object_unref (registry); return res; } GList * -e_ews_folder_utils_get_esources (ESourceRegistry *pregistry, - const gchar *master_hosturl, +e_ews_folder_utils_get_esources (const gchar *master_hosturl, const gchar *master_username, GCancellable *cancellable, GError **perror) @@ -892,19 +886,15 @@ e_ews_folder_utils_get_esources (ESourceRegistry *pregistry, ESourceRegistry *registry; GList *all_sources, *esources = NULL; - registry = pregistry; - if (!registry) { - registry = e_source_registry_new_sync (cancellable, perror); - if (!registry) - return NULL; - } + registry = e_source_registry_new_sync (cancellable, perror); + if (!registry) + return NULL; all_sources = e_source_registry_list_sources (registry, NULL); esources = e_ews_folder_utils_filter_sources_for_account (all_sources, master_hosturl, master_username); g_list_free_full (all_sources, g_object_unref); - if (!pregistry) - g_object_unref (registry); + g_object_unref (registry); return esources; } diff --git a/src/EWS/common/e-ews-folder.h b/src/EWS/common/e-ews-folder.h index dc1bf551..dbde4d26 100644 --- a/src/EWS/common/e-ews-folder.h +++ b/src/EWS/common/e-ews-folder.h @@ -108,14 +108,12 @@ gboolean e_ews_folder_utils_add_as_esource (ESourceRegistry *pregistry, gint color_seed, GCancellable *cancellable, GError **perror); -gboolean e_ews_folder_utils_remove_as_esource (ESourceRegistry *pregistry, - const gchar *master_hosturl, +gboolean e_ews_folder_utils_remove_as_esource (const gchar *master_hosturl, const gchar *master_username, const gchar *folder_id, GCancellable *cancellable, GError **perror); -GList * e_ews_folder_utils_get_esources (ESourceRegistry *pregistry, - const gchar *master_hosturl, +GList * e_ews_folder_utils_get_esources (const gchar *master_hosturl, const gchar *master_username, GCancellable *cancellable, GError **perror); diff --git a/src/Microsoft365/camel/CMakeLists.txt b/src/Microsoft365/camel/CMakeLists.txt index 928b837a..9cc88462 100644 --- a/src/Microsoft365/camel/CMakeLists.txt +++ b/src/Microsoft365/camel/CMakeLists.txt @@ -39,8 +39,6 @@ target_compile_definitions(camelmicrosoft365 PRIVATE target_compile_options(camelmicrosoft365 PUBLIC ${CAMEL_CFLAGS} - ${EVOLUTION_SHELL_CFLAGS} - ${EVOLUTION_MAIL_CFLAGS} ${LIBEDATASERVER_CFLAGS} ${LIBECAL_CFLAGS} ${SOUP_CFLAGS} @@ -53,8 +51,6 @@ target_include_directories(camelmicrosoft365 PUBLIC ${CMAKE_SOURCE_DIR}/src/Microsoft365 ${CMAKE_CURRENT_BINARY_DIR} ${CAMEL_INCLUDE_DIRS} - ${EVOLUTION_SHELL_INCLUDE_DIRS} - ${EVOLUTION_MAIL_INCLUDE_DIRS} ${LIBEDATASERVER_INCLUDE_DIRS} ${LIBECAL_INCLUDE_DIRS} ${SOUP_INCLUDE_DIRS} @@ -63,8 +59,6 @@ target_include_directories(camelmicrosoft365 PUBLIC target_link_libraries(camelmicrosoft365 ${DEPENDENCIES} ${CAMEL_LDFLAGS} - ${EVOLUTION_SHELL_LDFLAGS} - ${EVOLUTION_MAIL_LDFLAGS} ${LIBEDATASERVER_LDFLAGS} ${LIBECAL_LDFLAGS} ${SOUP_LDFLAGS} diff --git a/src/Microsoft365/camel/camel-m365-store.c b/src/Microsoft365/camel/camel-m365-store.c index a0f3f264..35376917 100644 --- a/src/Microsoft365/camel/camel-m365-store.c +++ b/src/Microsoft365/camel/camel-m365-store.c @@ -9,9 +9,6 @@ #include #include -#include -#include - #include "common/camel-m365-settings.h" #include "common/e-m365-connection.h" #include "camel-m365-folder.h" @@ -311,7 +308,7 @@ m365_store_save_category_changes (GHashTable *old_categories, /* gchar *id ~> Ca evo_labels = g_ptr_array_new_full (5, g_free); - settings = e_util_ref_settings ("org.gnome.evolution.mail"); + settings = g_settings_new ("org.gnome.evolution.mail"); strv = g_settings_get_strv (settings, "labels"); for (ii = 0; strv && strv[ii]; ii++) { @@ -1810,7 +1807,6 @@ camel_m365_store_maybe_disconnect (CamelM365Store *m365_store, return; if (g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) { - CamelSession *session; ESourceRegistry *registry = NULL; camel_service_disconnect_sync (service, FALSE, NULL, NULL); @@ -1818,10 +1814,7 @@ camel_m365_store_maybe_disconnect (CamelM365Store *m365_store, error->domain = CAMEL_SERVICE_ERROR; error->code = CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE; - session = camel_service_ref_session (service); - - if (E_IS_MAIL_SESSION (session)) - registry = e_mail_session_get_registry (E_MAIL_SESSION (session)); + registry = e_source_registry_new_sync (NULL, NULL); if (registry) { ESource *source, *collection = NULL; @@ -1839,7 +1832,7 @@ camel_m365_store_maybe_disconnect (CamelM365Store *m365_store, g_clear_object (&source); } - g_clear_object (&session); + g_clear_object (®istry); } } diff --git a/src/Microsoft365/camel/camel-m365-transport.c b/src/Microsoft365/camel/camel-m365-transport.c index fb12f412..d234f51f 100644 --- a/src/Microsoft365/camel/camel-m365-transport.c +++ b/src/Microsoft365/camel/camel-m365-transport.c @@ -10,8 +10,6 @@ #include -#include - #include "common/camel-m365-settings.h" #include "common/e-m365-connection.h" #include "camel-m365-store.h" @@ -30,34 +28,183 @@ struct _CamelM365TransportPrivate G_DEFINE_TYPE_WITH_PRIVATE (CamelM365Transport, camel_m365_transport, CAMEL_TYPE_TRANSPORT) +/* This is copy of e_mail_folder_uri_parse(), to not depend on the evolution code + in the library code (and to not bring gtk+ into random processes). */ +static gboolean +m365_transport_mail_folder_uri_parse (CamelSession *session, + const gchar *folder_uri, + CamelStore **out_store, + gchar **out_folder_name, + GError **error) +{ + CamelURL *url; + CamelService *service = NULL; + gchar *folder_name = NULL; + gboolean success = FALSE; + + g_return_val_if_fail (CAMEL_IS_SESSION (session), FALSE); + g_return_val_if_fail (folder_uri != NULL, FALSE); + + url = camel_url_new (folder_uri, error); + if (url == NULL) + return FALSE; + + /* Current URI Format: 'folder://' STORE_UID '/' FOLDER_PATH */ + if (g_strcmp0 (url->protocol, "folder") == 0) { + + if (url->host != NULL) { + gchar *uid; + + if (url->user == NULL || *url->user == '\0') + uid = g_strdup (url->host); + else + uid = g_strconcat ( + url->user, "@", url->host, NULL); + + service = camel_session_ref_service (session, uid); + g_free (uid); + } + + if (url->path != NULL && *url->path == '/') + folder_name = camel_url_decode_path (url->path + 1); + + /* This style was used to reference accounts by UID before + * CamelServices themselves had UIDs. Some examples are: + * + * Special cases: + * + * 'email://local@local/' FOLDER_PATH + * 'email://vfolder@local/' FOLDER_PATH + * + * General case: + * + * 'email://' ACCOUNT_UID '/' FOLDER_PATH + * + * Note: ACCOUNT_UID is now equivalent to STORE_UID, and + * the STORE_UIDs for the special cases are 'local' + * and 'vfolder'. + */ + } else if (g_strcmp0 (url->protocol, "email") == 0) { + gchar *uid = NULL; + + /* Handle the special cases. */ + if (g_strcmp0 (url->host, "local") == 0) { + if (g_strcmp0 (url->user, "local") == 0) + uid = g_strdup ("local"); + if (g_strcmp0 (url->user, "vfolder") == 0) + uid = g_strdup ("vfolder"); + } + + /* Handle the general case. */ + if (uid == NULL && url->host != NULL) { + if (url->user == NULL) + uid = g_strdup (url->host); + else + uid = g_strdup_printf ( + "%s@%s", url->user, url->host); + } + + if (uid != NULL) { + service = camel_session_ref_service (session, uid); + g_free (uid); + } + + if (url->path != NULL && *url->path == '/') + folder_name = camel_url_decode_path (url->path + 1); + + /* CamelFolderInfo URIs used to embed the store's URI, so the + * folder name is appended as either a path part or a fragment + * part, depending whether the store's URI used the path part. + * To determine which it is, you have to check the provider + * flags for CAMEL_URL_FRAGMENT_IS_PATH. */ + } else { + gboolean local_mbox_folder; + + /* In Evolution 2.x, the local mail store used mbox + * format. camel_session_ref_service_by_url() won't + * match "mbox:///.../mail/local" folder URIs, since + * the local mail store is now Maildir format. Test + * for this corner case and work around it. + * + * The folder path is kept in the fragment part of the + * URL which makes it easy to test the filesystem path. + * The suffix "evolution/mail/local" should match both + * the current XDG-compliant location and the old "dot + * folder" location (~/.evolution/mail/local). */ + local_mbox_folder = + (g_strcmp0 (url->protocol, "mbox") == 0) && + (url->path != NULL) && + g_str_has_suffix (url->path, "evolution/mail/local"); + + if (local_mbox_folder) { + service = camel_session_ref_service (session, "local"); + } else { + service = camel_session_ref_service_by_url ( + session, url, CAMEL_PROVIDER_STORE); + } + + if (CAMEL_IS_STORE (service)) { + CamelProvider *provider; + + provider = camel_service_get_provider (service); + + if (provider->url_flags & CAMEL_URL_FRAGMENT_IS_PATH) + folder_name = g_strdup (url->fragment); + else if (url->path != NULL && *url->path == '/') + folder_name = g_strdup (url->path + 1); + } + } + + if (CAMEL_IS_STORE (service) && folder_name != NULL) { + if (out_store != NULL) + *out_store = CAMEL_STORE (g_object_ref (service)); + + if (out_folder_name != NULL) { + *out_folder_name = folder_name; + folder_name = NULL; + } + + success = TRUE; + } else { + g_set_error ( + error, CAMEL_FOLDER_ERROR, + CAMEL_FOLDER_ERROR_INVALID, + _("Invalid folder URI ā€œ%sā€"), + folder_uri); + } + + if (service != NULL) + g_object_unref (service); + + g_free (folder_name); + + camel_url_free (url); + + return success; +} + static gboolean m365_transport_is_server_side_sent_folder (CamelService *service, GCancellable *cancellable) { - CamelSession *session; ESourceRegistry *registry; ESource *sibling, *source = NULL; gboolean is_server_side = FALSE; g_return_val_if_fail (CAMEL_IS_M365_TRANSPORT (service), FALSE); - session = camel_service_ref_session (service); - - if (session && E_IS_MAIL_SESSION (session)) - registry = g_object_ref (e_mail_session_get_registry (E_MAIL_SESSION (session))); - else - registry = e_source_registry_new_sync (cancellable, NULL); + registry = e_source_registry_new_sync (cancellable, NULL); - if (!registry) { - g_clear_object (&session); + if (!registry) return FALSE; - } sibling = e_source_registry_ref_source (registry, camel_service_get_uid (service)); if (sibling) { + CamelSession *session; GList *sources, *siter; + session = camel_service_ref_session (service); sources = e_source_registry_list_sources (registry, E_SOURCE_EXTENSION_MAIL_SUBMISSION); for (siter = sources; siter; siter = siter->next) { @@ -85,7 +232,7 @@ m365_transport_is_server_side_sent_folder (CamelService *service, by the evolution itself. */ if (!e_source_mail_submission_get_replies_to_origin_folder (subm_extension) && e_source_mail_submission_get_sent_folder (subm_extension) && - e_mail_folder_uri_parse (session, + m365_transport_mail_folder_uri_parse (session, e_source_mail_submission_get_sent_folder (subm_extension), &store, &folder_name, NULL) && CAMEL_IS_M365_STORE (store)) { CamelM365Store *m365_store = CAMEL_M365_STORE (store); @@ -114,10 +261,10 @@ m365_transport_is_server_side_sent_folder (CamelService *service, g_list_free_full (sources, g_object_unref); g_object_unref (sibling); + g_clear_object (&session); } g_object_unref (registry); - g_clear_object (&session); return is_server_side; } diff --git a/src/Microsoft365/camel/camel-m365-utils.c b/src/Microsoft365/camel/camel-m365-utils.c index 9d496693..ebe17e82 100644 --- a/src/Microsoft365/camel/camel-m365-utils.c +++ b/src/Microsoft365/camel/camel-m365-utils.c @@ -6,8 +6,6 @@ #include "evolution-ews-config.h" -#include - #include "camel-m365-utils.h" /* Unref with g_object_unref() when done with it */ @@ -15,23 +13,12 @@ static ESource * camel_m365_utils_ref_corresponding_source (CamelService *service, GCancellable *cancellable) { - ESourceRegistry *registry = NULL; - CamelSession *session; + ESourceRegistry *registry; ESource *source = NULL; g_return_val_if_fail (CAMEL_IS_SERVICE (service), NULL); - session = camel_service_ref_session (service); - if (E_IS_MAIL_SESSION (session)) { - registry = e_mail_session_get_registry (E_MAIL_SESSION (session)); - if (registry) - g_object_ref (registry); - } - - g_clear_object (&session); - - if (!registry) - registry = e_source_registry_new_sync (cancellable, NULL); + registry = e_source_registry_new_sync (cancellable, NULL); if (registry) { source = e_source_registry_ref_source (registry, camel_service_get_uid (service)); -- 2.35.1