| File: | src/calendar/backends/webdav-notes/e-cal-backend-webdav-notes.c |
| Warning: | line 1210, column 28 Null pointer passed to 1st parameter expecting 'nonnull' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* | ||||||
| 2 | * SPDX-FileCopyrightText: (C) 2020 Red Hat (www.redhat.com) | ||||||
| 3 | * SPDX-License-Identifier: LGPL-2.0-or-later | ||||||
| 4 | */ | ||||||
| 5 | |||||||
| 6 | #include "evolution-data-server-config.h" | ||||||
| 7 | |||||||
| 8 | #include <string.h> | ||||||
| 9 | #include <glib/gi18n-lib.h> | ||||||
| 10 | |||||||
| 11 | #include <libedataserver/libedataserver.h> | ||||||
| 12 | |||||||
| 13 | #include "e-cal-backend-webdav-notes.h" | ||||||
| 14 | |||||||
| 15 | #define E_WEBDAV_NOTES_X_ETAG"X-EVOLUTION-WEBDAV-NOTES-ETAG" "X-EVOLUTION-WEBDAV-NOTES-ETAG" | ||||||
| 16 | #define E_WEBDAV_NOTES_X_IS_MARKDOWN"X-EVOLUTION-IS-MARKDOWN" "X-EVOLUTION-IS-MARKDOWN" | ||||||
| 17 | |||||||
| 18 | #define EC_ERROR(_code)e_client_error_create (_code, ((void*)0)) e_client_error_create (_code, NULL((void*)0)) | ||||||
| 19 | #define ECC_ERROR(_code)e_cal_client_error_create (_code, ((void*)0)) e_cal_client_error_create (_code, NULL((void*)0)) | ||||||
| 20 | #define ECC_ERROR_EX(_code, _msg)e_cal_client_error_create (_code, _msg) e_cal_client_error_create (_code, _msg) | ||||||
| 21 | |||||||
| 22 | struct _ECalBackendWebDAVNotesPrivate { | ||||||
| 23 | /* The main WebDAV session */ | ||||||
| 24 | EWebDAVSession *webdav; | ||||||
| 25 | GUri *last_uri; | ||||||
| 26 | GMutex webdav_lock; | ||||||
| 27 | |||||||
| 28 | /* If already been connected, then the connect_sync() will relax server checks, | ||||||
| 29 | to avoid unnecessary requests towards the server. */ | ||||||
| 30 | gboolean been_connected; | ||||||
| 31 | |||||||
| 32 | gboolean etag_supported; | ||||||
| 33 | }; | ||||||
| 34 | |||||||
| 35 | G_DEFINE_TYPE_WITH_PRIVATE (ECalBackendWebDAVNotes, e_cal_backend_webdav_notes, E_TYPE_CAL_META_BACKEND)static void e_cal_backend_webdav_notes_init (ECalBackendWebDAVNotes *self); static void e_cal_backend_webdav_notes_class_init (ECalBackendWebDAVNotesClass *klass); static GType e_cal_backend_webdav_notes_get_type_once (void); static gpointer e_cal_backend_webdav_notes_parent_class = ((void*)0); static gint ECalBackendWebDAVNotes_private_offset ; static void e_cal_backend_webdav_notes_class_intern_init (gpointer klass) { e_cal_backend_webdav_notes_parent_class = g_type_class_peek_parent (klass); if (ECalBackendWebDAVNotes_private_offset != 0) g_type_class_adjust_private_offset (klass, &ECalBackendWebDAVNotes_private_offset); e_cal_backend_webdav_notes_class_init ((ECalBackendWebDAVNotesClass*) klass); } __attribute__ ((__unused__ )) static inline gpointer e_cal_backend_webdav_notes_get_instance_private (ECalBackendWebDAVNotes *self) { return (((gpointer) ((guint8 *) (self) + (glong) (ECalBackendWebDAVNotes_private_offset))) ); } GType e_cal_backend_webdav_notes_get_type (void) { static gsize static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); (void) (0 ? (gpointer) *( &static_g_define_type_id) : ((void*)0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id )); }))) { GType g_define_type_id = e_cal_backend_webdav_notes_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id) = (g_define_type_id) ) : (void) 0; g_once_init_leave ((&static_g_define_type_id ), (gsize) (g_define_type_id)); })); } return static_g_define_type_id ; } __attribute__ ((__noinline__)) static GType e_cal_backend_webdav_notes_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple ((e_cal_meta_backend_get_type ()), g_intern_static_string ("ECalBackendWebDAVNotes" ), sizeof (ECalBackendWebDAVNotesClass), (GClassInitFunc)(void (*)(void)) e_cal_backend_webdav_notes_class_intern_init, sizeof (ECalBackendWebDAVNotes), (GInstanceInitFunc)(void (*)(void) ) e_cal_backend_webdav_notes_init, (GTypeFlags) 0); { {{ ECalBackendWebDAVNotes_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (ECalBackendWebDAVNotesPrivate )); };} } return g_define_type_id; } | ||||||
| 36 | |||||||
| 37 | static gboolean | ||||||
| 38 | ecb_webdav_notes_has_supported_extension (const gchar *filename, | ||||||
| 39 | gint *out_ext_len, | ||||||
| 40 | const gchar **out_ext, | ||||||
| 41 | const gchar **out_ext_num_suffix, | ||||||
| 42 | const gchar **out_content_type) | ||||||
| 43 | { | ||||||
| 44 | if (!filename || !*filename) | ||||||
| 45 | return FALSE(0); | ||||||
| 46 | |||||||
| 47 | if (g_str_has_suffix (filename, ".txt")(__builtin_constant_p (".txt")? __extension__ ({ const char * const __str = (filename); const char * const __suffix = (".txt" ); gboolean __result = (0); if (__builtin_expect (__extension__ ({ int _g_boolean_var_64 = 0; if (__str == ((void*)0) || __suffix == ((void*)0)) _g_boolean_var_64 = 1; _g_boolean_var_64; }), 0)) __result = (g_str_has_suffix) (__str, __suffix); else { const size_t __str_len = strlen (((__str) + !(__str))); const size_t __suffix_len = strlen (((__suffix) + !(__suffix))); if (__str_len >= __suffix_len) __result = memcmp (__str + __str_len - __suffix_len , ((__suffix) + !(__suffix)), __suffix_len) == 0; } __result; }) : (g_str_has_suffix) (filename, ".txt") )) { | ||||||
| 48 | if (out_ext_len) | ||||||
| 49 | *out_ext_len = 4; | ||||||
| 50 | if (out_ext) | ||||||
| 51 | *out_ext = ".txt"; | ||||||
| 52 | if (out_ext_num_suffix) | ||||||
| 53 | *out_ext_num_suffix = ").txt"; | ||||||
| 54 | if (out_content_type) | ||||||
| 55 | *out_content_type = "text/plain; charset=\"utf-8\""; | ||||||
| 56 | |||||||
| 57 | return TRUE(!(0)); | ||||||
| 58 | } | ||||||
| 59 | |||||||
| 60 | if (g_str_has_suffix (filename, ".md")(__builtin_constant_p (".md")? __extension__ ({ const char * const __str = (filename); const char * const __suffix = (".md"); gboolean __result = (0); if (__builtin_expect (__extension__ ({ int _g_boolean_var_65 = 0; if (__str == ((void*)0) || __suffix == ((void*)0)) _g_boolean_var_65 = 1; _g_boolean_var_65; }), 0)) __result = (g_str_has_suffix ) (__str, __suffix); else { const size_t __str_len = strlen ( ((__str) + !(__str))); const size_t __suffix_len = strlen ((( __suffix) + !(__suffix))); if (__str_len >= __suffix_len) __result = memcmp (__str + __str_len - __suffix_len, ((__suffix) + !( __suffix)), __suffix_len) == 0; } __result; }) : (g_str_has_suffix ) (filename, ".md") )) { | ||||||
| 61 | if (out_ext_len) | ||||||
| 62 | *out_ext_len = 3; | ||||||
| 63 | if (out_ext) | ||||||
| 64 | *out_ext = ".md"; | ||||||
| 65 | if (out_ext_num_suffix) | ||||||
| 66 | *out_ext_num_suffix = ").md"; | ||||||
| 67 | if (out_content_type) | ||||||
| 68 | *out_content_type = "text/markdown; charset=\"utf-8\""; | ||||||
| 69 | |||||||
| 70 | return TRUE(!(0)); | ||||||
| 71 | } | ||||||
| 72 | |||||||
| 73 | return FALSE(0); | ||||||
| 74 | } | ||||||
| 75 | |||||||
| 76 | static EWebDAVSession * | ||||||
| 77 | ecb_webdav_notes_ref_session (ECalBackendWebDAVNotes *cbnotes) | ||||||
| 78 | { | ||||||
| 79 | EWebDAVSession *webdav; | ||||||
| 80 | |||||||
| 81 | g_return_val_if_fail (E_IS_CAL_BACKEND_WEBDAV_NOTES (cbnotes), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_66 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((cbnotes)); GType __t = ((e_cal_backend_webdav_notes_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_66 = 1; _g_boolean_var_66; }), 1) )) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "E_IS_CAL_BACKEND_WEBDAV_NOTES (cbnotes)" ); return (((void*)0)); } } while (0); | ||||||
| 82 | |||||||
| 83 | g_mutex_lock (&cbnotes->priv->webdav_lock); | ||||||
| 84 | if (cbnotes->priv->webdav) | ||||||
| 85 | webdav = g_object_ref (cbnotes->priv->webdav)((__typeof__ (cbnotes->priv->webdav)) (g_object_ref) (cbnotes ->priv->webdav)); | ||||||
| 86 | else | ||||||
| 87 | webdav = NULL((void*)0); | ||||||
| 88 | g_mutex_unlock (&cbnotes->priv->webdav_lock); | ||||||
| 89 | |||||||
| 90 | return webdav; | ||||||
| 91 | } | ||||||
| 92 | |||||||
| 93 | static gboolean | ||||||
| 94 | ecb_webdav_notes_connect_sync (ECalMetaBackend *meta_backend, | ||||||
| 95 | const ENamedParameters *credentials, | ||||||
| 96 | ESourceAuthenticationResult *out_auth_result, | ||||||
| 97 | gchar **out_certificate_pem, | ||||||
| 98 | GTlsCertificateFlags *out_certificate_errors, | ||||||
| 99 | GCancellable *cancellable, | ||||||
| 100 | GError **error) | ||||||
| 101 | { | ||||||
| 102 | ECalBackendWebDAVNotes *cbnotes; | ||||||
| 103 | EWebDAVSession *webdav; | ||||||
| 104 | GHashTable *capabilities = NULL((void*)0), *allows = NULL((void*)0); | ||||||
| 105 | ESource *source; | ||||||
| 106 | gboolean success, is_writable = FALSE(0), uri_changed = FALSE(0); | ||||||
| 107 | GError *local_error = NULL((void*)0); | ||||||
| 108 | |||||||
| 109 | g_return_val_if_fail (E_IS_CAL_BACKEND_WEBDAV_NOTES (meta_backend), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_67 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((meta_backend)); GType __t = ((e_cal_backend_webdav_notes_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_67 = 1; _g_boolean_var_67; }), 1) )) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "E_IS_CAL_BACKEND_WEBDAV_NOTES (meta_backend)" ); return ((0)); } } while (0); | ||||||
| 110 | g_return_val_if_fail (out_auth_result != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_68 = 0; if (out_auth_result != ((void*)0)) _g_boolean_var_68 = 1 ; _g_boolean_var_68; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes", ((const char*) (__func__)), "out_auth_result != NULL" ); return ((0)); } } while (0); | ||||||
| 111 | |||||||
| 112 | *out_auth_result = E_SOURCE_AUTHENTICATION_ACCEPTED; | ||||||
| 113 | |||||||
| 114 | cbnotes = E_CAL_BACKEND_WEBDAV_NOTES (meta_backend)((((ECalBackendWebDAVNotes*) (void *) ((meta_backend))))); | ||||||
| 115 | source = e_backend_get_source (E_BACKEND (meta_backend)((((EBackend*) (void *) ((meta_backend)))))); | ||||||
| 116 | |||||||
| 117 | g_mutex_lock (&cbnotes->priv->webdav_lock); | ||||||
| 118 | if (cbnotes->priv->webdav) { | ||||||
| 119 | g_mutex_unlock (&cbnotes->priv->webdav_lock); | ||||||
| 120 | return TRUE(!(0)); | ||||||
| 121 | } | ||||||
| 122 | |||||||
| 123 | if (e_source_has_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND"WebDAV Backend")) { | ||||||
| 124 | ESourceWebdav *webdav_extension; | ||||||
| 125 | GUri *current_uri; | ||||||
| 126 | |||||||
| 127 | webdav_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND"WebDAV Backend"); | ||||||
| 128 | current_uri = e_source_webdav_dup_uri (webdav_extension); | ||||||
| 129 | |||||||
| 130 | #define uri_str_equal(_func) (g_strcmp0 (_func (cbnotes->priv->last_uri), _func (current_uri)) == 0) | ||||||
| 131 | |||||||
| 132 | uri_changed = cbnotes->priv->last_uri && current_uri && ( | ||||||
| 133 | g_uri_get_port (cbnotes->priv->last_uri) != g_uri_get_port (current_uri) || | ||||||
| 134 | !uri_str_equal (g_uri_get_auth_params) || | ||||||
| 135 | !uri_str_equal (g_uri_get_host) || | ||||||
| 136 | !uri_str_equal (g_uri_get_path) || | ||||||
| 137 | !uri_str_equal (g_uri_get_query) || | ||||||
| 138 | !uri_str_equal (g_uri_get_fragment) || | ||||||
| 139 | !uri_str_equal (g_uri_get_scheme) || | ||||||
| 140 | !uri_str_equal (g_uri_get_userinfo) || | ||||||
| 141 | !uri_str_equal (g_uri_get_user) || | ||||||
| 142 | !uri_str_equal (g_uri_get_password)); | ||||||
| 143 | |||||||
| 144 | #undef uri_str_equal | ||||||
| 145 | |||||||
| 146 | if (!cbnotes->priv->last_uri || uri_changed) { | ||||||
| 147 | g_clear_pointer (&cbnotes->priv->last_uri, g_uri_unref)do { _Static_assert (sizeof *(&cbnotes->priv->last_uri ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ ((&cbnotes->priv->last_uri)) _pp = (&cbnotes-> priv->last_uri); __typeof__ (*(&cbnotes->priv->last_uri )) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_uri_unref) (_ptr ); } while (0); | ||||||
| 148 | cbnotes->priv->last_uri = current_uri; | ||||||
| 149 | } else if (current_uri) { | ||||||
| 150 | g_uri_unref (current_uri); | ||||||
| 151 | } | ||||||
| 152 | } | ||||||
| 153 | g_mutex_unlock (&cbnotes->priv->webdav_lock); | ||||||
| 154 | |||||||
| 155 | if (uri_changed) | ||||||
| 156 | e_cal_meta_backend_set_sync_tag (meta_backend, NULL((void*)0)); | ||||||
| 157 | |||||||
| 158 | webdav = e_webdav_session_new (source); | ||||||
| 159 | |||||||
| 160 | e_soup_session_setup_logging (E_SOUP_SESSION (webdav)((((ESoupSession*) (void *) ((webdav))))), g_getenv ("WEBDAV_NOTES_DEBUG")); | ||||||
| 161 | |||||||
| 162 | e_binding_bind_property ( | ||||||
| 163 | cbnotes, "proxy-resolver", | ||||||
| 164 | webdav, "proxy-resolver", | ||||||
| 165 | G_BINDING_SYNC_CREATE); | ||||||
| 166 | |||||||
| 167 | e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTING); | ||||||
| 168 | |||||||
| 169 | e_soup_session_set_credentials (E_SOUP_SESSION (webdav)((((ESoupSession*) (void *) ((webdav))))), credentials); | ||||||
| 170 | |||||||
| 171 | if (cbnotes->priv->been_connected) { | ||||||
| 172 | g_mutex_lock (&cbnotes->priv->webdav_lock); | ||||||
| 173 | cbnotes->priv->webdav = webdav; | ||||||
| 174 | g_mutex_unlock (&cbnotes->priv->webdav_lock); | ||||||
| 175 | |||||||
| 176 | return TRUE(!(0)); | ||||||
| 177 | } | ||||||
| 178 | |||||||
| 179 | /* This is just to make it similar to the CalDAV backend. */ | ||||||
| 180 | cbnotes->priv->etag_supported = TRUE(!(0)); | ||||||
| 181 | |||||||
| 182 | success = e_webdav_session_options_sync (webdav, NULL((void*)0), | ||||||
| 183 | &capabilities, &allows, cancellable, &local_error); | ||||||
| 184 | |||||||
| 185 | if (success && !g_cancellable_is_cancelled (cancellable)) { | ||||||
| 186 | GSList *privileges = NULL((void*)0), *link; | ||||||
| 187 | |||||||
| 188 | /* Ignore any errors here */ | ||||||
| 189 | if (e_webdav_session_get_current_user_privilege_set_full_sync (webdav, NULL((void*)0), &privileges, | ||||||
| 190 | capabilities ? NULL((void*)0) : &capabilities, | ||||||
| 191 | allows ? NULL((void*)0) : &allows, cancellable, NULL((void*)0))) { | ||||||
| 192 | for (link = privileges; link && !is_writable; link = g_slist_next (link)((link) ? (((GSList *)(link))->next) : ((void*)0))) { | ||||||
| 193 | EWebDAVPrivilege *privilege = link->data; | ||||||
| 194 | |||||||
| 195 | if (privilege) { | ||||||
| 196 | is_writable = | ||||||
| 197 | privilege->hint == E_WEBDAV_PRIVILEGE_HINT_WRITE || | ||||||
| 198 | privilege->hint == E_WEBDAV_PRIVILEGE_HINT_WRITE_CONTENT || | ||||||
| 199 | privilege->hint == E_WEBDAV_PRIVILEGE_HINT_ALL; | ||||||
| 200 | } | ||||||
| 201 | } | ||||||
| 202 | |||||||
| 203 | g_slist_free_full (privileges, e_webdav_privilege_free); | ||||||
| 204 | } else { | ||||||
| 205 | is_writable = allows && ( | ||||||
| 206 | g_hash_table_contains (allows, "PUT") || | ||||||
| 207 | g_hash_table_contains (allows, "POST") || | ||||||
| 208 | g_hash_table_contains (allows, "DELETE")); | ||||||
| 209 | } | ||||||
| 210 | } | ||||||
| 211 | |||||||
| 212 | if (success) { | ||||||
| 213 | e_cal_backend_set_writable (E_CAL_BACKEND (cbnotes)((((ECalBackend*) (void *) ((cbnotes))))), is_writable); | ||||||
| 214 | e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED); | ||||||
| 215 | } | ||||||
| 216 | |||||||
| 217 | if (success) { | ||||||
| 218 | gchar *ctag = NULL((void*)0); | ||||||
| 219 | |||||||
| 220 | /* Some servers, notably Google, allow OPTIONS when not | ||||||
| 221 | authorized (aka without credentials), thus try something | ||||||
| 222 | more aggressive, just in case. | ||||||
| 223 | |||||||
| 224 | The 'getctag' extension is not required, thus check | ||||||
| 225 | for unauthorized error only. */ | ||||||
| 226 | if (!e_webdav_session_getctag_sync (webdav, NULL((void*)0), &ctag, cancellable, &local_error) && | ||||||
| 227 | g_error_matches (local_error, E_SOUP_SESSION_ERROR(e_soup_session_error_quark()), SOUP_STATUS_UNAUTHORIZED)) { | ||||||
| 228 | success = FALSE(0); | ||||||
| 229 | } else { | ||||||
| 230 | g_clear_error (&local_error); | ||||||
| 231 | } | ||||||
| 232 | |||||||
| 233 | g_free (ctag); | ||||||
| 234 | } | ||||||
| 235 | |||||||
| 236 | if (success) { | ||||||
| 237 | e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED); | ||||||
| 238 | } else { | ||||||
| 239 | e_soup_session_handle_authentication_failure (E_SOUP_SESSION (webdav)((((ESoupSession*) (void *) ((webdav))))), credentials, | ||||||
| 240 | local_error, out_auth_result, out_certificate_pem, out_certificate_errors, error); | ||||||
| 241 | } | ||||||
| 242 | |||||||
| 243 | g_clear_error (&local_error); | ||||||
| 244 | |||||||
| 245 | if (capabilities) | ||||||
| 246 | g_hash_table_destroy (capabilities); | ||||||
| 247 | if (allows) | ||||||
| 248 | g_hash_table_destroy (allows); | ||||||
| 249 | |||||||
| 250 | if (success && !g_cancellable_set_error_if_cancelled (cancellable, error)) { | ||||||
| 251 | g_mutex_lock (&cbnotes->priv->webdav_lock); | ||||||
| 252 | cbnotes->priv->webdav = webdav; | ||||||
| 253 | g_mutex_unlock (&cbnotes->priv->webdav_lock); | ||||||
| 254 | cbnotes->priv->been_connected = TRUE(!(0)); | ||||||
| 255 | } else { | ||||||
| 256 | if (success) { | ||||||
| 257 | e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_DISCONNECTED); | ||||||
| 258 | success = FALSE(0); | ||||||
| 259 | } | ||||||
| 260 | |||||||
| 261 | g_clear_object (&webdav)do { _Static_assert (sizeof *((&webdav)) == sizeof (gpointer ), "Expression evaluates to false"); __typeof__ (((&webdav ))) _pp = ((&webdav)); __typeof__ (*((&webdav))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr) ; } while (0); | ||||||
| 262 | } | ||||||
| 263 | |||||||
| 264 | return success; | ||||||
| 265 | } | ||||||
| 266 | |||||||
| 267 | static gboolean | ||||||
| 268 | ecb_webdav_notes_disconnect_sync (ECalMetaBackend *meta_backend, | ||||||
| 269 | GCancellable *cancellable, | ||||||
| 270 | GError **error) | ||||||
| 271 | { | ||||||
| 272 | ECalBackendWebDAVNotes *cbnotes; | ||||||
| 273 | ESource *source; | ||||||
| 274 | |||||||
| 275 | g_return_val_if_fail (E_IS_CAL_BACKEND_WEBDAV_NOTES (meta_backend), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_69 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((meta_backend)); GType __t = ((e_cal_backend_webdav_notes_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_69 = 1; _g_boolean_var_69; }), 1) )) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "E_IS_CAL_BACKEND_WEBDAV_NOTES (meta_backend)" ); return ((0)); } } while (0); | ||||||
| 276 | |||||||
| 277 | cbnotes = E_CAL_BACKEND_WEBDAV_NOTES (meta_backend)((((ECalBackendWebDAVNotes*) (void *) ((meta_backend))))); | ||||||
| 278 | |||||||
| 279 | g_mutex_lock (&cbnotes->priv->webdav_lock); | ||||||
| 280 | if (cbnotes->priv->webdav) | ||||||
| 281 | soup_session_abort (SOUP_SESSION (cbnotes->priv->webdav)); | ||||||
| 282 | |||||||
| 283 | g_clear_object (&cbnotes->priv->webdav)do { _Static_assert (sizeof *((&cbnotes->priv->webdav )) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (((&cbnotes->priv->webdav))) _pp = ((&cbnotes-> priv->webdav)); __typeof__ (*((&cbnotes->priv->webdav ))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref ) (_ptr); } while (0); | ||||||
| 284 | g_mutex_unlock (&cbnotes->priv->webdav_lock); | ||||||
| 285 | |||||||
| 286 | source = e_backend_get_source (E_BACKEND (meta_backend)((((EBackend*) (void *) ((meta_backend)))))); | ||||||
| 287 | e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_DISCONNECTED); | ||||||
| 288 | |||||||
| 289 | return TRUE(!(0)); | ||||||
| 290 | } | ||||||
| 291 | |||||||
| 292 | typedef struct _WebDAVNotesChangesData { | ||||||
| 293 | GSList **out_modified_objects; | ||||||
| 294 | GSList **out_removed_objects; | ||||||
| 295 | GHashTable *known_items; /* gchar *href ~> ECalMetaBackendInfo * */ | ||||||
| 296 | } WebDAVNotesChangesData; | ||||||
| 297 | |||||||
| 298 | static gboolean | ||||||
| 299 | ecb_webdav_notes_search_changes_cb (ECalCache *cal_cache, | ||||||
| 300 | const gchar *uid, | ||||||
| 301 | const gchar *rid, | ||||||
| 302 | const gchar *revision, | ||||||
| 303 | const gchar *object, | ||||||
| 304 | const gchar *extra, | ||||||
| 305 | guint32 custom_flags, | ||||||
| 306 | EOfflineState offline_state, | ||||||
| 307 | gpointer user_data) | ||||||
| 308 | { | ||||||
| 309 | WebDAVNotesChangesData *ccd = user_data; | ||||||
| 310 | |||||||
| 311 | g_return_val_if_fail (ccd != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_70 = 0; if (ccd != ((void*)0)) _g_boolean_var_70 = 1; _g_boolean_var_70 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "ccd != NULL"); return ((0)); } } while (0); | ||||||
| 312 | g_return_val_if_fail (uid != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_71 = 0; if (uid != ((void*)0)) _g_boolean_var_71 = 1; _g_boolean_var_71 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "uid != NULL"); return ((0)); } } while (0); | ||||||
| 313 | |||||||
| 314 | /* The 'extra' can be NULL for added components in offline mode */ | ||||||
| 315 | if (((extra && *extra) || offline_state != E_OFFLINE_STATE_LOCALLY_CREATED) && (!rid || !*rid)) { | ||||||
| 316 | ECalMetaBackendInfo *nfo; | ||||||
| 317 | |||||||
| 318 | nfo = (extra && *extra) ? g_hash_table_lookup (ccd->known_items, extra) : NULL((void*)0); | ||||||
| 319 | if (nfo) { | ||||||
| 320 | if (g_strcmp0 (revision, nfo->revision) == 0) { | ||||||
| 321 | g_hash_table_remove (ccd->known_items, extra); | ||||||
| 322 | } else { | ||||||
| 323 | if (!nfo->uid || !*(nfo->uid)) { | ||||||
| 324 | g_free (nfo->uid); | ||||||
| 325 | nfo->uid = g_strdup (uid)g_strdup_inline (uid); | ||||||
| 326 | } | ||||||
| 327 | |||||||
| 328 | *(ccd->out_modified_objects) = g_slist_prepend (*(ccd->out_modified_objects), | ||||||
| 329 | e_cal_meta_backend_info_copy (nfo)); | ||||||
| 330 | |||||||
| 331 | g_hash_table_remove (ccd->known_items, extra); | ||||||
| 332 | } | ||||||
| 333 | } else { | ||||||
| 334 | *(ccd->out_removed_objects) = g_slist_prepend (*(ccd->out_removed_objects), | ||||||
| 335 | e_cal_meta_backend_info_new (uid, revision, object, extra)); | ||||||
| 336 | } | ||||||
| 337 | } | ||||||
| 338 | |||||||
| 339 | return TRUE(!(0)); | ||||||
| 340 | } | ||||||
| 341 | |||||||
| 342 | static void | ||||||
| 343 | ecb_webdav_notes_check_credentials_error (ECalBackendWebDAVNotes *cbnotes, | ||||||
| 344 | EWebDAVSession *webdav, | ||||||
| 345 | GError *op_error) | ||||||
| 346 | { | ||||||
| 347 | g_return_if_fail (E_IS_CAL_BACKEND_WEBDAV_NOTES (cbnotes))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_72 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((cbnotes)); GType __t = ((e_cal_backend_webdav_notes_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_72 = 1; _g_boolean_var_72; }), 1) )) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "E_IS_CAL_BACKEND_WEBDAV_NOTES (cbnotes)" ); return; } } while (0); | ||||||
| 348 | |||||||
| 349 | if (g_error_matches (op_error, G_TLS_ERROR(g_tls_error_quark ()), G_TLS_ERROR_BAD_CERTIFICATE) && webdav) { | ||||||
| 350 | op_error->domain = E_CLIENT_ERRORe_client_error_quark (); | ||||||
| 351 | op_error->code = E_CLIENT_ERROR_TLS_NOT_AVAILABLE; | ||||||
| 352 | } else if (g_error_matches (op_error, E_SOUP_SESSION_ERROR(e_soup_session_error_quark()), SOUP_STATUS_UNAUTHORIZED) || | ||||||
| 353 | g_error_matches (op_error, E_SOUP_SESSION_ERROR(e_soup_session_error_quark()), SOUP_STATUS_FORBIDDEN)) { | ||||||
| 354 | gboolean was_forbidden = g_error_matches (op_error, E_SOUP_SESSION_ERROR(e_soup_session_error_quark()), SOUP_STATUS_FORBIDDEN); | ||||||
| 355 | |||||||
| 356 | op_error->domain = E_CLIENT_ERRORe_client_error_quark (); | ||||||
| 357 | op_error->code = E_CLIENT_ERROR_AUTHENTICATION_REQUIRED; | ||||||
| 358 | |||||||
| 359 | cbnotes->priv->been_connected = FALSE(0); | ||||||
| 360 | |||||||
| 361 | if (webdav) { | ||||||
| 362 | ENamedParameters *credentials; | ||||||
| 363 | gboolean empty_credentials; | ||||||
| 364 | |||||||
| 365 | credentials = e_soup_session_dup_credentials (E_SOUP_SESSION (webdav)((((ESoupSession*) (void *) ((webdav)))))); | ||||||
| 366 | empty_credentials = !credentials || !e_named_parameters_count (credentials); | ||||||
| 367 | e_named_parameters_free (credentials); | ||||||
| 368 | |||||||
| 369 | if (!empty_credentials) { | ||||||
| 370 | if (was_forbidden) { | ||||||
| 371 | if (e_webdav_session_get_last_dav_error_is_permission (webdav)) { | ||||||
| 372 | op_error->code = E_CLIENT_ERROR_PERMISSION_DENIED; | ||||||
| 373 | g_free (op_error->message); | ||||||
| 374 | op_error->message = g_strdup (e_client_error_to_string (op_error->code))g_strdup_inline (e_client_error_to_string (op_error->code) ); | ||||||
| 375 | } else { | ||||||
| 376 | /* To avoid credentials prompt */ | ||||||
| 377 | op_error->code = E_CLIENT_ERROR_OTHER_ERROR; | ||||||
| 378 | } | ||||||
| 379 | } else { | ||||||
| 380 | op_error->code = E_CLIENT_ERROR_AUTHENTICATION_FAILED; | ||||||
| 381 | } | ||||||
| 382 | } | ||||||
| 383 | } | ||||||
| 384 | } | ||||||
| 385 | } | ||||||
| 386 | |||||||
| 387 | static gboolean | ||||||
| 388 | ecb_webdav_notes_getetag_cb (EWebDAVSession *webdav, | ||||||
| 389 | xmlNodePtr prop_node, | ||||||
| 390 | const GUri *request_uri, | ||||||
| 391 | const gchar *href, | ||||||
| 392 | guint status_code, | ||||||
| 393 | gpointer user_data) | ||||||
| 394 | { | ||||||
| 395 | if (status_code == SOUP_STATUS_OK) { | ||||||
| 396 | gchar **out_etag = user_data; | ||||||
| 397 | const xmlChar *etag; | ||||||
| 398 | |||||||
| 399 | g_return_val_if_fail (out_etag != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_73 = 0; if (out_etag != ((void*)0)) _g_boolean_var_73 = 1; _g_boolean_var_73 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "out_etag != NULL"); return ((0 )); } } while (0); | ||||||
| 400 | |||||||
| 401 | etag = e_xml_find_child_and_get_text (prop_node, E_WEBDAV_NS_DAV"DAV:", "getetag"); | ||||||
| 402 | |||||||
| 403 | if (etag && *etag) | ||||||
| 404 | *out_etag = e_webdav_session_util_maybe_dequote (g_strdup ((const gchar *) etag)g_strdup_inline ((const gchar *) etag)); | ||||||
| 405 | } | ||||||
| 406 | |||||||
| 407 | return FALSE(0); | ||||||
| 408 | } | ||||||
| 409 | |||||||
| 410 | static gboolean | ||||||
| 411 | ecb_webdav_notes_getetag_sync (EWebDAVSession *webdav, | ||||||
| 412 | const gchar *uri, | ||||||
| 413 | gchar **out_etag, | ||||||
| 414 | GCancellable *cancellable, | ||||||
| 415 | GError **error) | ||||||
| 416 | { | ||||||
| 417 | EXmlDocument *xml; | ||||||
| 418 | gboolean success; | ||||||
| 419 | |||||||
| 420 | g_return_val_if_fail (E_IS_WEBDAV_SESSION (webdav), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_74 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((webdav)); GType __t = ((e_webdav_session_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_74 = 1; _g_boolean_var_74; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes", ((const char*) (__func__)), "E_IS_WEBDAV_SESSION (webdav)" ); return ((0)); } } while (0); | ||||||
| 421 | g_return_val_if_fail (out_etag != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_75 = 0; if (out_etag != ((void*)0)) _g_boolean_var_75 = 1; _g_boolean_var_75 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "out_etag != NULL"); return ((0 )); } } while (0); | ||||||
| 422 | |||||||
| 423 | *out_etag = NULL((void*)0); | ||||||
| 424 | |||||||
| 425 | xml = e_xml_document_new (E_WEBDAV_NS_DAV"DAV:", "propfind"); | ||||||
| 426 | g_return_val_if_fail (xml != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_76 = 0; if (xml != ((void*)0)) _g_boolean_var_76 = 1; _g_boolean_var_76 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "xml != NULL"); return ((0)); } } while (0); | ||||||
| 427 | |||||||
| 428 | e_xml_document_start_element (xml, NULL((void*)0), "prop"); | ||||||
| 429 | e_xml_document_add_empty_element (xml, NULL((void*)0), "getetag"); | ||||||
| 430 | e_xml_document_end_element (xml); /* prop */ | ||||||
| 431 | |||||||
| 432 | success = e_webdav_session_propfind_sync (webdav, uri, E_WEBDAV_DEPTH_THIS"0", xml, | ||||||
| 433 | ecb_webdav_notes_getetag_cb, out_etag, cancellable, error); | ||||||
| 434 | |||||||
| 435 | g_object_unref (xml); | ||||||
| 436 | |||||||
| 437 | return success && *out_etag != NULL((void*)0); | ||||||
| 438 | } | ||||||
| 439 | |||||||
| 440 | static ICalComponent * | ||||||
| 441 | ecb_webdav_notes_new_icomp (glong creation_date, | ||||||
| 442 | glong last_modified, | ||||||
| 443 | const gchar *uid, | ||||||
| 444 | const gchar *revision, | ||||||
| 445 | const gchar *summary, | ||||||
| 446 | const gchar *description) | ||||||
| 447 | { | ||||||
| 448 | ICalComponent *icomp; | ||||||
| 449 | ICalTime *itt; | ||||||
| 450 | glong tt; | ||||||
| 451 | gint ext_len = 0; | ||||||
| 452 | |||||||
| 453 | icomp = i_cal_component_new_vjournal (); | ||||||
| 454 | |||||||
| 455 | if (creation_date > 0) | ||||||
| 456 | tt = creation_date; | ||||||
| 457 | else if (last_modified > 0) | ||||||
| 458 | tt = last_modified; | ||||||
| 459 | else | ||||||
| 460 | tt = (time_t) time (NULL((void*)0)); | ||||||
| 461 | |||||||
| 462 | itt = i_cal_time_new_from_timet_with_zone ((time_t) tt, FALSE(0), i_cal_timezone_get_utc_timezone ()); | ||||||
| 463 | i_cal_component_take_property (icomp, i_cal_property_new_created (itt)); | ||||||
| 464 | g_object_unref (itt); | ||||||
| 465 | |||||||
| 466 | if (last_modified > 0) | ||||||
| 467 | tt = last_modified; | ||||||
| 468 | else | ||||||
| 469 | tt = (time_t) time (NULL((void*)0)); | ||||||
| 470 | |||||||
| 471 | itt = i_cal_time_new_from_timet_with_zone ((time_t) tt, FALSE(0), i_cal_timezone_get_utc_timezone ()); | ||||||
| 472 | i_cal_component_take_property (icomp, i_cal_property_new_lastmodified (itt)); | ||||||
| 473 | g_object_unref (itt); | ||||||
| 474 | |||||||
| 475 | i_cal_component_set_uid (icomp, uid); | ||||||
| 476 | |||||||
| 477 | if (ecb_webdav_notes_has_supported_extension (summary, &ext_len, NULL((void*)0), NULL((void*)0), NULL((void*)0))) { | ||||||
| 478 | gchar *tmp; | ||||||
| 479 | |||||||
| 480 | tmp = g_strndup (summary, strlen (summary) - ext_len); | ||||||
| 481 | i_cal_component_set_summary (icomp, tmp); | ||||||
| 482 | g_free (tmp); | ||||||
| 483 | } else if (summary && *summary) { | ||||||
| 484 | i_cal_component_set_summary (icomp, summary); | ||||||
| 485 | } | ||||||
| 486 | |||||||
| 487 | if ((uid && g_str_has_suffix (uid, ".md")(__builtin_constant_p (".md")? __extension__ ({ const char * const __str = (uid); const char * const __suffix = (".md"); gboolean __result = (0); if (__builtin_expect (__extension__ ({ int _g_boolean_var_77 = 0; if (__str == ((void*)0) || __suffix == ((void*)0)) _g_boolean_var_77 = 1; _g_boolean_var_77; }), 0)) __result = (g_str_has_suffix ) (__str, __suffix); else { const size_t __str_len = strlen ( ((__str) + !(__str))); const size_t __suffix_len = strlen ((( __suffix) + !(__suffix))); if (__str_len >= __suffix_len) __result = memcmp (__str + __str_len - __suffix_len, ((__suffix) + !( __suffix)), __suffix_len) == 0; } __result; }) : (g_str_has_suffix ) (uid, ".md") )) || | ||||||
| 488 | (summary && g_str_has_suffix (summary, ".md")(__builtin_constant_p (".md")? __extension__ ({ const char * const __str = (summary); const char * const __suffix = (".md"); gboolean __result = (0); if (__builtin_expect (__extension__ ({ int _g_boolean_var_78 = 0; if (__str == ((void*)0) || __suffix == ((void*)0)) _g_boolean_var_78 = 1; _g_boolean_var_78; }), 0)) __result = (g_str_has_suffix ) (__str, __suffix); else { const size_t __str_len = strlen ( ((__str) + !(__str))); const size_t __suffix_len = strlen ((( __suffix) + !(__suffix))); if (__str_len >= __suffix_len) __result = memcmp (__str + __str_len - __suffix_len, ((__suffix) + !( __suffix)), __suffix_len) == 0; } __result; }) : (g_str_has_suffix ) (summary, ".md") ))) | ||||||
| 489 | e_cal_util_component_set_x_property (icomp, E_WEBDAV_NOTES_X_IS_MARKDOWN"X-EVOLUTION-IS-MARKDOWN", "1"); | ||||||
| 490 | |||||||
| 491 | if (description && *description) { | ||||||
| 492 | const gchar *current_summary; | ||||||
| 493 | |||||||
| 494 | i_cal_component_set_description (icomp, description); | ||||||
| 495 | |||||||
| 496 | current_summary = i_cal_component_get_summary (icomp); | ||||||
| 497 | |||||||
| 498 | if (!current_summary || !*current_summary) { | ||||||
| 499 | const gchar *pos; | ||||||
| 500 | |||||||
| 501 | pos = strchr (description, '\n'); | ||||||
| 502 | if (pos && pos > description && pos[-1] == '\r') | ||||||
| 503 | pos--; | ||||||
| 504 | |||||||
| 505 | if (!pos) { | ||||||
| 506 | /* single line description */ | ||||||
| 507 | i_cal_component_set_summary (icomp, description); | ||||||
| 508 | } else if (pos > description) { | ||||||
| 509 | gchar *tmp; | ||||||
| 510 | |||||||
| 511 | tmp = g_strndup (description, pos - description); | ||||||
| 512 | i_cal_component_set_summary (icomp, tmp); | ||||||
| 513 | g_free (tmp); | ||||||
| 514 | } | ||||||
| 515 | } | ||||||
| 516 | } | ||||||
| 517 | |||||||
| 518 | e_cal_util_component_set_x_property (icomp, E_WEBDAV_NOTES_X_ETAG"X-EVOLUTION-WEBDAV-NOTES-ETAG", revision); | ||||||
| 519 | |||||||
| 520 | return icomp; | ||||||
| 521 | } | ||||||
| 522 | |||||||
| 523 | static gboolean | ||||||
| 524 | ecb_webdav_notes_get_objects_sync (EWebDAVSession *webdav, | ||||||
| 525 | GHashTable *resources_hash, /* gchar *href ~> EWebDAVResource * */ | ||||||
| 526 | GSList *infos, /* ECalMetaBackendInfo * */ | ||||||
| 527 | GCancellable *cancellable, | ||||||
| 528 | GError **error) | ||||||
| 529 | { | ||||||
| 530 | GSList *link; | ||||||
| 531 | gboolean success = TRUE(!(0)); | ||||||
| 532 | |||||||
| 533 | g_return_val_if_fail (E_IS_WEBDAV_SESSION (webdav), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_79 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((webdav)); GType __t = ((e_webdav_session_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_79 = 1; _g_boolean_var_79; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes", ((const char*) (__func__)), "E_IS_WEBDAV_SESSION (webdav)" ); return ((0)); } } while (0); | ||||||
| 534 | |||||||
| 535 | for (link = infos; success && link; link = g_slist_next (link)((link) ? (((GSList *)(link))->next) : ((void*)0))) { | ||||||
| 536 | ECalMetaBackendInfo *nfo = link->data; | ||||||
| 537 | gchar *etag = NULL((void*)0), *bytes = NULL((void*)0); | ||||||
| 538 | |||||||
| 539 | if (!nfo) | ||||||
| 540 | continue; | ||||||
| 541 | |||||||
| 542 | success = e_webdav_session_get_data_sync (webdav, nfo->extra, NULL((void*)0), &etag, NULL((void*)0), &bytes, NULL((void*)0), cancellable, error); | ||||||
| 543 | |||||||
| 544 | if (success) { | ||||||
| 545 | EWebDAVResource *resource; | ||||||
| 546 | |||||||
| 547 | resource = g_hash_table_lookup (resources_hash, nfo->extra); | ||||||
| 548 | |||||||
| 549 | if (resource) { | ||||||
| 550 | ICalComponent *icomp; | ||||||
| 551 | |||||||
| 552 | if (g_strcmp0 (nfo->revision, etag) != 0) { | ||||||
| 553 | g_free (nfo->revision); | ||||||
| 554 | nfo->revision = etag; | ||||||
| 555 | etag = NULL((void*)0); | ||||||
| 556 | } | ||||||
| 557 | |||||||
| 558 | icomp = ecb_webdav_notes_new_icomp (resource->creation_date, | ||||||
| 559 | resource->last_modified, | ||||||
| 560 | nfo->uid, | ||||||
| 561 | nfo->revision, | ||||||
| 562 | resource->display_name, | ||||||
| 563 | bytes); | ||||||
| 564 | |||||||
| 565 | g_warn_if_fail (nfo->object == NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_80 = 0; if (nfo->object == ((void*)0)) _g_boolean_var_80 = 1 ; _g_boolean_var_80; }), 1)) ; else g_warn_message ("e-cal-backend-webdav-notes" , "/builds/GNOME/evolution-data-server/src/calendar/backends/webdav-notes/e-cal-backend-webdav-notes.c" , 565, ((const char*) (__func__)), "nfo->object == NULL"); } while (0); | ||||||
| 566 | |||||||
| 567 | nfo->object = i_cal_component_as_ical_string (icomp); | ||||||
| 568 | |||||||
| 569 | g_object_unref (icomp); | ||||||
| 570 | } else { /* !resource */ | ||||||
| 571 | g_warn_if_reached ()do { g_warn_message ("e-cal-backend-webdav-notes", "/builds/GNOME/evolution-data-server/src/calendar/backends/webdav-notes/e-cal-backend-webdav-notes.c" , 571, ((const char*) (__func__)), ((void*)0)); } while (0); | ||||||
| 572 | } | ||||||
| 573 | } | ||||||
| 574 | |||||||
| 575 | g_free (etag); | ||||||
| 576 | g_free (bytes); | ||||||
| 577 | } | ||||||
| 578 | |||||||
| 579 | return success; | ||||||
| 580 | } | ||||||
| 581 | |||||||
| 582 | static gchar * | ||||||
| 583 | ecb_webdav_notes_href_to_uid (const gchar *href) | ||||||
| 584 | { | ||||||
| 585 | const gchar *filename; | ||||||
| 586 | |||||||
| 587 | if (!href || !*href) | ||||||
| 588 | return NULL((void*)0); | ||||||
| 589 | |||||||
| 590 | filename = strrchr (href, '/'); | ||||||
| 591 | |||||||
| 592 | if (filename && filename[1]) | ||||||
| 593 | return g_uri_unescape_string (filename + 1, NULL((void*)0)); | ||||||
| 594 | |||||||
| 595 | return g_uri_unescape_string (href, NULL((void*)0)); | ||||||
| 596 | } | ||||||
| 597 | |||||||
| 598 | static gboolean | ||||||
| 599 | ecb_webdav_notes_get_changes_sync (ECalMetaBackend *meta_backend, | ||||||
| 600 | const gchar *last_sync_tag, | ||||||
| 601 | gboolean is_repeat, | ||||||
| 602 | gchar **out_new_sync_tag, | ||||||
| 603 | gboolean *out_repeat, | ||||||
| 604 | GSList **out_created_objects, | ||||||
| 605 | GSList **out_modified_objects, | ||||||
| 606 | GSList **out_removed_objects, | ||||||
| 607 | GCancellable *cancellable, | ||||||
| 608 | GError **error) | ||||||
| 609 | { | ||||||
| 610 | ECalBackendWebDAVNotes *cbnotes; | ||||||
| 611 | EWebDAVSession *webdav; | ||||||
| 612 | GHashTable *known_items; /* gchar *href ~> ECalMetaBackendInfo * */ | ||||||
| 613 | GHashTable *resources_hash; /* gchar *href ~> EWebDAVResource *, both borrowed from 'resources' GSList */ | ||||||
| 614 | GHashTableIter iter; | ||||||
| 615 | GSList *resources = NULL((void*)0), *link; | ||||||
| 616 | gpointer key = NULL((void*)0), value = NULL((void*)0); | ||||||
| 617 | gboolean success; | ||||||
| 618 | GError *local_error = NULL((void*)0); | ||||||
| 619 | |||||||
| 620 | g_return_val_if_fail (E_IS_CAL_BACKEND_WEBDAV_NOTES (meta_backend), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_81 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((meta_backend)); GType __t = ((e_cal_backend_webdav_notes_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_81 = 1; _g_boolean_var_81; }), 1) )) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "E_IS_CAL_BACKEND_WEBDAV_NOTES (meta_backend)" ); return ((0)); } } while (0); | ||||||
| 621 | g_return_val_if_fail (out_new_sync_tag, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_82 = 0; if (out_new_sync_tag) _g_boolean_var_82 = 1; _g_boolean_var_82 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "out_new_sync_tag"); return ((0 )); } } while (0); | ||||||
| 622 | g_return_val_if_fail (out_created_objects, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_83 = 0; if (out_created_objects) _g_boolean_var_83 = 1; _g_boolean_var_83 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "out_created_objects"); return ( (0)); } } while (0); | ||||||
| 623 | g_return_val_if_fail (out_modified_objects, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_84 = 0; if (out_modified_objects) _g_boolean_var_84 = 1; _g_boolean_var_84 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "out_modified_objects"); return ((0)); } } while (0); | ||||||
| 624 | g_return_val_if_fail (out_removed_objects, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_85 = 0; if (out_removed_objects) _g_boolean_var_85 = 1; _g_boolean_var_85 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "out_removed_objects"); return ( (0)); } } while (0); | ||||||
| 625 | |||||||
| 626 | *out_new_sync_tag = NULL((void*)0); | ||||||
| 627 | *out_created_objects = NULL((void*)0); | ||||||
| 628 | *out_modified_objects = NULL((void*)0); | ||||||
| 629 | *out_removed_objects = NULL((void*)0); | ||||||
| 630 | |||||||
| 631 | cbnotes = E_CAL_BACKEND_WEBDAV_NOTES (meta_backend)((((ECalBackendWebDAVNotes*) (void *) ((meta_backend))))); | ||||||
| 632 | webdav = ecb_webdav_notes_ref_session (cbnotes); | ||||||
| 633 | |||||||
| 634 | if (cbnotes->priv->etag_supported) { | ||||||
| 635 | gchar *new_sync_tag = NULL((void*)0); | ||||||
| 636 | |||||||
| 637 | success = ecb_webdav_notes_getetag_sync (webdav, NULL((void*)0), &new_sync_tag, cancellable, NULL((void*)0)); | ||||||
| 638 | if (!success) { | ||||||
| 639 | cbnotes->priv->etag_supported = g_cancellable_set_error_if_cancelled (cancellable, error); | ||||||
| 640 | if (cbnotes->priv->etag_supported || !webdav) { | ||||||
| 641 | g_clear_object (&webdav)do { _Static_assert (sizeof *((&webdav)) == sizeof (gpointer ), "Expression evaluates to false"); __typeof__ (((&webdav ))) _pp = ((&webdav)); __typeof__ (*((&webdav))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr) ; } while (0); | ||||||
| 642 | return FALSE(0); | ||||||
| 643 | } | ||||||
| 644 | } else if (new_sync_tag && last_sync_tag && g_strcmp0 (last_sync_tag, new_sync_tag) == 0) { | ||||||
| 645 | *out_new_sync_tag = new_sync_tag; | ||||||
| 646 | g_clear_object (&webdav)do { _Static_assert (sizeof *((&webdav)) == sizeof (gpointer ), "Expression evaluates to false"); __typeof__ (((&webdav ))) _pp = ((&webdav)); __typeof__ (*((&webdav))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr) ; } while (0); | ||||||
| 647 | return TRUE(!(0)); | ||||||
| 648 | } | ||||||
| 649 | |||||||
| 650 | *out_new_sync_tag = new_sync_tag; | ||||||
| 651 | } | ||||||
| 652 | |||||||
| 653 | known_items = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, e_cal_meta_backend_info_free); | ||||||
| 654 | resources_hash = g_hash_table_new (g_str_hash, g_str_equal); | ||||||
| 655 | |||||||
| 656 | success = e_webdav_session_list_sync (webdav, NULL((void*)0), E_WEBDAV_DEPTH_THIS_AND_CHILDREN"1", | ||||||
| 657 | E_WEBDAV_LIST_ETAG | E_WEBDAV_LIST_DISPLAY_NAME | E_WEBDAV_LIST_CREATION_DATE | E_WEBDAV_LIST_LAST_MODIFIED, | ||||||
| 658 | &resources, cancellable, &local_error); | ||||||
| 659 | |||||||
| 660 | if (success) { | ||||||
| 661 | ECalCache *cal_cache; | ||||||
| 662 | WebDAVNotesChangesData ccd; | ||||||
| 663 | |||||||
| 664 | for (link = resources; link; link = g_slist_next (link)((link) ? (((GSList *)(link))->next) : ((void*)0))) { | ||||||
| 665 | EWebDAVResource *resource = link->data; | ||||||
| 666 | |||||||
| 667 | if (resource && resource->kind == E_WEBDAV_RESOURCE_KIND_RESOURCE && resource->href && | ||||||
| 668 | ecb_webdav_notes_has_supported_extension (resource->href, NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0))) { | ||||||
| 669 | gchar *filename = ecb_webdav_notes_href_to_uid (resource->href); | ||||||
| 670 | |||||||
| 671 | g_hash_table_insert (known_items, g_strdup (resource->href)g_strdup_inline (resource->href), | ||||||
| 672 | e_cal_meta_backend_info_new (filename, resource->etag, NULL((void*)0), resource->href)); | ||||||
| 673 | |||||||
| 674 | g_hash_table_insert (resources_hash, resource->href, resource); | ||||||
| 675 | |||||||
| 676 | g_free (filename); | ||||||
| 677 | } | ||||||
| 678 | } | ||||||
| 679 | |||||||
| 680 | ccd.out_modified_objects = out_modified_objects; | ||||||
| 681 | ccd.out_removed_objects = out_removed_objects; | ||||||
| 682 | ccd.known_items = known_items; | ||||||
| 683 | |||||||
| 684 | cal_cache = e_cal_meta_backend_ref_cache (meta_backend); | ||||||
| 685 | |||||||
| 686 | success = e_cal_cache_search_with_callback (cal_cache, NULL((void*)0), ecb_webdav_notes_search_changes_cb, &ccd, cancellable, &local_error); | ||||||
| 687 | |||||||
| 688 | g_clear_object (&cal_cache)do { _Static_assert (sizeof *((&cal_cache)) == sizeof (gpointer ), "Expression evaluates to false"); __typeof__ (((&cal_cache ))) _pp = ((&cal_cache)); __typeof__ (*((&cal_cache)) ) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) ( _ptr); } while (0); | ||||||
| 689 | } | ||||||
| 690 | |||||||
| 691 | if (success) { | ||||||
| 692 | g_hash_table_iter_init (&iter, known_items); | ||||||
| 693 | while (g_hash_table_iter_next (&iter, &key, &value)) { | ||||||
| 694 | *out_created_objects = g_slist_prepend (*out_created_objects, e_cal_meta_backend_info_copy (value)); | ||||||
| 695 | } | ||||||
| 696 | } | ||||||
| 697 | |||||||
| 698 | g_hash_table_destroy (known_items); | ||||||
| 699 | |||||||
| 700 | if (success && (*out_created_objects || *out_modified_objects)) { | ||||||
| 701 | success = ecb_webdav_notes_get_objects_sync (webdav, resources_hash, *out_created_objects, cancellable, &local_error); | ||||||
| 702 | success = success && ecb_webdav_notes_get_objects_sync (webdav, resources_hash, *out_modified_objects, cancellable, &local_error); | ||||||
| 703 | } | ||||||
| 704 | |||||||
| 705 | if (local_error) { | ||||||
| 706 | ecb_webdav_notes_check_credentials_error (cbnotes, webdav, local_error); | ||||||
| 707 | g_propagate_error (error, local_error); | ||||||
| 708 | } | ||||||
| 709 | |||||||
| 710 | g_slist_free_full (resources, e_webdav_resource_free); | ||||||
| 711 | g_hash_table_destroy (resources_hash); | ||||||
| 712 | g_clear_object (&webdav)do { _Static_assert (sizeof *((&webdav)) == sizeof (gpointer ), "Expression evaluates to false"); __typeof__ (((&webdav ))) _pp = ((&webdav)); __typeof__ (*((&webdav))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr) ; } while (0); | ||||||
| 713 | |||||||
| 714 | return success; | ||||||
| 715 | } | ||||||
| 716 | |||||||
| 717 | static gboolean | ||||||
| 718 | ecb_webdav_notes_list_existing_sync (ECalMetaBackend *meta_backend, | ||||||
| 719 | gchar **out_new_sync_tag, | ||||||
| 720 | GSList **out_existing_objects, | ||||||
| 721 | GCancellable *cancellable, | ||||||
| 722 | GError **error) | ||||||
| 723 | { | ||||||
| 724 | ECalBackendWebDAVNotes *cbnotes; | ||||||
| 725 | EWebDAVSession *webdav; | ||||||
| 726 | GSList *resources = NULL((void*)0); | ||||||
| 727 | GError *local_error = NULL((void*)0); | ||||||
| 728 | gboolean success; | ||||||
| 729 | |||||||
| 730 | g_return_val_if_fail (E_IS_CAL_BACKEND_WEBDAV_NOTES (meta_backend), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_86 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((meta_backend)); GType __t = ((e_cal_backend_webdav_notes_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_86 = 1; _g_boolean_var_86; }), 1) )) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "E_IS_CAL_BACKEND_WEBDAV_NOTES (meta_backend)" ); return ((0)); } } while (0); | ||||||
| 731 | g_return_val_if_fail (out_existing_objects != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_87 = 0; if (out_existing_objects != ((void*)0)) _g_boolean_var_87 = 1; _g_boolean_var_87; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes", ((const char*) (__func__)), "out_existing_objects != NULL" ); return ((0)); } } while (0); | ||||||
| 732 | |||||||
| 733 | *out_existing_objects = NULL((void*)0); | ||||||
| 734 | |||||||
| 735 | cbnotes = E_CAL_BACKEND_WEBDAV_NOTES (meta_backend)((((ECalBackendWebDAVNotes*) (void *) ((meta_backend))))); | ||||||
| 736 | webdav = ecb_webdav_notes_ref_session (cbnotes); | ||||||
| 737 | |||||||
| 738 | success = e_webdav_session_list_sync (webdav, NULL((void*)0), E_WEBDAV_DEPTH_THIS_AND_CHILDREN"1", E_WEBDAV_LIST_ETAG, &resources, cancellable, &local_error); | ||||||
| 739 | |||||||
| 740 | if (success) { | ||||||
| 741 | GSList *link; | ||||||
| 742 | |||||||
| 743 | for (link = resources; link; link = g_slist_next (link)((link) ? (((GSList *)(link))->next) : ((void*)0))) { | ||||||
| 744 | EWebDAVResource *resource = link->data; | ||||||
| 745 | |||||||
| 746 | if (resource && resource->kind == E_WEBDAV_RESOURCE_KIND_RESOURCE && resource->href && | ||||||
| 747 | ecb_webdav_notes_has_supported_extension (resource->href, NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0))) { | ||||||
| 748 | gchar *filename = ecb_webdav_notes_href_to_uid (resource->href); | ||||||
| 749 | |||||||
| 750 | *out_existing_objects = g_slist_prepend (*out_existing_objects, | ||||||
| 751 | e_cal_meta_backend_info_new (filename, resource->etag, NULL((void*)0), resource->href)); | ||||||
| 752 | |||||||
| 753 | g_free (filename); | ||||||
| 754 | } | ||||||
| 755 | } | ||||||
| 756 | |||||||
| 757 | *out_existing_objects = g_slist_reverse (*out_existing_objects); | ||||||
| 758 | } | ||||||
| 759 | |||||||
| 760 | if (local_error) { | ||||||
| 761 | ecb_webdav_notes_check_credentials_error (cbnotes, webdav, local_error); | ||||||
| 762 | g_propagate_error (error, local_error); | ||||||
| 763 | } | ||||||
| 764 | |||||||
| 765 | g_slist_free_full (resources, e_webdav_resource_free); | ||||||
| 766 | g_clear_object (&webdav)do { _Static_assert (sizeof *((&webdav)) == sizeof (gpointer ), "Expression evaluates to false"); __typeof__ (((&webdav ))) _pp = ((&webdav)); __typeof__ (*((&webdav))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr) ; } while (0); | ||||||
| 767 | |||||||
| 768 | return success; | ||||||
| 769 | } | ||||||
| 770 | |||||||
| 771 | static gchar * | ||||||
| 772 | ecb_webdav_notes_uid_to_uri (ECalBackendWebDAVNotes *cbnotes, | ||||||
| 773 | const gchar *uid) | ||||||
| 774 | { | ||||||
| 775 | ESourceWebdav *webdav_extension; | ||||||
| 776 | GUri *parsed_uri; | ||||||
| 777 | gchar *uri, *tmp, *filename, *uid_hash = NULL((void*)0); | ||||||
| 778 | |||||||
| 779 | g_return_val_if_fail (E_IS_CAL_BACKEND_WEBDAV_NOTES (cbnotes), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_88 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((cbnotes)); GType __t = ((e_cal_backend_webdav_notes_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_88 = 1; _g_boolean_var_88; }), 1) )) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "E_IS_CAL_BACKEND_WEBDAV_NOTES (cbnotes)" ); return (((void*)0)); } } while (0); | ||||||
| 780 | g_return_val_if_fail (uid != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_89 = 0; if (uid != ((void*)0)) _g_boolean_var_89 = 1; _g_boolean_var_89 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "uid != NULL"); return (((void* )0)); } } while (0); | ||||||
| 781 | |||||||
| 782 | webdav_extension = e_source_get_extension (e_backend_get_source (E_BACKEND (cbnotes)((((EBackend*) (void *) ((cbnotes)))))), E_SOURCE_EXTENSION_WEBDAV_BACKEND"WebDAV Backend"); | ||||||
| 783 | parsed_uri = e_source_webdav_dup_uri (webdav_extension); | ||||||
| 784 | g_return_val_if_fail (parsed_uri != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_90 = 0; if (parsed_uri != ((void*)0)) _g_boolean_var_90 = 1; _g_boolean_var_90 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "parsed_uri != NULL"); return ( ((void*)0)); } } while (0); | ||||||
| 785 | |||||||
| 786 | /* UIDs with forward slashes can cause trouble, because the destination server can | ||||||
| 787 | consider them as a path delimiter. Double-encode the URL doesn't always work, | ||||||
| 788 | thus rather cause a mismatch between stored UID and its href on the server. */ | ||||||
| 789 | if (strchr (uid, '/')) { | ||||||
| 790 | uid_hash = g_compute_checksum_for_string (G_CHECKSUM_SHA1, uid, -1); | ||||||
| 791 | |||||||
| 792 | if (uid_hash) | ||||||
| 793 | uid = uid_hash; | ||||||
| 794 | } | ||||||
| 795 | |||||||
| 796 | filename = g_uri_escape_string (uid, NULL((void*)0), FALSE(0)); | ||||||
| 797 | |||||||
| 798 | if (*g_uri_get_path (parsed_uri)) { | ||||||
| 799 | const gchar *slash = strrchr (g_uri_get_path (parsed_uri), '/'); | ||||||
| 800 | |||||||
| 801 | if (slash && !slash[1]) | ||||||
| 802 | tmp = g_strconcat (g_uri_get_path (parsed_uri), filename, NULL((void*)0)); | ||||||
| 803 | else | ||||||
| 804 | tmp = g_strconcat (g_uri_get_path (parsed_uri), "/", filename, NULL((void*)0)); | ||||||
| 805 | } else | ||||||
| 806 | tmp = g_strconcat ("/", filename, NULL((void*)0)); | ||||||
| 807 | |||||||
| 808 | e_util_change_uri_component (&parsed_uri, SOUP_URI_PATH, tmp); | ||||||
| 809 | uri = g_uri_to_string_partial (parsed_uri, G_URI_HIDE_USERINFO | G_URI_HIDE_PASSWORD); | ||||||
| 810 | |||||||
| 811 | g_uri_unref (parsed_uri); | ||||||
| 812 | g_free (filename); | ||||||
| 813 | g_free (uid_hash); | ||||||
| 814 | |||||||
| 815 | return uri; | ||||||
| 816 | } | ||||||
| 817 | |||||||
| 818 | static void | ||||||
| 819 | ecb_webdav_notes_store_component_etag (ICalComponent *icomp, | ||||||
| 820 | const gchar *etag) | ||||||
| 821 | { | ||||||
| 822 | ICalComponent *subcomp; | ||||||
| 823 | |||||||
| 824 | g_return_if_fail (icomp != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_91 = 0; if (icomp != ((void*)0)) _g_boolean_var_91 = 1; _g_boolean_var_91 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "icomp != NULL"); return; } } while (0); | ||||||
| 825 | g_return_if_fail (etag != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_92 = 0; if (etag != ((void*)0)) _g_boolean_var_92 = 1; _g_boolean_var_92 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "etag != NULL"); return; } } while (0); | ||||||
| 826 | |||||||
| 827 | e_cal_util_component_set_x_property (icomp, E_WEBDAV_NOTES_X_ETAG"X-EVOLUTION-WEBDAV-NOTES-ETAG", etag); | ||||||
| 828 | |||||||
| 829 | for (subcomp = i_cal_component_get_first_component (icomp, I_CAL_ANY_COMPONENT); | ||||||
| 830 | subcomp; | ||||||
| 831 | g_object_unref (subcomp), subcomp = i_cal_component_get_next_component (icomp, I_CAL_ANY_COMPONENT)) { | ||||||
| 832 | ICalComponentKind kind = i_cal_component_isa (subcomp); | ||||||
| 833 | |||||||
| 834 | if (kind == I_CAL_VJOURNAL_COMPONENT) { | ||||||
| 835 | e_cal_util_component_set_x_property (subcomp, E_WEBDAV_NOTES_X_ETAG"X-EVOLUTION-WEBDAV-NOTES-ETAG", etag); | ||||||
| 836 | } | ||||||
| 837 | } | ||||||
| 838 | } | ||||||
| 839 | |||||||
| 840 | static gboolean | ||||||
| 841 | ecb_webdav_notes_load_component_sync (ECalMetaBackend *meta_backend, | ||||||
| 842 | const gchar *uid, | ||||||
| 843 | const gchar *extra, | ||||||
| 844 | ICalComponent **out_component, | ||||||
| 845 | gchar **out_extra, | ||||||
| 846 | GCancellable *cancellable, | ||||||
| 847 | GError **error) | ||||||
| 848 | { | ||||||
| 849 | ECalBackendWebDAVNotes *cbnotes; | ||||||
| 850 | EWebDAVSession *webdav; | ||||||
| 851 | EWebDAVResource *use_resource = NULL((void*)0); | ||||||
| 852 | gchar *uri = NULL((void*)0), *href = NULL((void*)0), *etag = NULL((void*)0), *bytes = NULL((void*)0); | ||||||
| 853 | gsize length = -1; | ||||||
| 854 | gboolean success = FALSE(0); | ||||||
| 855 | GError *local_error = NULL((void*)0); | ||||||
| 856 | |||||||
| 857 | g_return_val_if_fail (E_IS_CAL_BACKEND_WEBDAV_NOTES (meta_backend), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_93 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((meta_backend)); GType __t = ((e_cal_backend_webdav_notes_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_93 = 1; _g_boolean_var_93; }), 1) )) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "E_IS_CAL_BACKEND_WEBDAV_NOTES (meta_backend)" ); return ((0)); } } while (0); | ||||||
| 858 | g_return_val_if_fail (uid != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_94 = 0; if (uid != ((void*)0)) _g_boolean_var_94 = 1; _g_boolean_var_94 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "uid != NULL"); return ((0)); } } while (0); | ||||||
| 859 | g_return_val_if_fail (out_component != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_95 = 0; if (out_component != ((void*)0)) _g_boolean_var_95 = 1; _g_boolean_var_95; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes", ((const char*) (__func__)), "out_component != NULL" ); return ((0)); } } while (0); | ||||||
| 860 | g_return_val_if_fail (out_extra != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_96 = 0; if (out_extra != ((void*)0)) _g_boolean_var_96 = 1; _g_boolean_var_96 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "out_extra != NULL"); return (( 0)); } } while (0); | ||||||
| 861 | |||||||
| 862 | cbnotes = E_CAL_BACKEND_WEBDAV_NOTES (meta_backend)((((ECalBackendWebDAVNotes*) (void *) ((meta_backend))))); | ||||||
| 863 | |||||||
| 864 | /* When called immediately after save and the server didn't change the component, | ||||||
| 865 | then the 'extra' contains "href" + "\n" + "vCalendar", to avoid unneeded GET | ||||||
| 866 | from the server. */ | ||||||
| 867 | if (extra && *extra) { | ||||||
| 868 | const gchar *newline; | ||||||
| 869 | |||||||
| 870 | newline = strchr (extra, '\n'); | ||||||
| 871 | if (newline && newline[1] && newline != extra) { | ||||||
| 872 | ICalComponent *vcalendar; | ||||||
| 873 | |||||||
| 874 | vcalendar = i_cal_component_new_from_string (newline + 1); | ||||||
| 875 | if (vcalendar) { | ||||||
| 876 | *out_extra = g_strndup (extra, newline - extra); | ||||||
| 877 | *out_component = vcalendar; | ||||||
| 878 | |||||||
| 879 | return TRUE(!(0)); | ||||||
| 880 | } | ||||||
| 881 | } | ||||||
| 882 | } | ||||||
| 883 | |||||||
| 884 | webdav = ecb_webdav_notes_ref_session (cbnotes); | ||||||
| 885 | |||||||
| 886 | if (extra && *extra) { | ||||||
| 887 | uri = g_strdup (extra)g_strdup_inline (extra); | ||||||
| 888 | |||||||
| 889 | success = e_webdav_session_get_data_sync (webdav, uri, &href, &etag, NULL((void*)0), &bytes, &length, cancellable, &local_error); | ||||||
| 890 | |||||||
| 891 | if (!success) { | ||||||
| 892 | g_free (uri); | ||||||
| 893 | uri = NULL((void*)0); | ||||||
| 894 | } | ||||||
| 895 | } | ||||||
| 896 | |||||||
| 897 | if (!success && cbnotes->priv->etag_supported) { | ||||||
| 898 | gchar *new_sync_tag = NULL((void*)0); | ||||||
| 899 | |||||||
| 900 | if (ecb_webdav_notes_getetag_sync (webdav, NULL((void*)0), &new_sync_tag, cancellable, NULL((void*)0)) && new_sync_tag) { | ||||||
| 901 | gchar *last_sync_tag; | ||||||
| 902 | |||||||
| 903 | last_sync_tag = e_cal_meta_backend_dup_sync_tag (meta_backend); | ||||||
| 904 | |||||||
| 905 | /* The calendar didn't change, thus the component cannot be there */ | ||||||
| 906 | if (g_strcmp0 (last_sync_tag, new_sync_tag) == 0) { | ||||||
| 907 | g_clear_error (&local_error); | ||||||
| 908 | g_clear_object (&webdav)do { _Static_assert (sizeof *((&webdav)) == sizeof (gpointer ), "Expression evaluates to false"); __typeof__ (((&webdav ))) _pp = ((&webdav)); __typeof__ (*((&webdav))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr) ; } while (0); | ||||||
| 909 | g_free (last_sync_tag); | ||||||
| 910 | g_free (new_sync_tag); | ||||||
| 911 | |||||||
| 912 | g_propagate_error (error, ECC_ERROR (E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND)e_cal_client_error_create (E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND , ((void*)0))); | ||||||
| 913 | |||||||
| 914 | return FALSE(0); | ||||||
| 915 | } | ||||||
| 916 | |||||||
| 917 | g_free (last_sync_tag); | ||||||
| 918 | } | ||||||
| 919 | |||||||
| 920 | g_free (new_sync_tag); | ||||||
| 921 | } | ||||||
| 922 | |||||||
| 923 | if (!success) { | ||||||
| 924 | uri = ecb_webdav_notes_uid_to_uri (cbnotes, uid); | ||||||
| 925 | g_return_val_if_fail (uri != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_97 = 0; if (uri != ((void*)0)) _g_boolean_var_97 = 1; _g_boolean_var_97 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "uri != NULL"); return ((0)); } } while (0); | ||||||
| 926 | |||||||
| 927 | g_clear_error (&local_error); | ||||||
| 928 | |||||||
| 929 | success = e_webdav_session_get_data_sync (webdav, uri, &href, &etag, NULL((void*)0), &bytes, &length, cancellable, &local_error); | ||||||
| 930 | } | ||||||
| 931 | |||||||
| 932 | if (success) { | ||||||
| 933 | GSList *resources = NULL((void*)0); | ||||||
| 934 | |||||||
| 935 | success = e_webdav_session_list_sync (webdav, href, E_WEBDAV_DEPTH_THIS"0", | ||||||
| 936 | E_WEBDAV_LIST_DISPLAY_NAME | E_WEBDAV_LIST_CREATION_DATE | E_WEBDAV_LIST_LAST_MODIFIED, | ||||||
| 937 | &resources, cancellable, &local_error); | ||||||
| 938 | |||||||
| 939 | if (success) { | ||||||
| 940 | GSList *link; | ||||||
| 941 | |||||||
| 942 | for (link = resources; link; link = g_slist_next (link)((link) ? (((GSList *)(link))->next) : ((void*)0))) { | ||||||
| 943 | EWebDAVResource *resource = link->data; | ||||||
| 944 | |||||||
| 945 | if (resource && resource->kind == E_WEBDAV_RESOURCE_KIND_RESOURCE && g_strcmp0 (resource->href, href) == 0) { | ||||||
| 946 | use_resource = resource; | ||||||
| 947 | link->data = NULL((void*)0); | ||||||
| 948 | break; | ||||||
| 949 | } | ||||||
| 950 | } | ||||||
| 951 | |||||||
| 952 | g_slist_free_full (resources, e_webdav_resource_free); | ||||||
| 953 | |||||||
| 954 | success = use_resource != NULL((void*)0); | ||||||
| 955 | |||||||
| 956 | if (!success) | ||||||
| 957 | local_error = ECC_ERROR (E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND)e_cal_client_error_create (E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND , ((void*)0)); | ||||||
| 958 | } | ||||||
| 959 | } | ||||||
| 960 | |||||||
| 961 | if (success) { | ||||||
| 962 | *out_component = NULL((void*)0); | ||||||
| 963 | |||||||
| 964 | if (href && etag && length != ((gsize) -1)) { | ||||||
| 965 | ICalComponent *icomp; | ||||||
| 966 | gchar *filename = ecb_webdav_notes_href_to_uid (use_resource->href); | ||||||
| 967 | |||||||
| 968 | icomp = ecb_webdav_notes_new_icomp (use_resource->creation_date, | ||||||
| 969 | use_resource->last_modified, | ||||||
| 970 | filename, | ||||||
| 971 | etag, | ||||||
| 972 | use_resource->display_name, | ||||||
| 973 | bytes); | ||||||
| 974 | |||||||
| 975 | g_free (filename); | ||||||
| 976 | |||||||
| 977 | if (icomp) { | ||||||
| 978 | ecb_webdav_notes_store_component_etag (icomp, etag); | ||||||
| 979 | |||||||
| 980 | *out_component = icomp; | ||||||
| 981 | } | ||||||
| 982 | } | ||||||
| 983 | |||||||
| 984 | if (!*out_component) { | ||||||
| 985 | success = FALSE(0); | ||||||
| 986 | |||||||
| 987 | if (!href) | ||||||
| 988 | g_propagate_error (&local_error, ECC_ERROR_EX (E_CAL_CLIENT_ERROR_INVALID_OBJECT, _("Server didn’t return object’s href"))e_cal_client_error_create (E_CAL_CLIENT_ERROR_INVALID_OBJECT, ((char *) g_dgettext ("evolution-data-server", "Server didn’t return object’s href" )))); | ||||||
| 989 | else if (!etag) | ||||||
| 990 | g_propagate_error (&local_error, ECC_ERROR_EX (E_CAL_CLIENT_ERROR_INVALID_OBJECT, _("Server didn’t return object’s ETag"))e_cal_client_error_create (E_CAL_CLIENT_ERROR_INVALID_OBJECT, ((char *) g_dgettext ("evolution-data-server", "Server didn’t return object’s ETag" )))); | ||||||
| 991 | else | ||||||
| 992 | g_propagate_error (&local_error, ECC_ERROR (E_CAL_CLIENT_ERROR_INVALID_OBJECT)e_cal_client_error_create (E_CAL_CLIENT_ERROR_INVALID_OBJECT, ((void*)0))); | ||||||
| 993 | } else if (out_extra) { | ||||||
| 994 | *out_extra = g_strdup (href)g_strdup_inline (href); | ||||||
| 995 | } | ||||||
| 996 | } | ||||||
| 997 | |||||||
| 998 | e_webdav_resource_free (use_resource); | ||||||
| 999 | g_free (uri); | ||||||
| 1000 | g_free (href); | ||||||
| 1001 | g_free (etag); | ||||||
| 1002 | g_free (bytes); | ||||||
| 1003 | |||||||
| 1004 | if (local_error) { | ||||||
| 1005 | ecb_webdav_notes_check_credentials_error (cbnotes, webdav, local_error); | ||||||
| 1006 | |||||||
| 1007 | if (g_error_matches (local_error, E_SOUP_SESSION_ERROR(e_soup_session_error_quark()), SOUP_STATUS_NOT_FOUND)) { | ||||||
| 1008 | local_error->domain = E_CAL_CLIENT_ERRORe_cal_client_error_quark (); | ||||||
| 1009 | local_error->code = E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND; | ||||||
| 1010 | } | ||||||
| 1011 | |||||||
| 1012 | g_propagate_error (error, local_error); | ||||||
| 1013 | } | ||||||
| 1014 | |||||||
| 1015 | g_clear_object (&webdav)do { _Static_assert (sizeof *((&webdav)) == sizeof (gpointer ), "Expression evaluates to false"); __typeof__ (((&webdav ))) _pp = ((&webdav)); __typeof__ (*((&webdav))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr) ; } while (0); | ||||||
| 1016 | |||||||
| 1017 | return success; | ||||||
| 1018 | } | ||||||
| 1019 | |||||||
| 1020 | /* A rough code to mimic what Nextcloud does, it's not accurate, but it's close | ||||||
| 1021 | enough to work similarly. It skips leading whitespaces and uses up to the first | ||||||
| 1022 | 100 letters of the first non-empty line as the base file name. */ | ||||||
| 1023 | static gchar * | ||||||
| 1024 | ecb_webdav_notes_construct_base_filename (const gchar *description) | ||||||
| 1025 | { | ||||||
| 1026 | GString *base_filename; | ||||||
| 1027 | gunichar uchr; | ||||||
| 1028 | gboolean add_space = FALSE(0); | ||||||
| 1029 | |||||||
| 1030 | if (!description || !*description || !g_utf8_validate (description, -1, NULL((void*)0))) | ||||||
| 1031 | return g_strdup (_("New note"))g_strdup_inline (((char *) g_dgettext ("evolution-data-server" , "New note"))); | ||||||
| 1032 | |||||||
| 1033 | base_filename = g_string_sized_new (102); | ||||||
| 1034 | |||||||
| 1035 | while (uchr = g_utf8_get_char (description), g_unichar_isspace (uchr)) | ||||||
| 1036 | description = g_utf8_next_char (description)((description) + g_utf8_skip[*(const guchar *)(description)]); | ||||||
| 1037 | |||||||
| 1038 | while (uchr = g_utf8_get_char (description), uchr && uchr != '\r' && uchr != '\n') { | ||||||
| 1039 | if (g_unichar_isspace (uchr)) { | ||||||
| 1040 | add_space = TRUE(!(0)); | ||||||
| 1041 | } else if ((uchr >> 8) != 0 || !strchr ("\"/\\?:*|", (uchr & 0xFF))) { | ||||||
| 1042 | if (base_filename->len >= 98) | ||||||
| 1043 | break; | ||||||
| 1044 | |||||||
| 1045 | if (add_space) { | ||||||
| 1046 | g_string_append_c (base_filename, ' ')g_string_append_c_inline (base_filename, ' '); | ||||||
| 1047 | add_space = FALSE(0); | ||||||
| 1048 | } | ||||||
| 1049 | |||||||
| 1050 | g_string_append_unichar (base_filename, uchr); | ||||||
| 1051 | |||||||
| 1052 | if (base_filename->len >= 100) | ||||||
| 1053 | break; | ||||||
| 1054 | } | ||||||
| 1055 | |||||||
| 1056 | description = g_utf8_next_char (description)((description) + g_utf8_skip[*(const guchar *)(description)]); | ||||||
| 1057 | } | ||||||
| 1058 | |||||||
| 1059 | if (!base_filename->len) | ||||||
| 1060 | g_string_append (base_filename, _("New note"))(__builtin_constant_p (((char *) g_dgettext ("evolution-data-server" , "New note"))) ? __extension__ ({ const char * const __val = (((char *) g_dgettext ("evolution-data-server", "New note")) ); g_string_append_len_inline (base_filename, __val, (__builtin_expect (__extension__ ({ int _g_boolean_var_98 = 0; if (__val != (( void*)0)) _g_boolean_var_98 = 1; _g_boolean_var_98; }), 1)) ? (gssize) strlen (((__val) + !(__val))) : (gssize) -1); }) : g_string_append_len_inline (base_filename, ((char *) g_dgettext ("evolution-data-server" , "New note")), (gssize) -1)); | ||||||
| 1061 | |||||||
| 1062 | return g_string_free (base_filename, FALSE(0)); | ||||||
| 1063 | } | ||||||
| 1064 | |||||||
| 1065 | static gboolean | ||||||
| 1066 | ecb_webdav_notes_save_component_sync (ECalMetaBackend *meta_backend, | ||||||
| 1067 | gboolean overwrite_existing, | ||||||
| 1068 | EConflictResolution conflict_resolution, | ||||||
| 1069 | const GSList *instances, | ||||||
| 1070 | const gchar *extra, | ||||||
| 1071 | ECalOperationFlags opflags, | ||||||
| 1072 | gchar **out_new_uid, | ||||||
| 1073 | gchar **out_new_extra, | ||||||
| 1074 | GCancellable *cancellable, | ||||||
| 1075 | GError **error) | ||||||
| 1076 | { | ||||||
| 1077 | ECalBackendWebDAVNotes *cbnotes; | ||||||
| 1078 | EWebDAVSession *webdav; | ||||||
| 1079 | ICalComponent *icomp; | ||||||
| 1080 | gchar *href = NULL((void*)0), *etag = NULL((void*)0); | ||||||
| 1081 | const gchar *description = NULL((void*)0), *uid = NULL((void*)0); | ||||||
| 1082 | gboolean success; | ||||||
| 1083 | GError *local_error = NULL((void*)0); | ||||||
| 1084 | |||||||
| 1085 | g_return_val_if_fail (E_IS_CAL_BACKEND_WEBDAV_NOTES (meta_backend), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_99 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((meta_backend)); GType __t = ((e_cal_backend_webdav_notes_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_99 = 1; _g_boolean_var_99; }), 1) )) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "E_IS_CAL_BACKEND_WEBDAV_NOTES (meta_backend)" ); return ((0)); } } while (0); | ||||||
| |||||||
| 1086 | g_return_val_if_fail (instances != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_100 = 0; if (instances != ((void*)0)) _g_boolean_var_100 = 1; _g_boolean_var_100 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "instances != NULL"); return (( 0)); } } while (0); | ||||||
| 1087 | g_return_val_if_fail (instances->data != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_101 = 0; if (instances->data != ((void*)0)) _g_boolean_var_101 = 1; _g_boolean_var_101; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes", ((const char*) (__func__)), "instances->data != NULL" ); return ((0)); } } while (0); | ||||||
| 1088 | g_return_val_if_fail (instances->next == NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_102 = 0; if (instances->next == ((void*)0)) _g_boolean_var_102 = 1; _g_boolean_var_102; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes", ((const char*) (__func__)), "instances->next == NULL" ); return ((0)); } } while (0); | ||||||
| 1089 | g_return_val_if_fail (out_new_uid, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_103 = 0; if (out_new_uid) _g_boolean_var_103 = 1; _g_boolean_var_103 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "out_new_uid"); return ((0)); } } while (0); | ||||||
| 1090 | g_return_val_if_fail (out_new_extra, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_104 = 0; if (out_new_extra) _g_boolean_var_104 = 1; _g_boolean_var_104 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "out_new_extra"); return ((0)); } } while (0); | ||||||
| 1091 | |||||||
| 1092 | icomp = e_cal_component_get_icalcomponent (instances->data); | ||||||
| 1093 | g_return_val_if_fail (i_cal_component_isa (icomp) == I_CAL_VJOURNAL_COMPONENT, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_105 = 0; if (i_cal_component_isa (icomp) == I_CAL_VJOURNAL_COMPONENT ) _g_boolean_var_105 = 1; _g_boolean_var_105; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes", (( const char*) (__func__)), "i_cal_component_isa (icomp) == I_CAL_VJOURNAL_COMPONENT" ); return ((0)); } } while (0); | ||||||
| 1094 | |||||||
| 1095 | cbnotes = E_CAL_BACKEND_WEBDAV_NOTES (meta_backend)((((ECalBackendWebDAVNotes*) (void *) ((meta_backend))))); | ||||||
| 1096 | |||||||
| 1097 | description = i_cal_component_get_description (icomp); | ||||||
| 1098 | etag = e_cal_util_component_dup_x_property (icomp, E_WEBDAV_NOTES_X_ETAG"X-EVOLUTION-WEBDAV-NOTES-ETAG"); | ||||||
| 1099 | uid = i_cal_component_get_uid (icomp); | ||||||
| 1100 | |||||||
| 1101 | webdav = ecb_webdav_notes_ref_session (cbnotes); | ||||||
| 1102 | |||||||
| 1103 | if (uid && (!overwrite_existing || (extra && *extra))) { | ||||||
| 1104 | gchar *new_extra = NULL((void*)0), *new_etag = NULL((void*)0); | ||||||
| 1105 | gchar *base_filename, *expected_filename = NULL((void*)0); | ||||||
| 1106 | gboolean force_write = FALSE(0), new_filename = FALSE(0); | ||||||
| 1107 | guint counter = 1; | ||||||
| 1108 | const gchar *use_ext = NULL((void*)0), *use_ext_num_suffix = NULL((void*)0), *use_content_type = NULL((void*)0); | ||||||
| 1109 | gint ext_len = 0; | ||||||
| 1110 | |||||||
| 1111 | base_filename = ecb_webdav_notes_construct_base_filename (description); | ||||||
| 1112 | if (!ecb_webdav_notes_has_supported_extension (uid, &ext_len, &use_ext, &use_ext_num_suffix, &use_content_type)) { | ||||||
| 1113 | ESource *source; | ||||||
| 1114 | ESourceWebDAVNotes *notes_extension; | ||||||
| 1115 | const gchar *default_ext; | ||||||
| 1116 | |||||||
| 1117 | source = e_backend_get_source (E_BACKEND (meta_backend)((((EBackend*) (void *) ((meta_backend)))))); | ||||||
| 1118 | notes_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_NOTES"WebDAV Notes"); | ||||||
| 1119 | |||||||
| 1120 | e_source_extension_property_lock (E_SOURCE_EXTENSION (notes_extension)((((ESourceExtension*) (void *) ((notes_extension)))))); | ||||||
| 1121 | default_ext = e_source_webdav_notes_get_default_ext (notes_extension); | ||||||
| 1122 | |||||||
| 1123 | if (!ecb_webdav_notes_has_supported_extension (default_ext, &ext_len, &use_ext, &use_ext_num_suffix, &use_content_type)) { | ||||||
| 1124 | /* Fallback to the markdown format in case of broken setup */ | ||||||
| 1125 | g_warn_if_fail (ecb_webdav_notes_has_supported_extension (".md", &ext_len, &use_ext, &use_ext_num_suffix, &use_content_type))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_106 = 0; if (ecb_webdav_notes_has_supported_extension (".md", & ext_len, &use_ext, &use_ext_num_suffix, &use_content_type )) _g_boolean_var_106 = 1; _g_boolean_var_106; }), 1)) ; else g_warn_message ("e-cal-backend-webdav-notes", "/builds/GNOME/evolution-data-server/src/calendar/backends/webdav-notes/e-cal-backend-webdav-notes.c" , 1125, ((const char*) (__func__)), "ecb_webdav_notes_has_supported_extension (\".md\", &ext_len, &use_ext, &use_ext_num_suffix, &use_content_type)" ); } while (0); | ||||||
| 1126 | } | ||||||
| 1127 | |||||||
| 1128 | e_source_extension_property_unlock (E_SOURCE_EXTENSION (notes_extension)((((ESourceExtension*) (void *) ((notes_extension)))))); | ||||||
| 1129 | } | ||||||
| 1130 | |||||||
| 1131 | expected_filename = g_strconcat (base_filename, use_ext, NULL((void*)0)); | ||||||
| 1132 | |||||||
| 1133 | if (overwrite_existing
| ||||||
| 1134 | switch (conflict_resolution) { | ||||||
| 1135 | case E_CONFLICT_RESOLUTION_FAIL: | ||||||
| 1136 | case E_CONFLICT_RESOLUTION_USE_NEWER: | ||||||
| 1137 | case E_CONFLICT_RESOLUTION_KEEP_SERVER: | ||||||
| 1138 | case E_CONFLICT_RESOLUTION_WRITE_COPY: | ||||||
| 1139 | break; | ||||||
| 1140 | case E_CONFLICT_RESOLUTION_KEEP_LOCAL: | ||||||
| 1141 | force_write = TRUE(!(0)); | ||||||
| 1142 | break; | ||||||
| 1143 | } | ||||||
| 1144 | } | ||||||
| 1145 | |||||||
| 1146 | new_filename = g_strcmp0 (expected_filename, uid) != 0; | ||||||
| 1147 | |||||||
| 1148 | /* Checks whether the saved file on the server is already with the "(nnn)" suffix */ | ||||||
| 1149 | if (new_filename
| ||||||
| 1150 | g_str_has_suffix (uid, use_ext_num_suffix)(__builtin_constant_p (use_ext_num_suffix)? __extension__ ({ const char * const __str = (uid); const char * const __suffix = (use_ext_num_suffix ); gboolean __result = (0); if (__builtin_expect (__extension__ ({ int _g_boolean_var_107 = 0; if (__str == ((void*)0) || __suffix == ((void*)0)) _g_boolean_var_107 = 1; _g_boolean_var_107; } ), 0)) __result = (g_str_has_suffix) (__str, __suffix); else { const size_t __str_len = strlen (((__str) + !(__str))); const size_t __suffix_len = strlen (((__suffix) + !(__suffix))); if (__str_len >= __suffix_len) __result = memcmp (__str + __str_len - __suffix_len, ((__suffix) + !(__suffix)), __suffix_len) == 0; } __result; }) : (g_str_has_suffix) (uid, use_ext_num_suffix ) ) && g_ascii_strncasecmp (uid, expected_filename, strlen (expected_filename) - ext_len) == 0) { | ||||||
| 1151 | gint ii = strlen (expected_filename) - ext_len; | ||||||
| 1152 | |||||||
| 1153 | if (uid[ii] == ' ' && uid[ii + 1] == '(') { | ||||||
| 1154 | ii += 2; | ||||||
| 1155 | |||||||
| 1156 | while (uid[ii] >= '0' && uid[ii] <= '9') | ||||||
| 1157 | ii++; | ||||||
| 1158 | |||||||
| 1159 | if (g_strcmp0 (uid + ii, use_ext_num_suffix) == 0) | ||||||
| 1160 | new_filename = FALSE(0); | ||||||
| 1161 | } | ||||||
| 1162 | } | ||||||
| 1163 | |||||||
| 1164 | if (!extra
| ||||||
| 1165 | href = ecb_webdav_notes_uid_to_uri (cbnotes, expected_filename); | ||||||
| 1166 | uid = expected_filename; | ||||||
| 1167 | force_write = FALSE(0); | ||||||
| 1168 | } | ||||||
| 1169 | |||||||
| 1170 | do { | ||||||
| 1171 | if (!counter
| ||||||
| 1172 | break; | ||||||
| 1173 | |||||||
| 1174 | g_clear_error (&local_error); | ||||||
| 1175 | |||||||
| 1176 | if (counter
| ||||||
| 1177 | g_free (expected_filename); | ||||||
| 1178 | expected_filename = g_strdup_printf ("%s (%u)%s", base_filename, counter, use_ext); | ||||||
| 1179 | |||||||
| 1180 | g_free (href); | ||||||
| 1181 | href = ecb_webdav_notes_uid_to_uri (cbnotes, expected_filename); | ||||||
| 1182 | |||||||
| 1183 | uid = expected_filename; | ||||||
| 1184 | } | ||||||
| 1185 | |||||||
| 1186 | success = e_webdav_session_put_data_sync (webdav, (!new_filename
| ||||||
| 1187 | force_write
| ||||||
| 1188 | NULL((void*)0), description
| ||||||
| 1189 | |||||||
| 1190 | counter++; | ||||||
| 1191 | } while (!success && new_filename && !g_cancellable_is_cancelled (cancellable) && | ||||||
| 1192 | g_error_matches (local_error, E_SOUP_SESSION_ERROR(e_soup_session_error_quark()), SOUP_STATUS_PRECONDITION_FAILED)); | ||||||
| 1193 | |||||||
| 1194 | if (success
| ||||||
| 1195 | /* The name on the server changed, remove the old file */ | ||||||
| 1196 | e_webdav_session_delete_sync (webdav, extra, E_WEBDAV_DEPTH_THIS"0", etag, cancellable, NULL((void*)0)); | ||||||
| 1197 | } | ||||||
| 1198 | |||||||
| 1199 | if (success
| ||||||
| 1200 | ICalComponent *icomp_copy = NULL((void*)0); | ||||||
| 1201 | |||||||
| 1202 | /* Only if both are returned and it's not a weak ETag */ | ||||||
| 1203 | if (new_extra && *new_extra && new_etag && *new_etag && | ||||||
| 1204 | g_ascii_strncasecmp (new_etag, "W/", 2) != 0) { | ||||||
| 1205 | gchar *tmp = NULL((void*)0); | ||||||
| 1206 | glong now = (glong) time (NULL((void*)0)); | ||||||
| 1207 | gint len = 0; | ||||||
| 1208 | |||||||
| 1209 | if (ecb_webdav_notes_has_supported_extension (uid, &len, NULL((void*)0), NULL((void*)0), NULL((void*)0))) | ||||||
| 1210 | tmp = g_strndup (uid, strlen (uid) - len); | ||||||
| |||||||
| 1211 | |||||||
| 1212 | icomp_copy = ecb_webdav_notes_new_icomp (now, now, uid, new_etag, | ||||||
| 1213 | tmp ? tmp : uid, description); | ||||||
| 1214 | |||||||
| 1215 | g_free (tmp); | ||||||
| 1216 | } else if (out_new_extra && new_extra && *new_extra) { | ||||||
| 1217 | gchar *is_markdown_str; | ||||||
| 1218 | |||||||
| 1219 | is_markdown_str = e_cal_util_component_dup_x_property (icomp, E_WEBDAV_NOTES_X_IS_MARKDOWN"X-EVOLUTION-IS-MARKDOWN"); | ||||||
| 1220 | |||||||
| 1221 | /* add or remove is-markdown notice, if needed */ | ||||||
| 1222 | if (g_str_has_suffix (uid, ".md")(__builtin_constant_p (".md")? __extension__ ({ const char * const __str = (uid); const char * const __suffix = (".md"); gboolean __result = (0); if (__builtin_expect (__extension__ ({ int _g_boolean_var_108 = 0; if (__str == ((void*)0) || __suffix == ((void*)0)) _g_boolean_var_108 = 1; _g_boolean_var_108; }), 0)) __result = (g_str_has_suffix ) (__str, __suffix); else { const size_t __str_len = strlen ( ((__str) + !(__str))); const size_t __suffix_len = strlen ((( __suffix) + !(__suffix))); if (__str_len >= __suffix_len) __result = memcmp (__str + __str_len - __suffix_len, ((__suffix) + !( __suffix)), __suffix_len) == 0; } __result; }) : (g_str_has_suffix ) (uid, ".md") )) { | ||||||
| 1223 | if (g_strcmp0 (is_markdown_str, "1") != 0) { | ||||||
| 1224 | icomp_copy = i_cal_component_clone (icomp); | ||||||
| 1225 | e_cal_util_component_set_x_property (icomp_copy, E_WEBDAV_NOTES_X_IS_MARKDOWN"X-EVOLUTION-IS-MARKDOWN", "1"); | ||||||
| 1226 | } | ||||||
| 1227 | } else if (g_strcmp0 (is_markdown_str, "1") == 0) { | ||||||
| 1228 | icomp_copy = i_cal_component_clone (icomp); | ||||||
| 1229 | while (e_cal_util_component_remove_x_property (icomp_copy, E_WEBDAV_NOTES_X_IS_MARKDOWN"X-EVOLUTION-IS-MARKDOWN")) { | ||||||
| 1230 | /* remove all */ | ||||||
| 1231 | } | ||||||
| 1232 | } | ||||||
| 1233 | |||||||
| 1234 | g_free (is_markdown_str); | ||||||
| 1235 | } | ||||||
| 1236 | |||||||
| 1237 | if (icomp_copy != NULL((void*)0)) { | ||||||
| 1238 | gchar *tmp, *ical_string; | ||||||
| 1239 | |||||||
| 1240 | ical_string = i_cal_component_as_ical_string (icomp_copy); | ||||||
| 1241 | |||||||
| 1242 | /* Encodes the href and the component into one string, which | ||||||
| 1243 | will be decoded in the load function */ | ||||||
| 1244 | tmp = g_strconcat (new_extra, "\n", ical_string, NULL((void*)0)); | ||||||
| 1245 | g_free (new_extra); | ||||||
| 1246 | new_extra = tmp; | ||||||
| 1247 | |||||||
| 1248 | g_object_unref (icomp_copy); | ||||||
| 1249 | g_free (ical_string); | ||||||
| 1250 | } | ||||||
| 1251 | |||||||
| 1252 | /* To read the component back, either from the new_extra | ||||||
| 1253 | or from the server, because the server could change it */ | ||||||
| 1254 | *out_new_uid = g_strdup (uid)g_strdup_inline (uid); | ||||||
| 1255 | |||||||
| 1256 | if (out_new_extra) | ||||||
| 1257 | *out_new_extra = new_extra; | ||||||
| 1258 | else | ||||||
| 1259 | g_free (new_extra); | ||||||
| 1260 | } | ||||||
| 1261 | |||||||
| 1262 | g_free (base_filename); | ||||||
| 1263 | g_free (expected_filename); | ||||||
| 1264 | g_free (new_etag); | ||||||
| 1265 | } else if (uid) { | ||||||
| 1266 | ECalCache *cache; | ||||||
| 1267 | |||||||
| 1268 | cache = e_cal_meta_backend_ref_cache (meta_backend); | ||||||
| 1269 | success = FALSE(0); | ||||||
| 1270 | |||||||
| 1271 | g_propagate_error (error, e_cal_client_error_create_fmt (E_CAL_CLIENT_ERROR_INVALID_OBJECT, | ||||||
| 1272 | _("Missing information about component URL, local cache is possibly incomplete or broken. You can try to remove it and restart background evolution-data-server processes. Cache file: %s")((char *) g_dgettext ("evolution-data-server", "Missing information about component URL, local cache is possibly incomplete or broken. You can try to remove it and restart background evolution-data-server processes. Cache file: %s" )), | ||||||
| 1273 | e_cache_get_filename (E_CACHE (cache)((((ECache*) (void *) ((cache)))))))); | ||||||
| 1274 | |||||||
| 1275 | g_clear_object (&cache)do { _Static_assert (sizeof *((&cache)) == sizeof (gpointer ), "Expression evaluates to false"); __typeof__ (((&cache ))) _pp = ((&cache)); __typeof__ (*((&cache))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while (0); | ||||||
| 1276 | } else { | ||||||
| 1277 | success = FALSE(0); | ||||||
| 1278 | g_propagate_error (error, ECC_ERROR (E_CAL_CLIENT_ERROR_INVALID_OBJECT)e_cal_client_error_create (E_CAL_CLIENT_ERROR_INVALID_OBJECT, ((void*)0))); | ||||||
| 1279 | } | ||||||
| 1280 | |||||||
| 1281 | g_free (href); | ||||||
| 1282 | g_free (etag); | ||||||
| 1283 | |||||||
| 1284 | if (overwrite_existing && g_error_matches (local_error, E_SOUP_SESSION_ERROR(e_soup_session_error_quark()), SOUP_STATUS_PRECONDITION_FAILED)) { | ||||||
| 1285 | g_clear_error (&local_error); | ||||||
| 1286 | |||||||
| 1287 | /* Pretend success when using the serer version on conflict, | ||||||
| 1288 | the component will be updated during the refresh */ | ||||||
| 1289 | if (conflict_resolution == E_CONFLICT_RESOLUTION_KEEP_SERVER) | ||||||
| 1290 | success = TRUE(!(0)); | ||||||
| 1291 | else | ||||||
| 1292 | local_error = EC_ERROR (E_CLIENT_ERROR_OUT_OF_SYNC)e_client_error_create (E_CLIENT_ERROR_OUT_OF_SYNC, ((void*)0) ); | ||||||
| 1293 | } | ||||||
| 1294 | |||||||
| 1295 | if (local_error) { | ||||||
| 1296 | ecb_webdav_notes_check_credentials_error (cbnotes, webdav, local_error); | ||||||
| 1297 | g_propagate_error (error, local_error); | ||||||
| 1298 | } | ||||||
| 1299 | |||||||
| 1300 | g_clear_object (&webdav)do { _Static_assert (sizeof *((&webdav)) == sizeof (gpointer ), "Expression evaluates to false"); __typeof__ (((&webdav ))) _pp = ((&webdav)); __typeof__ (*((&webdav))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr) ; } while (0); | ||||||
| 1301 | |||||||
| 1302 | return success; | ||||||
| 1303 | } | ||||||
| 1304 | |||||||
| 1305 | static gboolean | ||||||
| 1306 | ecb_webdav_notes_remove_component_sync (ECalMetaBackend *meta_backend, | ||||||
| 1307 | EConflictResolution conflict_resolution, | ||||||
| 1308 | const gchar *uid, | ||||||
| 1309 | const gchar *extra, | ||||||
| 1310 | const gchar *object, | ||||||
| 1311 | ECalOperationFlags opflags, | ||||||
| 1312 | GCancellable *cancellable, | ||||||
| 1313 | GError **error) | ||||||
| 1314 | { | ||||||
| 1315 | ECalBackendWebDAVNotes *cbnotes; | ||||||
| 1316 | EWebDAVSession *webdav; | ||||||
| 1317 | ICalComponent *icomp; | ||||||
| 1318 | gchar *etag = NULL((void*)0); | ||||||
| 1319 | gboolean success; | ||||||
| 1320 | GError *local_error = NULL((void*)0); | ||||||
| 1321 | |||||||
| 1322 | g_return_val_if_fail (E_IS_CAL_BACKEND_WEBDAV_NOTES (meta_backend), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_109 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((meta_backend)); GType __t = ((e_cal_backend_webdav_notes_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_109 = 1; _g_boolean_var_109; }), 1 ))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "E_IS_CAL_BACKEND_WEBDAV_NOTES (meta_backend)" ); return ((0)); } } while (0); | ||||||
| 1323 | g_return_val_if_fail (uid != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_110 = 0; if (uid != ((void*)0)) _g_boolean_var_110 = 1; _g_boolean_var_110 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "uid != NULL"); return ((0)); } } while (0); | ||||||
| 1324 | g_return_val_if_fail (object != NULL, FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_111 = 0; if (object != ((void*)0)) _g_boolean_var_111 = 1; _g_boolean_var_111 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "object != NULL"); return ((0)) ; } } while (0); | ||||||
| 1325 | |||||||
| 1326 | cbnotes = E_CAL_BACKEND_WEBDAV_NOTES (meta_backend)((((ECalBackendWebDAVNotes*) (void *) ((meta_backend))))); | ||||||
| 1327 | |||||||
| 1328 | if (!extra || !*extra) { | ||||||
| 1329 | g_propagate_error (error, ECC_ERROR (E_CAL_CLIENT_ERROR_INVALID_OBJECT)e_cal_client_error_create (E_CAL_CLIENT_ERROR_INVALID_OBJECT, ((void*)0))); | ||||||
| 1330 | return FALSE(0); | ||||||
| 1331 | } | ||||||
| 1332 | |||||||
| 1333 | icomp = i_cal_component_new_from_string (object); | ||||||
| 1334 | if (!icomp) { | ||||||
| 1335 | g_propagate_error (error, ECC_ERROR (E_CAL_CLIENT_ERROR_INVALID_OBJECT)e_cal_client_error_create (E_CAL_CLIENT_ERROR_INVALID_OBJECT, ((void*)0))); | ||||||
| 1336 | return FALSE(0); | ||||||
| 1337 | } | ||||||
| 1338 | |||||||
| 1339 | if (conflict_resolution == E_CONFLICT_RESOLUTION_FAIL) | ||||||
| 1340 | etag = e_cal_util_component_dup_x_property (icomp, E_WEBDAV_NOTES_X_ETAG"X-EVOLUTION-WEBDAV-NOTES-ETAG"); | ||||||
| 1341 | |||||||
| 1342 | webdav = ecb_webdav_notes_ref_session (cbnotes); | ||||||
| 1343 | |||||||
| 1344 | success = e_webdav_session_delete_sync (webdav, extra, | ||||||
| 1345 | NULL((void*)0), etag, cancellable, &local_error); | ||||||
| 1346 | |||||||
| 1347 | g_object_unref (icomp); | ||||||
| 1348 | g_free (etag); | ||||||
| 1349 | |||||||
| 1350 | /* Ignore not found errors, this was a delete and the resource is gone. | ||||||
| 1351 | It can be that it had been deleted on the server by other application. */ | ||||||
| 1352 | if (g_error_matches (local_error, E_SOUP_SESSION_ERROR(e_soup_session_error_quark()), SOUP_STATUS_NOT_FOUND)) { | ||||||
| 1353 | g_clear_error (&local_error); | ||||||
| 1354 | success = TRUE(!(0)); | ||||||
| 1355 | } else if (g_error_matches (local_error, E_SOUP_SESSION_ERROR(e_soup_session_error_quark()), SOUP_STATUS_PRECONDITION_FAILED)) { | ||||||
| 1356 | g_clear_error (&local_error); | ||||||
| 1357 | |||||||
| 1358 | /* Pretend success when using the serer version on conflict, | ||||||
| 1359 | the component will be updated during the refresh */ | ||||||
| 1360 | if (conflict_resolution == E_CONFLICT_RESOLUTION_KEEP_SERVER) | ||||||
| 1361 | success = TRUE(!(0)); | ||||||
| 1362 | else | ||||||
| 1363 | local_error = EC_ERROR (E_CLIENT_ERROR_OUT_OF_SYNC)e_client_error_create (E_CLIENT_ERROR_OUT_OF_SYNC, ((void*)0) ); | ||||||
| 1364 | } | ||||||
| 1365 | |||||||
| 1366 | if (local_error) { | ||||||
| 1367 | ecb_webdav_notes_check_credentials_error (cbnotes, webdav, local_error); | ||||||
| 1368 | g_propagate_error (error, local_error); | ||||||
| 1369 | } | ||||||
| 1370 | |||||||
| 1371 | g_clear_object (&webdav)do { _Static_assert (sizeof *((&webdav)) == sizeof (gpointer ), "Expression evaluates to false"); __typeof__ (((&webdav ))) _pp = ((&webdav)); __typeof__ (*((&webdav))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr) ; } while (0); | ||||||
| 1372 | |||||||
| 1373 | return success; | ||||||
| 1374 | } | ||||||
| 1375 | |||||||
| 1376 | static gboolean | ||||||
| 1377 | ecb_webdav_notes_get_ssl_error_details (ECalMetaBackend *meta_backend, | ||||||
| 1378 | gchar **out_certificate_pem, | ||||||
| 1379 | GTlsCertificateFlags *out_certificate_errors) | ||||||
| 1380 | { | ||||||
| 1381 | ECalBackendWebDAVNotes *cbnotes; | ||||||
| 1382 | EWebDAVSession *webdav; | ||||||
| 1383 | gboolean res; | ||||||
| 1384 | |||||||
| 1385 | g_return_val_if_fail (E_IS_CAL_BACKEND_WEBDAV_NOTES (meta_backend), FALSE)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_112 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((meta_backend)); GType __t = ((e_cal_backend_webdav_notes_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_112 = 1; _g_boolean_var_112; }), 1 ))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "E_IS_CAL_BACKEND_WEBDAV_NOTES (meta_backend)" ); return ((0)); } } while (0); | ||||||
| 1386 | |||||||
| 1387 | cbnotes = E_CAL_BACKEND_WEBDAV_NOTES (meta_backend)((((ECalBackendWebDAVNotes*) (void *) ((meta_backend))))); | ||||||
| 1388 | webdav = ecb_webdav_notes_ref_session (cbnotes); | ||||||
| 1389 | |||||||
| 1390 | if (!webdav) | ||||||
| 1391 | return FALSE(0); | ||||||
| 1392 | |||||||
| 1393 | res = e_soup_session_get_ssl_error_details (E_SOUP_SESSION (webdav)((((ESoupSession*) (void *) ((webdav))))), out_certificate_pem, out_certificate_errors); | ||||||
| 1394 | |||||||
| 1395 | g_clear_object (&webdav)do { _Static_assert (sizeof *((&webdav)) == sizeof (gpointer ), "Expression evaluates to false"); __typeof__ (((&webdav ))) _pp = ((&webdav)); __typeof__ (*((&webdav))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr) ; } while (0); | ||||||
| 1396 | |||||||
| 1397 | return res; | ||||||
| 1398 | } | ||||||
| 1399 | |||||||
| 1400 | static gchar * | ||||||
| 1401 | ecb_webdav_notes_get_usermail (ECalBackendWebDAVNotes *cbnotes) | ||||||
| 1402 | { | ||||||
| 1403 | ESource *source; | ||||||
| 1404 | ESourceAuthentication *auth_extension; | ||||||
| 1405 | ESourceWebdav *webdav_extension; | ||||||
| 1406 | const gchar *extension_name; | ||||||
| 1407 | gchar *usermail; | ||||||
| 1408 | gchar *username; | ||||||
| 1409 | gchar *res = NULL((void*)0); | ||||||
| 1410 | |||||||
| 1411 | g_return_val_if_fail (E_IS_CAL_BACKEND_WEBDAV_NOTES (cbnotes), NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_113 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((cbnotes)); GType __t = ((e_cal_backend_webdav_notes_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_113 = 1; _g_boolean_var_113; }), 1 ))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "E_IS_CAL_BACKEND_WEBDAV_NOTES (cbnotes)" ); return (((void*)0)); } } while (0); | ||||||
| 1412 | |||||||
| 1413 | source = e_backend_get_source (E_BACKEND (cbnotes)((((EBackend*) (void *) ((cbnotes)))))); | ||||||
| 1414 | |||||||
| 1415 | extension_name = E_SOURCE_EXTENSION_WEBDAV_BACKEND"WebDAV Backend"; | ||||||
| 1416 | webdav_extension = e_source_get_extension (source, extension_name); | ||||||
| 1417 | |||||||
| 1418 | /* This will never return an empty string. */ | ||||||
| 1419 | usermail = e_source_webdav_dup_email_address (webdav_extension); | ||||||
| 1420 | |||||||
| 1421 | if (usermail) | ||||||
| 1422 | return usermail; | ||||||
| 1423 | |||||||
| 1424 | extension_name = E_SOURCE_EXTENSION_AUTHENTICATION"Authentication"; | ||||||
| 1425 | auth_extension = e_source_get_extension (source, extension_name); | ||||||
| 1426 | username = e_source_authentication_dup_user (auth_extension); | ||||||
| 1427 | |||||||
| 1428 | if (username && strchr (username, '@') && strrchr (username, '.') > strchr (username, '@')) { | ||||||
| 1429 | res = username; | ||||||
| 1430 | username = NULL((void*)0); | ||||||
| 1431 | } | ||||||
| 1432 | |||||||
| 1433 | g_free (username); | ||||||
| 1434 | |||||||
| 1435 | return res; | ||||||
| 1436 | } | ||||||
| 1437 | |||||||
| 1438 | static gchar * | ||||||
| 1439 | ecb_webdav_notes_get_backend_property (ECalBackend *backend, | ||||||
| 1440 | const gchar *prop_name) | ||||||
| 1441 | { | ||||||
| 1442 | g_return_val_if_fail (prop_name != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_114 = 0; if (prop_name != ((void*)0)) _g_boolean_var_114 = 1; _g_boolean_var_114 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "prop_name != NULL"); return (( (void*)0)); } } while (0); | ||||||
| 1443 | |||||||
| 1444 | if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_CAPABILITIES)(strcmp ((const char *) (prop_name), (const char *) ("capabilities" )) == 0)) { | ||||||
| 1445 | return g_strjoin (",", | ||||||
| 1446 | e_cal_meta_backend_get_capabilities (E_CAL_META_BACKEND (backend)((((ECalMetaBackend*) (void *) ((backend)))))), | ||||||
| 1447 | E_CAL_STATIC_CAPABILITY_REFRESH_SUPPORTED"refresh-supported", | ||||||
| 1448 | E_CAL_STATIC_CAPABILITY_SIMPLE_MEMO"simple-memo", | ||||||
| 1449 | NULL((void*)0)); | ||||||
| 1450 | } else if (g_str_equal (prop_name, E_CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS)(strcmp ((const char *) (prop_name), (const char *) ("cal-email-address" )) == 0) || | ||||||
| 1451 | g_str_equal (prop_name, E_CAL_BACKEND_PROPERTY_ALARM_EMAIL_ADDRESS)(strcmp ((const char *) (prop_name), (const char *) ("alarm-email-address" )) == 0)) { | ||||||
| 1452 | return ecb_webdav_notes_get_usermail (E_CAL_BACKEND_WEBDAV_NOTES (backend)((((ECalBackendWebDAVNotes*) (void *) ((backend)))))); | ||||||
| 1453 | } | ||||||
| 1454 | |||||||
| 1455 | /* Chain up to parent's method. */ | ||||||
| 1456 | return E_CAL_BACKEND_CLASS (e_cal_backend_webdav_notes_parent_class)((((ECalBackendClass*) (void *) ((e_cal_backend_webdav_notes_parent_class )))))->impl_get_backend_property (backend, prop_name); | ||||||
| 1457 | } | ||||||
| 1458 | |||||||
| 1459 | static void | ||||||
| 1460 | ecb_webdav_notes_notify_property_changed_cb (GObject *object, | ||||||
| 1461 | GParamSpec *param, | ||||||
| 1462 | gpointer user_data) | ||||||
| 1463 | { | ||||||
| 1464 | ECalBackendWebDAVNotes *cbnotes = user_data; | ||||||
| 1465 | ECalBackend *cal_backend; | ||||||
| 1466 | gboolean email_address_changed; | ||||||
| 1467 | gchar *value; | ||||||
| 1468 | |||||||
| 1469 | g_return_if_fail (E_IS_CAL_BACKEND_WEBDAV_NOTES (cbnotes))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_115 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((cbnotes)); GType __t = ((e_cal_backend_webdav_notes_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_115 = 1; _g_boolean_var_115; }), 1 ))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "E_IS_CAL_BACKEND_WEBDAV_NOTES (cbnotes)" ); return; } } while (0); | ||||||
| 1470 | |||||||
| 1471 | cal_backend = E_CAL_BACKEND (cbnotes)((((ECalBackend*) (void *) ((cbnotes))))); | ||||||
| 1472 | |||||||
| 1473 | email_address_changed = param && g_strcmp0 (param->name, "email-address") == 0; | ||||||
| 1474 | |||||||
| 1475 | if (email_address_changed) { | ||||||
| 1476 | value = ecb_webdav_notes_get_backend_property (cal_backend, E_CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS"cal-email-address"); | ||||||
| 1477 | e_cal_backend_notify_property_changed (cal_backend, E_CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS"cal-email-address", value); | ||||||
| 1478 | e_cal_backend_notify_property_changed (cal_backend, E_CAL_BACKEND_PROPERTY_ALARM_EMAIL_ADDRESS"alarm-email-address", value); | ||||||
| 1479 | g_free (value); | ||||||
| 1480 | } | ||||||
| 1481 | } | ||||||
| 1482 | |||||||
| 1483 | static void | ||||||
| 1484 | ecb_webdav_notes_refresh_sync (ECalBackendSync *sync_backend, | ||||||
| 1485 | EDataCal *cal, | ||||||
| 1486 | GCancellable *cancellable, | ||||||
| 1487 | GError **error) | ||||||
| 1488 | { | ||||||
| 1489 | ECalBackendWebDAVNotes *cbnotes; | ||||||
| 1490 | |||||||
| 1491 | g_return_if_fail (E_IS_CAL_BACKEND_WEBDAV_NOTES (sync_backend))do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_116 = 0; if ((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((sync_backend)); GType __t = ((e_cal_backend_webdav_notes_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) _g_boolean_var_116 = 1; _g_boolean_var_116; }), 1 ))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "E_IS_CAL_BACKEND_WEBDAV_NOTES (sync_backend)" ); return; } } while (0); | ||||||
| 1492 | |||||||
| 1493 | cbnotes = E_CAL_BACKEND_WEBDAV_NOTES (sync_backend)((((ECalBackendWebDAVNotes*) (void *) ((sync_backend))))); | ||||||
| 1494 | cbnotes->priv->been_connected = FALSE(0); | ||||||
| 1495 | |||||||
| 1496 | /* Chain up to parent's method. */ | ||||||
| 1497 | E_CAL_BACKEND_SYNC_CLASS (e_cal_backend_webdav_notes_parent_class)((((ECalBackendSyncClass*) (void *) ((e_cal_backend_webdav_notes_parent_class )))))->refresh_sync (sync_backend, cal, cancellable, error); | ||||||
| 1498 | } | ||||||
| 1499 | |||||||
| 1500 | static gchar * | ||||||
| 1501 | ecb_webdav_notes_dup_component_revision_cb (ECalCache *cal_cache, | ||||||
| 1502 | ICalComponent *icomp) | ||||||
| 1503 | { | ||||||
| 1504 | g_return_val_if_fail (icomp != NULL, NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_117 = 0; if (icomp != ((void*)0)) _g_boolean_var_117 = 1; _g_boolean_var_117 ; }), 1))) { } else { g_return_if_fail_warning ("e-cal-backend-webdav-notes" , ((const char*) (__func__)), "icomp != NULL"); return (((void *)0)); } } while (0); | ||||||
| 1505 | |||||||
| 1506 | return e_cal_util_component_dup_x_property (icomp, E_WEBDAV_NOTES_X_ETAG"X-EVOLUTION-WEBDAV-NOTES-ETAG"); | ||||||
| 1507 | } | ||||||
| 1508 | |||||||
| 1509 | static void | ||||||
| 1510 | e_cal_backend_webdav_notes_constructed (GObject *object) | ||||||
| 1511 | { | ||||||
| 1512 | ECalBackendWebDAVNotes *cbnotes = E_CAL_BACKEND_WEBDAV_NOTES (object)((((ECalBackendWebDAVNotes*) (void *) ((object))))); | ||||||
| 1513 | ECalCache *cal_cache; | ||||||
| 1514 | ESource *source; | ||||||
| 1515 | ESourceWebdav *webdav_extension; | ||||||
| 1516 | |||||||
| 1517 | /* Chain up to parent's method. */ | ||||||
| 1518 | G_OBJECT_CLASS (e_cal_backend_webdav_notes_parent_class)((((GObjectClass*) (void *) ((e_cal_backend_webdav_notes_parent_class )))))->constructed (object); | ||||||
| 1519 | |||||||
| 1520 | cal_cache = e_cal_meta_backend_ref_cache (E_CAL_META_BACKEND (cbnotes)((((ECalMetaBackend*) (void *) ((cbnotes)))))); | ||||||
| 1521 | |||||||
| 1522 | g_signal_connect (cal_cache, "dup-component-revision",g_signal_connect_data ((cal_cache), ("dup-component-revision" ), (((GCallback) (ecb_webdav_notes_dup_component_revision_cb) )), (((void*)0)), ((void*)0), (GConnectFlags) 0) | ||||||
| 1523 | G_CALLBACK (ecb_webdav_notes_dup_component_revision_cb), NULL)g_signal_connect_data ((cal_cache), ("dup-component-revision" ), (((GCallback) (ecb_webdav_notes_dup_component_revision_cb) )), (((void*)0)), ((void*)0), (GConnectFlags) 0); | ||||||
| 1524 | |||||||
| 1525 | g_clear_object (&cal_cache)do { _Static_assert (sizeof *((&cal_cache)) == sizeof (gpointer ), "Expression evaluates to false"); __typeof__ (((&cal_cache ))) _pp = ((&cal_cache)); __typeof__ (*((&cal_cache)) ) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) ( _ptr); } while (0); | ||||||
| 1526 | |||||||
| 1527 | source = e_backend_get_source (E_BACKEND (cbnotes)((((EBackend*) (void *) ((cbnotes)))))); | ||||||
| 1528 | webdav_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND"WebDAV Backend"); | ||||||
| 1529 | |||||||
| 1530 | g_signal_connect_object (webdav_extension, "notify::email-address", | ||||||
| 1531 | G_CALLBACK (ecb_webdav_notes_notify_property_changed_cb)((GCallback) (ecb_webdav_notes_notify_property_changed_cb)), cbnotes, 0); | ||||||
| 1532 | } | ||||||
| 1533 | |||||||
| 1534 | static void | ||||||
| 1535 | e_cal_backend_webdav_notes_dispose (GObject *object) | ||||||
| 1536 | { | ||||||
| 1537 | ECalBackendWebDAVNotes *cbnotes = E_CAL_BACKEND_WEBDAV_NOTES (object)((((ECalBackendWebDAVNotes*) (void *) ((object))))); | ||||||
| 1538 | |||||||
| 1539 | g_mutex_lock (&cbnotes->priv->webdav_lock); | ||||||
| 1540 | g_clear_object (&cbnotes->priv->webdav)do { _Static_assert (sizeof *((&cbnotes->priv->webdav )) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (((&cbnotes->priv->webdav))) _pp = ((&cbnotes-> priv->webdav)); __typeof__ (*((&cbnotes->priv->webdav ))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref ) (_ptr); } while (0); | ||||||
| 1541 | g_clear_pointer (&cbnotes->priv->last_uri, g_uri_unref)do { _Static_assert (sizeof *(&cbnotes->priv->last_uri ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ ((&cbnotes->priv->last_uri)) _pp = (&cbnotes-> priv->last_uri); __typeof__ (*(&cbnotes->priv->last_uri )) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_uri_unref) (_ptr ); } while (0); | ||||||
| 1542 | g_mutex_unlock (&cbnotes->priv->webdav_lock); | ||||||
| 1543 | |||||||
| 1544 | /* Chain up to parent's method. */ | ||||||
| 1545 | G_OBJECT_CLASS (e_cal_backend_webdav_notes_parent_class)((((GObjectClass*) (void *) ((e_cal_backend_webdav_notes_parent_class )))))->dispose (object); | ||||||
| 1546 | } | ||||||
| 1547 | |||||||
| 1548 | static void | ||||||
| 1549 | e_cal_backend_webdav_notes_finalize (GObject *object) | ||||||
| 1550 | { | ||||||
| 1551 | ECalBackendWebDAVNotes *cbnotes = E_CAL_BACKEND_WEBDAV_NOTES (object)((((ECalBackendWebDAVNotes*) (void *) ((object))))); | ||||||
| 1552 | |||||||
| 1553 | g_mutex_clear (&cbnotes->priv->webdav_lock); | ||||||
| 1554 | |||||||
| 1555 | /* Chain up to parent's method. */ | ||||||
| 1556 | G_OBJECT_CLASS (e_cal_backend_webdav_notes_parent_class)((((GObjectClass*) (void *) ((e_cal_backend_webdav_notes_parent_class )))))->finalize (object); | ||||||
| 1557 | } | ||||||
| 1558 | |||||||
| 1559 | static void | ||||||
| 1560 | e_cal_backend_webdav_notes_init (ECalBackendWebDAVNotes *cbnotes) | ||||||
| 1561 | { | ||||||
| 1562 | cbnotes->priv = e_cal_backend_webdav_notes_get_instance_private (cbnotes); | ||||||
| 1563 | |||||||
| 1564 | g_mutex_init (&cbnotes->priv->webdav_lock); | ||||||
| 1565 | } | ||||||
| 1566 | |||||||
| 1567 | static void | ||||||
| 1568 | e_cal_backend_webdav_notes_class_init (ECalBackendWebDAVNotesClass *klass) | ||||||
| 1569 | { | ||||||
| 1570 | GObjectClass *object_class; | ||||||
| 1571 | ECalBackendClass *cal_backend_class; | ||||||
| 1572 | ECalBackendSyncClass *cal_backend_sync_class; | ||||||
| 1573 | ECalMetaBackendClass *cal_meta_backend_class; | ||||||
| 1574 | |||||||
| 1575 | cal_meta_backend_class = E_CAL_META_BACKEND_CLASS (klass)((((ECalMetaBackendClass*) (void *) ((klass))))); | ||||||
| 1576 | cal_meta_backend_class->connect_sync = ecb_webdav_notes_connect_sync; | ||||||
| 1577 | cal_meta_backend_class->disconnect_sync = ecb_webdav_notes_disconnect_sync; | ||||||
| 1578 | cal_meta_backend_class->get_changes_sync = ecb_webdav_notes_get_changes_sync; | ||||||
| 1579 | cal_meta_backend_class->list_existing_sync = ecb_webdav_notes_list_existing_sync; | ||||||
| 1580 | cal_meta_backend_class->load_component_sync = ecb_webdav_notes_load_component_sync; | ||||||
| 1581 | cal_meta_backend_class->save_component_sync = ecb_webdav_notes_save_component_sync; | ||||||
| 1582 | cal_meta_backend_class->remove_component_sync = ecb_webdav_notes_remove_component_sync; | ||||||
| 1583 | cal_meta_backend_class->get_ssl_error_details = ecb_webdav_notes_get_ssl_error_details; | ||||||
| 1584 | |||||||
| 1585 | cal_backend_sync_class = E_CAL_BACKEND_SYNC_CLASS (klass)((((ECalBackendSyncClass*) (void *) ((klass))))); | ||||||
| 1586 | cal_backend_sync_class->refresh_sync = ecb_webdav_notes_refresh_sync; | ||||||
| 1587 | |||||||
| 1588 | cal_backend_class = E_CAL_BACKEND_CLASS (klass)((((ECalBackendClass*) (void *) ((klass))))); | ||||||
| 1589 | cal_backend_class->impl_get_backend_property = ecb_webdav_notes_get_backend_property; | ||||||
| 1590 | |||||||
| 1591 | object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) ((klass))))); | ||||||
| 1592 | object_class->constructed = e_cal_backend_webdav_notes_constructed; | ||||||
| 1593 | object_class->dispose = e_cal_backend_webdav_notes_dispose; | ||||||
| 1594 | object_class->finalize = e_cal_backend_webdav_notes_finalize; | ||||||
| 1595 | } |