static void ebbm_contacts_open (EBookBackendMAPI *ebma, GCancellable *cancellable, gboolean only_if_exists, GError **perror) { ESource *source = e_backend_get_source (E_BACKEND (ebma)); ESourceMapiFolder *ext_mapi_folder; EBookBackendMAPIContactsPrivate *priv = ((EBookBackendMAPIContacts *) ebma)->priv; GError *err = NULL; if (e_book_backend_is_opened (E_BOOK_BACKEND (ebma))) { if (E_BOOK_BACKEND_MAPI_CLASS (e_book_backend_mapi_contacts_parent_class)->op_open) E_BOOK_BACKEND_MAPI_CLASS (e_book_backend_mapi_contacts_parent_class)->op_open (ebma, cancellable, only_if_exists, perror); return; } ext_mapi_folder = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER); priv->fid = e_source_mapi_folder_get_id (ext_mapi_folder); priv->is_public_folder = e_source_mapi_folder_is_public (ext_mapi_folder); priv->foreign_username = e_source_mapi_folder_dup_foreign_username (ext_mapi_folder); if (priv->foreign_username && !*priv->foreign_username) { g_free (priv->foreign_username); priv->foreign_username = NULL; } /* Chain up to parent's op_load_source() method. */ if (E_BOOK_BACKEND_MAPI_CLASS (e_book_backend_mapi_contacts_parent_class)->op_open) E_BOOK_BACKEND_MAPI_CLASS (e_book_backend_mapi_contacts_parent_class)->op_open (ebma, cancellable, only_if_exists, &err); if (err) g_propagate_error (perror, err); }
static EBookBackendSyncStatus e_book_backend_scalix_get_contact_list (EBookBackendSync * backend, EDataBook * book, guint32 opid, const char *query, GList ** contacts) { EBookBackendScalix *bs; EBookBackendScalixPrivate *priv; ScanContext context; bs = E_BOOK_BACKEND_SCALIX (backend); priv = E_BOOK_BACKEND_SCALIX_GET_PRIVATE (bs); context.sexp = e_book_backend_sexp_new (query); context.search_needed = query_is_search (query); context.backend = E_BOOK_BACKEND (bs); context.obj_list = NULL; context.return_objects = FALSE; scalix_container_foreach (priv->container, scan_objects, &context); *contacts = context.obj_list; if (*contacts == NULL) { return GNOME_Evolution_Addressbook_ContactNotFound; } return GNOME_Evolution_Addressbook_Success; }
static void set_backend_online_status (gpointer key, gpointer value, gpointer data) { EBookBackend *backend; backend = E_BOOK_BACKEND (value); e_book_backend_set_mode (backend, GPOINTER_TO_INT (data)); }
EBookBackend * e_book_backend_scalix_new (void) { EBookBackendScalix *backend; backend = g_object_new (E_TYPE_BOOK_BACKEND_SCALIX, NULL); return E_BOOK_BACKEND (backend); }
static void dump_active_server_map_entry (gpointer key, gpointer value, gpointer data) { char *uri; EBookBackend *backend; uri = key; backend = E_BOOK_BACKEND (value); g_message (" %s: %p", uri, backend); }
static gboolean go_offline (EBookBackendScalix * bs) { EBookBackendScalixPrivate *priv; EBookBackend *backend; gboolean res; backend = E_BOOK_BACKEND (bs); priv = E_BOOK_BACKEND_SCALIX_GET_PRIVATE (bs); res = scalix_container_set_online (priv->container, FALSE); return res; }
static gboolean go_online (EBookBackendScalix * bs) { EBookBackendScalixPrivate *priv; EBookBackend *backend; gboolean res; backend = E_BOOK_BACKEND (bs); priv = E_BOOK_BACKEND_SCALIX_GET_PRIVATE (bs); res = TRUE; g_thread_create (go_online_thread, bs, FALSE, NULL); return res; }
static void container_object_added_cb (ScalixContainer * container, ScalixObject * object, gpointer data) { EBookBackend *backend; backend = E_BOOK_BACKEND (data); if (!E_IS_CONTACT (object)) { g_warning ("Invalid object\n"); return; } e_book_backend_notify_update (backend, E_CONTACT (object)); e_book_backend_notify_complete (backend); }
static void ebbm_contacts_connection_status_changed (EBookBackendMAPI *ebma, gboolean is_online) { ESource *source; ESourceMapiFolder *ext_mapi_folder; e_book_backend_set_writable (E_BOOK_BACKEND (ebma), is_online); if (!is_online) return; source = e_backend_get_source (E_BACKEND (ebma)); ext_mapi_folder = e_source_get_extension (source, E_SOURCE_EXTENSION_MAPI_FOLDER); if (e_source_mapi_folder_get_server_notification (ext_mapi_folder)) { EMapiConnection *conn; mapi_object_t obj_folder; gboolean status; GError *mapi_error = NULL; e_book_backend_mapi_lock_connection (ebma); conn = e_book_backend_mapi_get_connection (ebma, NULL, NULL); if (!conn) { e_book_backend_mapi_unlock_connection (ebma); return; } status = ebbm_contacts_open_folder (E_BOOK_BACKEND_MAPI_CONTACTS (ebma), conn, &obj_folder, NULL, &mapi_error); if (status) { e_mapi_connection_enable_notifications (conn, &obj_folder, fnevObjectCreated | fnevObjectModified | fnevObjectDeleted | fnevObjectMoved | fnevObjectCopied, NULL, &mapi_error); e_mapi_connection_close_folder (conn, &obj_folder, NULL, &mapi_error); } e_book_backend_mapi_maybe_disconnect (ebma, mapi_error); g_clear_error (&mapi_error); g_signal_connect (conn, "server-notification", G_CALLBACK (ebbmc_server_notification_cb), ebma); e_book_backend_mapi_unlock_connection (ebma); } }
static guint send_and_handle_ssl (EBookBackendWebdav *webdav, SoupMessage *message, GCancellable *cancellable) { guint status_code; status_code = soup_session_send_message (webdav->priv->session, message); if (status_code == SOUP_STATUS_SSL_FAILED) { ESource *source; ESourceWebdav *extension; ESourceRegistry *registry; EBackend *backend; ETrustPromptResponse response; ENamedParameters *parameters; backend = E_BACKEND (webdav); source = e_backend_get_source (backend); registry = e_book_backend_get_registry (E_BOOK_BACKEND (backend)); extension = e_source_get_extension (source, E_SOURCE_EXTENSION_WEBDAV_BACKEND); parameters = e_named_parameters_new (); response = e_source_webdav_prepare_ssl_trust_prompt (extension, message, registry, parameters); if (response == E_TRUST_PROMPT_RESPONSE_UNKNOWN) { response = e_backend_trust_prompt_sync (backend, parameters, cancellable, NULL); if (response != E_TRUST_PROMPT_RESPONSE_UNKNOWN) e_source_webdav_store_ssl_trust_prompt (extension, message, response); } e_named_parameters_free (parameters); if (response == E_TRUST_PROMPT_RESPONSE_ACCEPT || response == E_TRUST_PROMPT_RESPONSE_ACCEPT_TEMPORARILY) { g_object_set (webdav->priv->session, SOUP_SESSION_SSL_STRICT, FALSE, NULL); status_code = soup_session_send_message (webdav->priv->session, message); } } return status_code; }
static gpointer go_online_thread (gpointer data) { EBookBackend *backend; EBookBackendScalix *bs; EBookBackendScalixPrivate *priv; gboolean res; bs = E_BOOK_BACKEND_SCALIX (data); backend = E_BOOK_BACKEND (bs); priv = E_BOOK_BACKEND_SCALIX_GET_PRIVATE (bs); res = scalix_container_set_online (priv->container, TRUE); if (res == TRUE) { scalix_container_sync (priv->container); } GLOG_CAT_INFO (&slbook, "done (writable: %d)", res); return NULL; }
static void container_object_removed_cb (ScalixContainer * container, ScalixObject * object, gpointer data) { EBookBackend *backend; EContact *contact; const char *uid; backend = E_BOOK_BACKEND (data); if (!E_IS_CONTACT (object)) { g_warning ("Invalid object"); return; } contact = E_CONTACT (object); uid = e_contact_get_const (contact, E_CONTACT_UID); g_assert (uid != NULL); e_book_backend_notify_remove (backend, uid); e_book_backend_notify_complete (backend); }
static GError * download_contacts (EBookBackendWebdav *webdav, EFlag *running, EDataBookView *book_view, GCancellable *cancellable) { EBookBackendWebdavPrivate *priv = webdav->priv; EBookBackend *book_backend; SoupMessage *message; guint status; xmlTextReaderPtr reader; response_element_t *elements; response_element_t *element; response_element_t *next; gint count; gint i; gchar *new_ctag = NULL; g_mutex_lock (&priv->update_lock); if (!check_addressbook_changed (webdav, &new_ctag, cancellable)) { g_free (new_ctag); g_mutex_unlock (&priv->update_lock); return EDB_ERROR (SUCCESS); } book_backend = E_BOOK_BACKEND (webdav); if (book_view != NULL) { e_data_book_view_notify_progress (book_view, -1, _("Loading Addressbook summary...")); } message = send_propfind (webdav, cancellable); status = message->status_code; if (status == 401 || status == 407) { g_object_unref (message); g_free (new_ctag); if (book_view) e_data_book_view_notify_progress (book_view, -1, NULL); g_mutex_unlock (&priv->update_lock); return webdav_handle_auth_request (webdav); } if (status != 207) { GError *error; error = e_data_book_create_error_fmt ( E_DATA_BOOK_STATUS_OTHER_ERROR, _("PROPFIND on webdav failed with HTTP status %d (%s)"), status, message->reason_phrase && *message->reason_phrase ? message->reason_phrase : (soup_status_get_phrase (message->status_code) ? soup_status_get_phrase (message->status_code) : _("Unknown error"))); g_object_unref (message); g_free (new_ctag); if (book_view) e_data_book_view_notify_progress (book_view, -1, NULL); g_mutex_unlock (&priv->update_lock); return error; } if (message->response_body == NULL) { g_warning ("No response body in webdav PROPFIND result"); g_object_unref (message); g_free (new_ctag); if (book_view) e_data_book_view_notify_progress (book_view, -1, NULL); g_mutex_unlock (&priv->update_lock); return e_data_book_create_error_fmt (E_DATA_BOOK_STATUS_OTHER_ERROR, _("No response body in webdav PROPFIND result")); } /* parse response */ reader = xmlReaderForMemory ( message->response_body->data, message->response_body->length, NULL, NULL, XML_PARSE_NOWARNING); elements = parse_propfind_response (reader); /* count contacts */ count = 0; for (element = elements; element != NULL; element = element->next) { ++count; } /* download contacts */ i = 0; for (element = elements; element != NULL; element = element->next, ++i) { const gchar *uri; const gchar *etag; EContact *contact; gchar *complete_uri; /* stop downloading if search was aborted */ if (running != NULL && !e_flag_is_set (running)) break; if (book_view != NULL) { gfloat percent = 100.0 / count * i; gchar buf[100]; snprintf (buf, sizeof (buf), _("Loading Contacts (%d%%)"), (gint) percent); e_data_book_view_notify_progress (book_view, -1, buf); } /* skip collections */ uri = (const gchar *) element->href; if (uri[strlen (uri) - 1] == '/') continue; /* uri might be relative, construct complete one */ if (uri[0] == '/') { SoupURI *soup_uri = soup_uri_new (priv->uri); soup_uri->path = g_strdup (uri); complete_uri = soup_uri_to_string (soup_uri, 0); soup_uri_free (soup_uri); } else { complete_uri = g_strdup (uri); } etag = (const gchar *) element->etag; g_mutex_lock (&priv->cache_lock); contact = e_book_backend_cache_get_contact (priv->cache, complete_uri); g_mutex_unlock (&priv->cache_lock); /* download contact if it is not cached or its ETag changed */ if (contact == NULL || etag == NULL || strcmp (e_contact_get_const (contact, E_CONTACT_REV), etag) != 0) { contact = download_contact (webdav, complete_uri, cancellable); if (contact != NULL) { g_mutex_lock (&priv->cache_lock); if (e_book_backend_cache_remove_contact (priv->cache, complete_uri)) e_book_backend_notify_remove (book_backend, complete_uri); e_book_backend_cache_add_contact (priv->cache, contact); g_mutex_unlock (&priv->cache_lock); e_book_backend_notify_update (book_backend, contact); } } g_free (complete_uri); } /* free element list */ for (element = elements; element != NULL; element = next) { next = element->next; xmlFree (element->href); xmlFree (element->etag); g_free (element); } xmlFreeTextReader (reader); g_object_unref (message); if (new_ctag) { g_mutex_lock (&priv->cache_lock); if (!e_file_cache_replace_object (E_FILE_CACHE (priv->cache), WEBDAV_CTAG_KEY, new_ctag)) e_file_cache_add_object (E_FILE_CACHE (priv->cache), WEBDAV_CTAG_KEY, new_ctag); g_mutex_unlock (&priv->cache_lock); } g_free (new_ctag); if (book_view) e_data_book_view_notify_progress (book_view, -1, NULL); g_mutex_unlock (&priv->update_lock); return EDB_ERROR (SUCCESS); }
static gpointer book_view_thread (gpointer data) { EBookBackendScalix *bs; gboolean stopped; const char *query; EDataBookView *book_view; EBookBackendScalixPrivate *priv; ScalixBackendSearchClosure *closure; GList *iter; ScanContext context; gboolean res; book_view = data; closure = closure_get (book_view); bs = closure->bs; priv = E_BOOK_BACKEND_SCALIX_GET_PRIVATE (bs); stopped = FALSE; bonobo_object_ref (book_view); if (priv->container == NULL) { e_data_book_view_notify_complete (book_view, GNOME_Evolution_Addressbook_AuthenticationRequired); bonobo_object_unref (book_view); return NULL; } query = e_data_book_view_get_card_query (book_view); context.sexp = e_book_backend_sexp_new (query); context.backend = E_BOOK_BACKEND (bs); context.obj_list = NULL; context.return_objects = TRUE; if (!(context.search_needed = query_is_search (query))) { e_data_book_view_notify_status_message (book_view, _("Loading...")); } else { e_data_book_view_notify_status_message (book_view, _("Searching...")); } g_mutex_lock (closure->mutex); g_cond_signal (closure->cond); g_mutex_unlock (closure->mutex); res = scalix_container_foreach (priv->container, scan_objects, &context); if (res == FALSE) { e_data_book_view_notify_complete (book_view, GNOME_Evolution_Addressbook_OtherError); bonobo_object_unref (book_view); return NULL; } for (iter = context.obj_list; iter; iter = iter->next) { g_mutex_lock (closure->mutex); stopped = closure->stopped; g_mutex_unlock (closure->mutex); if (stopped) { break; } e_data_book_view_notify_update (book_view, iter->data); g_object_unref (iter->data); } /*FIXME: we leek objects if stopped */ g_list_free (context.obj_list); if (!stopped) { e_data_book_view_notify_complete (book_view, GNOME_Evolution_Addressbook_Success); } bonobo_object_unref (book_view); return NULL; }
/* ************************************************************************* */ static GNOME_Evolution_Addressbook_CallStatus e_book_backend_scalix_load_source (EBookBackend * backend, ESource * source, gboolean only_if_exists) { EBookBackendScalix *bs; EBookBackendScalixPrivate *priv; ScalixContainer *container; const char *prop_ssl; gchar *uri; bs = E_BOOK_BACKEND_SCALIX (backend); priv = E_BOOK_BACKEND_SCALIX_GET_PRIVATE (bs); if (priv->container != NULL) { /* Source already loaded! */ return GNOME_Evolution_Addressbook_Success; } uri = e_source_get_uri (source); if ((prop_ssl = e_source_get_property (source, "use_ssl"))) { CamelURL *url; url = camel_url_new (uri, NULL); camel_url_set_param (url, "use_ssl", prop_ssl); g_free (uri); uri = camel_url_to_string (url, 0); } container = scalix_container_open (uri); g_free (uri); if (container == NULL) { return GNOME_Evolution_Addressbook_OtherError; } e_book_backend_set_is_loaded (E_BOOK_BACKEND (backend), TRUE); e_book_backend_set_is_writable (E_BOOK_BACKEND (backend), TRUE); if (only_if_exists == FALSE) { GLOG_CAT_DEBUG (&slbook, "Only if exists == FALSE"); g_object_set (container, "only_if_exists", FALSE, "type", "Contacts", NULL); } priv->container = container; // go online here? if (priv->mode == GNOME_Evolution_Addressbook_MODE_REMOTE) { go_online (bs); } g_signal_connect (container, "object_added", G_CALLBACK (container_object_added_cb), (gpointer) backend); g_signal_connect (container, "object_removed", G_CALLBACK (container_object_removed_cb), (gpointer) backend); g_signal_connect (container, "object_changed", G_CALLBACK (container_object_changed_cb), (gpointer) backend); return GNOME_Evolution_Addressbook_Success; }