aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook/backend
diff options
context:
space:
mode:
Diffstat (limited to 'addressbook/backend')
-rw-r--r--addressbook/backend/pas/pas-backend-file.c207
-rw-r--r--addressbook/backend/pas/pas-backend-ldap.c282
-rw-r--r--addressbook/backend/pas/pas-backend.c362
-rw-r--r--addressbook/backend/pas/pas-backend.h62
4 files changed, 518 insertions, 395 deletions
diff --git a/addressbook/backend/pas/pas-backend-file.c b/addressbook/backend/pas/pas-backend-file.c
index c5c8251ad9..852352191d 100644
--- a/addressbook/backend/pas/pas-backend-file.c
+++ b/addressbook/backend/pas/pas-backend-file.c
@@ -51,13 +51,10 @@ typedef struct _PASBackendFileSearchContext PASBackendFileSearchContext;
typedef struct _PasBackendFileChangeContext PASBackendFileChangeContext;
struct _PASBackendFilePrivate {
- GList *clients;
- gboolean loaded;
char *uri;
char *filename;
DB *file_db;
EList *book_views;
- gboolean writable;
GHashTable *address_lists;
PASBackendSummary *summary;
};
@@ -349,9 +346,6 @@ pas_backend_file_search (PASBackendFile *bf,
PASBackendFileBookView *view = (PASBackendFileBookView *)cnstview;
gboolean search_needed;
- if (!bf->priv->loaded)
- return;
-
search_needed = TRUE;
if ( ! strcmp (view->search, "(contains \"x-evolution-any-field\" \"\")"))
@@ -487,9 +481,6 @@ pas_backend_file_changes (PASBackendFile *bf,
memset (&id_dbt, 0, sizeof (id_dbt));
memset (&vcard_dbt, 0, sizeof (vcard_dbt));
- if (!bf->priv->loaded)
- return;
-
/* Find the changed ids */
dirname = g_strdup (bf->priv->filename);
slash = strrchr (dirname, '/');
@@ -991,8 +982,6 @@ pas_backend_file_process_get_book_view (PASBackend *backend,
PASBackendFileBookView view;
EIterator *iterator;
- g_return_if_fail (req->listener != NULL);
-
bonobo_object_ref(BONOBO_OBJECT(book));
book_view = pas_book_view_new (req->listener);
@@ -1013,6 +1002,9 @@ pas_backend_file_process_get_book_view (PASBackend *backend,
: GNOME_Evolution_Addressbook_BookListener_CardNotFound /* XXX */),
book_view);
+ if (!pas_backend_is_loaded (backend))
+ return;
+
iterator = e_list_get_iterator(bf->priv->book_views);
e_iterator_last(iterator);
pas_backend_file_search (bf, book, e_iterator_get(iterator), FALSE);
@@ -1029,8 +1021,6 @@ pas_backend_file_process_get_completion_view (PASBackend *backend,
PASBackendFileBookView view;
EIterator *iterator;
- g_return_if_fail (req->listener != NULL);
-
bonobo_object_ref(BONOBO_OBJECT(book));
book_view = pas_book_view_new (req->listener);
@@ -1051,6 +1041,9 @@ pas_backend_file_process_get_completion_view (PASBackend *backend,
: GNOME_Evolution_Addressbook_BookListener_CardNotFound /* XXX */),
book_view);
+ if (!pas_backend_is_loaded (backend))
+ return;
+
iterator = e_list_get_iterator(bf->priv->book_views);
e_iterator_last(iterator);
pas_backend_file_search (bf, book, e_iterator_get(iterator), TRUE);
@@ -1068,8 +1061,6 @@ pas_backend_file_process_get_changes (PASBackend *backend,
PASBackendFileChangeContext ctx;
EIterator *iterator;
- g_return_if_fail (req->listener != NULL);
-
bonobo_object_ref(BONOBO_OBJECT(book));
book_view = pas_book_view_new (req->listener);
@@ -1096,6 +1087,9 @@ pas_backend_file_process_get_changes (PASBackend *backend,
e_list_append(bf->priv->book_views, &view);
+ if (!pas_backend_is_loaded (backend))
+ return;
+
iterator = e_list_get_iterator(bf->priv->book_views);
e_iterator_last(iterator);
pas_backend_file_changes (bf, book, e_iterator_get(iterator));
@@ -1156,75 +1150,6 @@ pas_backend_file_process_get_supported_fields (PASBackend *backend,
fields);
}
-static void
-pas_backend_file_process_client_requests (PASBook *book)
-{
- PASBackend *backend;
- PASRequest *req;
-
- backend = pas_book_get_backend (book);
-
- req = pas_book_pop_request (book);
- if (req == NULL)
- return;
-
- switch (req->op) {
- case CreateCard:
- pas_backend_file_process_create_card (backend, book, (PASCreateCardRequest*)req);
- break;
-
- case RemoveCard:
- pas_backend_file_process_remove_card (backend, book, (PASRemoveCardRequest*)req);
- break;
-
- case ModifyCard:
- pas_backend_file_process_modify_card (backend, book, (PASModifyCardRequest*)req);
- break;
-
- case CheckConnection:
- pas_backend_file_process_check_connection (backend, book, (PASCheckConnectionRequest*)req);
- break;
-
- case GetVCard:
- pas_backend_file_process_get_vcard (backend, book, (PASGetVCardRequest*)req);
- break;
-
- case GetCursor:
- pas_backend_file_process_get_cursor (backend, book, (PASGetCursorRequest*)req);
- break;
-
- case GetBookView:
- pas_backend_file_process_get_book_view (backend, book, (PASGetBookViewRequest*)req);
- break;
-
- case GetCompletionView:
- pas_backend_file_process_get_completion_view (backend, book, (PASGetCompletionViewRequest*)req);
- break;
-
- case GetChanges:
- pas_backend_file_process_get_changes (backend, book, (PASGetChangesRequest*)req);
- break;
-
- case AuthenticateUser:
- pas_backend_file_process_authenticate_user (backend, book, (PASAuthenticateUserRequest*)req);
- break;
-
- case GetSupportedFields:
- pas_backend_file_process_get_supported_fields (backend, book, (PASGetSupportedFieldsRequest*)req);
- break;
- }
-
- pas_book_free_request (req);
-}
-
-static void
-pas_backend_file_book_destroy_cb (gpointer data, GObject *where_book_was)
-{
- PASBackendFile *backend = PAS_BACKEND_FILE (data);
-
- pas_backend_remove_client (PAS_BACKEND (backend), (PASBook*)where_book_was);
-}
-
/*
** versions:
**
@@ -1377,8 +1302,6 @@ pas_backend_file_load_uri (PASBackend *backend,
struct stat sb;
char *summary_filename;
- g_assert (bf->priv->loaded == FALSE);
-
db_version (&major, &minor, &patch);
if (major != 3 ||
@@ -1445,14 +1368,9 @@ pas_backend_file_load_uri (PASBackend *backend,
return GNOME_Evolution_Addressbook_BookListener_OtherError;
}
- bf->priv->writable = writable;
-
- if (pas_backend_file_maybe_upgrade_db (bf))
- bf->priv->loaded = TRUE;
- else {
+ if (!pas_backend_file_maybe_upgrade_db (bf)) {
db->close (db, 0);
bf->priv->file_db = NULL;
- bf->priv->writable = FALSE;
return GNOME_Evolution_Addressbook_BookListener_OtherError;
}
@@ -1465,7 +1383,6 @@ pas_backend_file_load_uri (PASBackend *backend,
if (stat (bf->priv->filename, &sb) == -1) {
db->close (db, 0);
bf->priv->file_db = NULL;
- bf->priv->writable = FALSE;
return GNOME_Evolution_Addressbook_BookListener_OtherError;
}
db_mtime = sb.st_mtime;
@@ -1479,6 +1396,8 @@ pas_backend_file_load_uri (PASBackend *backend,
build_summary (bf->priv);
}
+ pas_backend_set_is_loaded (backend, TRUE);
+ pas_backend_set_is_writable (backend, writable);
return GNOME_Evolution_Addressbook_BookListener_Success;
}
@@ -1490,96 +1409,13 @@ pas_backend_file_get_uri (PASBackend *backend)
bf = PAS_BACKEND_FILE (backend);
- g_return_val_if_fail (bf->priv->loaded, NULL);
g_assert (bf->priv->uri != NULL);
return bf->priv->uri;
}
-static gboolean
-pas_backend_file_add_client (PASBackend *backend,
- GNOME_Evolution_Addressbook_BookListener listener)
-{
- PASBackendFile *bf;
- PASBook *book;
-
- g_assert (backend != NULL);
- g_assert (PAS_IS_BACKEND_FILE (backend));
-
- bf = PAS_BACKEND_FILE (backend);
-
- book = pas_book_new (backend, listener);
-
- if (!book) {
- if (!bf->priv->clients)
- pas_backend_last_client_gone (backend);
-
- return FALSE;
- }
-
- g_object_weak_ref (G_OBJECT (book), pas_backend_file_book_destroy_cb, backend);
-
- g_signal_connect (book, "requests_queued",
- G_CALLBACK (pas_backend_file_process_client_requests), NULL);
-
- bf->priv->clients = g_list_prepend (
- bf->priv->clients, book);
-
- if (bf->priv->loaded) {
- pas_book_respond_open (
- book, GNOME_Evolution_Addressbook_BookListener_Success);
- if (bf->priv->writable)
- pas_book_report_writable (book, bf->priv->writable);
- } else {
- pas_book_respond_open (
- book, GNOME_Evolution_Addressbook_BookListener_OtherError);
- }
-
- bonobo_object_unref (BONOBO_OBJECT (book));
-
- return TRUE;
-}
-
-static void
-pas_backend_file_remove_client (PASBackend *backend,
- PASBook *book)
-{
- PASBackendFile *bf;
- GList *l;
- PASBook *lbook;
-
- g_return_if_fail (backend != NULL);
- g_return_if_fail (PAS_IS_BACKEND_FILE (backend));
- g_return_if_fail (book != NULL);
- g_return_if_fail (PAS_IS_BOOK (book));
-
- bf = PAS_BACKEND_FILE (backend);
-
- /* Find the book in the list of clients */
-
- for (l = bf->priv->clients; l; l = l->next) {
- lbook = PAS_BOOK (l->data);
-
- if (lbook == book)
- break;
- }
-
- g_assert (l != NULL);
-
- /* Disconnect */
-
- bf->priv->clients = g_list_remove_link (bf->priv->clients, l);
- g_list_free_1 (l);
-
- /* When all clients go away, notify the parent factory about it so that
- * it may decide whether to kill the backend or not.
- */
- if (!bf->priv->clients)
- pas_backend_last_client_gone (backend);
-}
-
static char *
-pas_backend_file_get_static_capabilities (PASBackend *backend)
+pas_backend_file_get_static_capabilities (PASBackend *backend)
{
return g_strdup("local,do-initial-query,cache-completions");
}
@@ -1648,10 +1484,20 @@ pas_backend_file_class_init (PASBackendFileClass *klass)
/* Set the virtual methods. */
parent_class->load_uri = pas_backend_file_load_uri;
parent_class->get_uri = pas_backend_file_get_uri;
- parent_class->add_client = pas_backend_file_add_client;
- parent_class->remove_client = pas_backend_file_remove_client;
parent_class->get_static_capabilities = pas_backend_file_get_static_capabilities;
+ parent_class->create_card = pas_backend_file_process_create_card;
+ parent_class->remove_card = pas_backend_file_process_remove_card;
+ parent_class->modify_card = pas_backend_file_process_modify_card;
+ parent_class->check_connection = pas_backend_file_process_check_connection;
+ parent_class->get_vcard = pas_backend_file_process_get_vcard;
+ parent_class->get_cursor = pas_backend_file_process_get_cursor;
+ parent_class->get_book_view = pas_backend_file_process_get_book_view;
+ parent_class->get_completion_view = pas_backend_file_process_get_completion_view;
+ parent_class->get_changes = pas_backend_file_process_get_changes;
+ parent_class->authenticate_user = pas_backend_file_process_authenticate_user;
+ parent_class->get_supported_fields = pas_backend_file_process_get_supported_fields;
+
object_class->dispose = pas_backend_file_dispose;
}
@@ -1661,11 +1507,8 @@ pas_backend_file_init (PASBackendFile *backend)
PASBackendFilePrivate *priv;
priv = g_new0 (PASBackendFilePrivate, 1);
- priv->loaded = FALSE;
- priv->clients = NULL;
priv->book_views = e_list_new((EListCopyFunc) pas_backend_file_book_view_copy, (EListFreeFunc) pas_backend_file_book_view_free, NULL);
priv->uri = NULL;
- priv->writable = FALSE;
backend->priv = priv;
}
diff --git a/addressbook/backend/pas/pas-backend-ldap.c b/addressbook/backend/pas/pas-backend-ldap.c
index c09495fb22..0a609450ab 100644
--- a/addressbook/backend/pas/pas-backend-ldap.c
+++ b/addressbook/backend/pas/pas-backend-ldap.c
@@ -85,7 +85,6 @@ typedef struct LDAPOp LDAPOp;
struct _PASBackendLDAPPrivate {
char *uri;
gboolean connected;
- GList *clients;
gchar *ldap_host; /* the hostname of the server */
int ldap_port; /* the port of the server */
@@ -117,8 +116,6 @@ struct _PASBackendLDAPPrivate {
gboolean calEntrySupported;
gboolean evolutionPersonChecked;
- gboolean writable;
-
/* our operations */
GHashTable *id_to_op;
int active_ops;
@@ -485,7 +482,7 @@ check_schema_support (PASBackendLDAP *bl)
of draconian acl's that keep subschema
reads from working until the user is
authed. */
- if (!bl->priv->writable) {
+ if (!pas_backend_is_writable (PAS_BACKEND (bl)) {
g_warning ("subschema read returned nothing before successful auth");
bl->priv->evolutionPersonChecked = FALSE;
}
@@ -691,6 +688,7 @@ pas_backend_ldap_connect (PASBackendLDAP *bl)
if (!bl->priv->evolutionPersonChecked)
check_schema_support (bl);
+ pas_backend_set_is_loaded (PAS_BACKEND (bl), TRUE);
return GNOME_Evolution_Addressbook_BookListener_Success;
}
else
@@ -1167,7 +1165,7 @@ create_card_dtor (LDAPOp *op)
static void
pas_backend_ldap_process_create_card (PASBackend *backend,
PASBook *book,
- PASRequest *req)
+ PASCreateCardRequest *req)
{
LDAPCreateOp *create_op = g_new (LDAPCreateOp, 1);
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
@@ -1182,9 +1180,9 @@ pas_backend_ldap_process_create_card (PASBackend *backend,
book_view = find_book_view (bl);
- printf ("vcard = %s\n", req->create.vcard);
+ printf ("vcard = %s\n", req->vcard);
- new_ecard = e_card_new (req->create.vcard);
+ new_ecard = e_card_new (req->vcard);
create_op->new_card = e_card_simple_new (new_ecard);
create_op->dn = create_dn_from_ecard (create_op->new_card, bl->priv->ldap_rootdn);
@@ -1350,7 +1348,7 @@ remove_card_dtor (LDAPOp *op)
static void
pas_backend_ldap_process_remove_card (PASBackend *backend,
PASBook *book,
- PASRequest *req)
+ PASRemoveCardRequest *req)
{
LDAPRemoveOp *remove_op = g_new (LDAPRemoveOp, 1);
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
@@ -1360,7 +1358,7 @@ pas_backend_ldap_process_remove_card (PASBackend *backend,
book_view = find_book_view (bl);
- remove_op->id = g_strdup (req->remove.id);
+ remove_op->id = g_strdup (req->id);
do {
book_view_notify_status (book_view, _("Removing card from LDAP server..."));
@@ -1579,7 +1577,7 @@ modify_card_dtor (LDAPOp *op)
static void
pas_backend_ldap_process_modify_card (PASBackend *backend,
PASBook *book,
- PASRequest *req)
+ PASModifyCardRequest *req)
{
LDAPModifyOp *modify_op = g_new0 (LDAPModifyOp, 1);
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
@@ -1591,7 +1589,7 @@ pas_backend_ldap_process_modify_card (PASBackend *backend,
book_view = find_book_view (bl);
- modify_op->vcard = g_strdup (req->modify.vcard);
+ modify_op->vcard = g_strdup (req->vcard);
new_ecard = e_card_new (modify_op->vcard);
modify_op->card = e_card_simple_new (new_ecard);
g_object_unref (new_ecard);
@@ -1691,7 +1689,7 @@ get_vcard_dtor (LDAPOp *op)
static void
pas_backend_ldap_process_get_vcard (PASBackend *backend,
PASBook *book,
- PASRequest *req)
+ PASGetVCardRequest *req)
{
LDAPGetVCardOp *get_vcard_op = g_new0 (LDAPGetVCardOp, 1);
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
@@ -1703,7 +1701,7 @@ pas_backend_ldap_process_get_vcard (PASBackend *backend,
book_view = find_book_view (bl);
do {
- ldap_error = ldap_search_ext (ldap, req->get_vcard.id,
+ ldap_error = ldap_search_ext (ldap, req->id,
LDAP_SCOPE_BASE,
"(objectclass=*)",
NULL, 0, NULL, NULL,
@@ -1851,7 +1849,7 @@ get_cursor_dtor (LDAPOp *op)
static void
pas_backend_ldap_process_get_cursor (PASBackend *backend,
PASBook *book,
- PASRequest *req)
+ PASGetCursorRequest *req)
{
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
LDAP *ldap = bl->priv->ldap;
@@ -2743,7 +2741,7 @@ build_card_from_entry (LDAP *ldap, LDAPMessage *e, GList **existing_objectclasse
struct prop_info *info = NULL;
char **values;
- if (existing_objectclasses && !strcasecmp (attr, "objectclass")) {
+ if (existing_objectclasses && !g_ascii_strcasecmp (attr, "objectclass")) {
values = ldap_get_values (ldap, e, attr);
for (i = 0; values[i]; i ++)
*existing_objectclasses = g_list_append (*existing_objectclasses, g_strdup (values[i]));
@@ -3056,33 +3054,27 @@ pas_backend_ldap_search (PASBackendLDAP *bl,
}
static void
-pas_backend_ldap_process_get_book_view (PASBackend *backend,
- PASBook *book,
- PASRequest *req)
+ldap_get_view (PASBackend *backend,
+ PASBook *book,
+ const char *search,
+ GNOME_Evolution_Addressbook_BookViewListener listener,
+ int limit)
{
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
PASBookView *book_view;
PASBackendLDAPBookView *view;
- g_return_if_fail (req->get_book_view.listener != NULL);
-
- book_view = pas_book_view_new (req->get_book_view.listener);
+ book_view = pas_book_view_new (listener);
bonobo_object_ref(BONOBO_OBJECT(book));
g_object_weak_ref (G_OBJECT (book_view), view_destroy, book);
view = g_new0(PASBackendLDAPBookView, 1);
view->book_view = book_view;
- view->search = g_strdup(req->get_book_view.search);
+ view->search = g_strdup(search);
view->card_sexp = pas_backend_card_sexp_new (view->search);
view->blpriv = bl->priv;
-
- if (req->op == GetCompletionView) {
- view->limit = MIN (bl->priv->ldap_limit, 100);
- }
- else {
- view->limit = bl->priv->ldap_limit;
- }
+ view->limit = limit;
e_list_append(bl->priv->book_views, view);
@@ -3098,9 +3090,39 @@ pas_backend_ldap_process_get_book_view (PASBackend *backend,
}
static void
+pas_backend_ldap_process_get_book_view (PASBackend *backend,
+ PASBook *book,
+ PASGetBookViewRequest *req)
+{
+ PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
+
+ ldap_get_view (backend, book, req->search, req->listener,
+ bl->priv->ldap_limit);
+}
+
+static void
+pas_backend_ldap_process_get_completion_view (PASBackend *backend,
+ PASBook *book,
+ PASGetCompletionViewRequest *req)
+{
+ PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
+
+ ldap_get_view (backend, book, req->search, req->listener,
+ MIN (bl->priv->ldap_limit, 100));
+}
+
+static void
+pas_backend_ldap_process_get_changes (PASBackend *backend,
+ PASBook *book,
+ PASGetChangesRequest *req)
+{
+ /* FIXME: implement */
+}
+
+static void
pas_backend_ldap_process_check_connection (PASBackend *backend,
PASBook *book,
- PASRequest *req)
+ PASCheckConnectionRequest *req)
{
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
@@ -3110,15 +3132,15 @@ pas_backend_ldap_process_check_connection (PASBackend *backend,
static void
pas_backend_ldap_process_authenticate_user (PASBackend *backend,
PASBook *book,
- PASRequest *req)
+ PASAuthenticateUserRequest *req)
{
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
int ldap_error;
char *dn = NULL;
- if (!strcmp (req->auth_user.auth_method, "ldap/simple-email")) {
+ if (!strcmp (req->auth_method, "ldap/simple-email")) {
LDAPMessage *res, *e;
- char *query = g_strdup_printf ("(mail=%s)", req->auth_user.user);
+ char *query = g_strdup_printf ("(mail=%s)", req->user);
ldap_error = ldap_search_s (bl->priv->ldap,
bl->priv->ldap_rootdn,
@@ -3144,46 +3166,49 @@ pas_backend_ldap_process_authenticate_user (PASBackend *backend,
return;
}
}
- else if (!strcmp (req->auth_user.auth_method, "ldap/simple-binddn")) {
- dn = g_strdup (req->auth_user.user);
+ else if (!strcmp (req->auth_method, "ldap/simple-binddn")) {
+ dn = g_strdup (req->user);
}
/* now authenticate against the DN we were either supplied or queried for */
printf ("authenticating as %s\n", dn);
ldap_error = ldap_simple_bind_s(bl->priv->ldap,
dn,
- req->auth_user.passwd);
+ req->passwd);
bl->priv->auth_dn = dn;
- bl->priv->auth_passwd = g_strdup (req->auth_user.passwd);
+ bl->priv->auth_passwd = g_strdup (req->passwd);
pas_book_respond_authenticate_user (book,
ldap_error_to_response (ldap_error));
- bl->priv->writable = (ldap_error == LDAP_SUCCESS);
-
- /* if the bind was successful we force a requery on the root
- dse since some ldap servers are set up such that they don't
- report anything (including the schema DN) until the user is
- authenticated */
- if (!bl->priv->evolutionPersonChecked && ldap_error == LDAP_SUCCESS) {
- ldap_error = query_ldap_root_dse (bl);
-
- if (LDAP_SUCCESS == ldap_error) {
- if (!bl->priv->evolutionPersonChecked)
- check_schema_support (bl);
+ if (ldap_error == LDAP_SUCCESS) {
+ pas_backend_set_writable (backend, TRUE);
+
+ /* force a requery on the root dse since some ldap
+ servers are set up such that they don't report
+ anything (including the schema DN) until the user
+ is authenticated */
+ if (!bl->priv->evolutionPersonChecked) {
+ ldap_error = query_ldap_root_dse (bl);
+
+ if (LDAP_SUCCESS == ldap_error) {
+ if (!bl->priv->evolutionPersonChecked)
+ check_schema_support (bl);
+ }
+ else
+ g_warning ("Failed to perform root dse query after authenticating, (ldap_error 0x%02x)", ldap_error);
}
- else
- g_warning ("Failed to perform root dse query after authenticating, (ldap_error 0x%02x)", ldap_error);
+
+ pas_book_report_writable (book, TRUE);
}
- pas_book_report_writable (book, bl->priv->writable);
}
static void
pas_backend_ldap_process_get_supported_fields (PASBackend *backend,
PASBook *book,
- PASRequest *req)
+ PASGetSupportedFieldsRequest *req)
{
PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
@@ -3193,76 +3218,6 @@ pas_backend_ldap_process_get_supported_fields (PASBackend *backend,
bl->priv->supported_fields);
}
-static void
-pas_backend_ldap_process_client_requests (PASBook *book)
-{
- PASBackend *backend;
- PASRequest *req;
-
- backend = pas_book_get_backend (book);
-
- req = pas_book_pop_request (book);
- if (req == NULL)
- return;
-
- switch (req->op) {
- case CreateCard:
- pas_backend_ldap_process_create_card (backend, book, req);
- break;
-
- case RemoveCard:
- pas_backend_ldap_process_remove_card (backend, book, req);
- break;
-
- case ModifyCard:
- pas_backend_ldap_process_modify_card (backend, book, req);
- break;
-
- case CheckConnection:
- pas_backend_ldap_process_check_connection (backend, book, req);
- break;
-
- case GetVCard:
- pas_backend_ldap_process_get_vcard (backend, book, req);
- break;
-
- case GetCursor:
- pas_backend_ldap_process_get_cursor (backend, book, req);
- break;
-
- case GetBookView:
- pas_backend_ldap_process_get_book_view (backend, book, req);
- break;
-
- case GetCompletionView:
- /* we don't support summaries so completion view requests are the same as book view requests */
- pas_backend_ldap_process_get_book_view (backend, book, req);
- break;
-
- case GetChanges:
- /* FIXME: Code this. */
- break;
-
- case AuthenticateUser:
- pas_backend_ldap_process_authenticate_user (backend, book, req);
- break;
-
- case GetSupportedFields:
- pas_backend_ldap_process_get_supported_fields (backend, book, req);
- break;
- }
-
- pas_book_free_request (req);
-}
-
-static void
-pas_backend_ldap_book_destroy_cb (gpointer data, GObject *where_book_was)
-{
- PASBackendLDAP *backend = PAS_BACKEND_LDAP (data);
-
- pas_backend_remove_client (PAS_BACKEND (backend), (PASBook*)where_book_was);
-}
-
static GNOME_Evolution_Addressbook_BookListener_CallStatus
pas_backend_ldap_load_uri (PASBackend *backend,
const char *uri)
@@ -3354,73 +3309,6 @@ pas_backend_ldap_get_uri (PASBackend *backend)
return bl->priv->uri;
}
-static gboolean
-pas_backend_ldap_add_client (PASBackend *backend,
- GNOME_Evolution_Addressbook_BookListener listener)
-{
- PASBackendLDAP *bl;
- PASBook *book;
-
- g_assert (backend != NULL);
- g_assert (PAS_IS_BACKEND_LDAP (backend));
-
- bl = PAS_BACKEND_LDAP (backend);
-
- book = pas_book_new (backend, listener);
-
- if (!book) {
- if (!bl->priv->clients)
- pas_backend_last_client_gone (backend);
-
- return FALSE;
- }
-
- g_object_weak_ref (G_OBJECT (book), pas_backend_ldap_book_destroy_cb, backend);
-
- g_signal_connect (book, "requests_queued",
- G_CALLBACK (pas_backend_ldap_process_client_requests), NULL);
-
- bl->priv->clients = g_list_prepend (
- bl->priv->clients, book);
-
- if (bl->priv->connected) {
- pas_book_respond_open (
- book, GNOME_Evolution_Addressbook_BookListener_Success);
- } else {
- pas_book_respond_open (
- book, GNOME_Evolution_Addressbook_BookListener_OtherError);
- }
-
- pas_book_report_writable (book, bl->priv->writable);
-
- bonobo_object_unref (BONOBO_OBJECT (book));
-
- return TRUE;
-}
-
-static void
-pas_backend_ldap_remove_client (PASBackend *backend,
- PASBook *book)
-{
- PASBackendLDAP *bl;
-
- g_return_if_fail (backend != NULL);
- g_return_if_fail (PAS_IS_BACKEND_LDAP (backend));
- g_return_if_fail (book != NULL);
- g_return_if_fail (PAS_IS_BOOK (book));
-
- bl = PAS_BACKEND_LDAP (backend);
-
- /* Disconnect */
- bl->priv->clients = g_list_remove (bl->priv->clients, book);
-
- /* When all clients go away, notify the parent factory about it so that
- * it may decide whether to kill the backend or not.
- */
- if (!bl->priv->clients)
- pas_backend_last_client_gone (backend);
-}
-
static char *
pas_backend_ldap_get_static_capabilities (PASBackend *backend)
{
@@ -3515,10 +3403,20 @@ pas_backend_ldap_class_init (PASBackendLDAPClass *klass)
/* Set the virtual methods. */
parent_class->load_uri = pas_backend_ldap_load_uri;
parent_class->get_uri = pas_backend_ldap_get_uri;
- parent_class->add_client = pas_backend_ldap_add_client;
- parent_class->remove_client = pas_backend_ldap_remove_client;
parent_class->get_static_capabilities = pas_backend_ldap_get_static_capabilities;
+ parent_class->create_card = pas_backend_ldap_process_create_card;
+ parent_class->remove_card = pas_backend_ldap_process_remove_card;
+ parent_class->modify_card = pas_backend_ldap_process_modify_card;
+ parent_class->check_connection = pas_backend_ldap_process_check_connection;
+ parent_class->get_vcard = pas_backend_ldap_process_get_vcard;
+ parent_class->get_cursor = pas_backend_ldap_process_get_cursor;
+ parent_class->get_book_view = pas_backend_ldap_process_get_book_view;
+ parent_class->get_completion_view = pas_backend_ldap_process_get_completion_view;
+ parent_class->get_changes = pas_backend_ldap_process_get_changes;
+ parent_class->authenticate_user = pas_backend_ldap_process_authenticate_user;
+ parent_class->get_supported_fields = pas_backend_ldap_process_get_supported_fields;
+
object_class->dispose = pas_backend_ldap_dispose;
}
diff --git a/addressbook/backend/pas/pas-backend.c b/addressbook/backend/pas/pas-backend.c
index 6d64ba938b..513632c909 100644
--- a/addressbook/backend/pas/pas-backend.c
+++ b/addressbook/backend/pas/pas-backend.c
@@ -10,6 +10,11 @@
#include "pas-backend.h"
#include "pas-marshal.h"
+struct _PASBackendPrivate {
+ GList *clients;
+ gboolean loaded, writable;
+};
+
/* Signal IDs */
enum {
LAST_CLIENT_GONE,
@@ -18,6 +23,7 @@ enum {
static guint pas_backend_signals[LAST_SIGNAL];
+static GObjectClass *parent_class;
gboolean
pas_backend_construct (PASBackend *backend)
@@ -32,6 +38,7 @@ pas_backend_load_uri (PASBackend *backend,
g_return_val_if_fail (backend != NULL, FALSE);
g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE);
g_return_val_if_fail (uri != NULL, FALSE);
+ g_return_val_if_fail (backend->priv->loaded == FALSE, FALSE);
g_assert (PAS_BACKEND_GET_CLASS (backend)->load_uri != NULL);
@@ -51,12 +58,279 @@ pas_backend_get_uri (PASBackend *backend)
{
g_return_val_if_fail (backend != NULL, NULL);
g_return_val_if_fail (PAS_IS_BACKEND (backend), NULL);
+ g_return_val_if_fail (backend->priv->loaded, NULL);
g_assert (PAS_BACKEND_GET_CLASS (backend)->get_uri != NULL);
return (* PAS_BACKEND_GET_CLASS (backend)->get_uri) (backend);
}
+
+void
+pas_backend_create_card (PASBackend *backend,
+ PASBook *book,
+ PASCreateCardRequest *req)
+{
+ g_return_if_fail (PAS_IS_BACKEND (backend));
+ g_return_if_fail (PAS_IS_BOOK (book));
+ g_return_if_fail (req != NULL && req->vcard != NULL);
+
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->create_card != NULL);
+
+ return (* PAS_BACKEND_GET_CLASS (backend)->create_card) (backend, book, req);
+}
+
+void
+pas_backend_remove_card (PASBackend *backend,
+ PASBook *book,
+ PASRemoveCardRequest *req)
+{
+ g_return_if_fail (PAS_IS_BACKEND (backend));
+ g_return_if_fail (PAS_IS_BOOK (book));
+ g_return_if_fail (req != NULL && req->id != NULL);
+
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->remove_card != NULL);
+
+ return (* PAS_BACKEND_GET_CLASS (backend)->remove_card) (backend, book, req);
+}
+
+void
+pas_backend_modify_card (PASBackend *backend,
+ PASBook *book,
+ PASModifyCardRequest *req)
+{
+ g_return_if_fail (PAS_IS_BACKEND (backend));
+ g_return_if_fail (PAS_IS_BOOK (book));
+ g_return_if_fail (req != NULL && req->vcard != NULL);
+
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->modify_card != NULL);
+
+ return (* PAS_BACKEND_GET_CLASS (backend)->modify_card) (backend, book, req);
+}
+
+void
+pas_backend_check_connection (PASBackend *backend,
+ PASBook *book,
+ PASCheckConnectionRequest *req)
+{
+ g_return_if_fail (PAS_IS_BACKEND (backend));
+ g_return_if_fail (PAS_IS_BOOK (book));
+ g_return_if_fail (req != NULL);
+
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->check_connection != NULL);
+
+ return (* PAS_BACKEND_GET_CLASS (backend)->check_connection) (backend, book, req);
+}
+
+void
+pas_backend_get_vcard (PASBackend *backend,
+ PASBook *book,
+ PASGetVCardRequest *req)
+{
+ g_return_if_fail (PAS_IS_BACKEND (backend));
+ g_return_if_fail (PAS_IS_BOOK (book));
+ g_return_if_fail (req != NULL && req->id != NULL);
+
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->get_vcard != NULL);
+
+ return (* PAS_BACKEND_GET_CLASS (backend)->get_vcard) (backend, book, req);
+}
+
+void
+pas_backend_get_cursor (PASBackend *backend,
+ PASBook *book,
+ PASGetCursorRequest *req)
+{
+ g_return_if_fail (PAS_IS_BACKEND (backend));
+ g_return_if_fail (PAS_IS_BOOK (book));
+ g_return_if_fail (req != NULL && req->search != NULL);
+
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->get_cursor != NULL);
+
+ return (* PAS_BACKEND_GET_CLASS (backend)->get_cursor) (backend, book, req);
+}
+
+void
+pas_backend_get_book_view (PASBackend *backend,
+ PASBook *book,
+ PASGetBookViewRequest *req)
+{
+ g_return_if_fail (PAS_IS_BACKEND (backend));
+ g_return_if_fail (PAS_IS_BOOK (book));
+ g_return_if_fail (req != NULL && req->search != NULL && req->listener != CORBA_OBJECT_NIL);
+
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->get_book_view != NULL);
+
+ return (* PAS_BACKEND_GET_CLASS (backend)->get_book_view) (backend, book, req);
+}
+
+void
+pas_backend_get_completion_view (PASBackend *backend,
+ PASBook *book,
+ PASGetCompletionViewRequest *req)
+{
+ g_return_if_fail (PAS_IS_BACKEND (backend));
+ g_return_if_fail (PAS_IS_BOOK (book));
+ g_return_if_fail (req != NULL && req->search != NULL && req->listener != CORBA_OBJECT_NIL);
+
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->get_completion_view != NULL);
+
+ return (* PAS_BACKEND_GET_CLASS (backend)->get_completion_view) (backend, book, req);
+}
+
+void
+pas_backend_get_changes (PASBackend *backend,
+ PASBook *book,
+ PASGetChangesRequest *req)
+{
+ g_return_if_fail (PAS_IS_BACKEND (backend));
+ g_return_if_fail (PAS_IS_BOOK (book));
+ g_return_if_fail (req != NULL && req->change_id != NULL && req->listener != CORBA_OBJECT_NIL);
+
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->get_changes != NULL);
+
+ return (* PAS_BACKEND_GET_CLASS (backend)->get_changes) (backend, book, req);
+}
+
+void
+pas_backend_authenticate_user (PASBackend *backend,
+ PASBook *book,
+ PASAuthenticateUserRequest *req)
+{
+ g_return_if_fail (PAS_IS_BACKEND (backend));
+ g_return_if_fail (PAS_IS_BOOK (book));
+ g_return_if_fail (req != NULL);
+
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->authenticate_user != NULL);
+
+ return (* PAS_BACKEND_GET_CLASS (backend)->authenticate_user) (backend, book, req);
+}
+
+void
+pas_backend_get_supported_fields (PASBackend *backend,
+ PASBook *book,
+ PASGetSupportedFieldsRequest *req)
+{
+ g_return_if_fail (PAS_IS_BACKEND (backend));
+ g_return_if_fail (PAS_IS_BOOK (book));
+ g_return_if_fail (req != NULL);
+
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->get_supported_fields != NULL);
+
+ return (* PAS_BACKEND_GET_CLASS (backend)->get_supported_fields) (backend, book, req);
+}
+
+static void
+process_client_requests (PASBook *book, gpointer user_data)
+{
+ PASBackend *backend;
+ PASRequest *req;
+
+ backend = PAS_BACKEND (user_data);
+
+ req = pas_book_pop_request (book);
+ if (req == NULL)
+ return;
+
+ switch (req->op) {
+ case CreateCard:
+ pas_backend_create_card (backend, book, &req->create);
+ break;
+
+ case RemoveCard:
+ pas_backend_remove_card (backend, book, &req->remove);
+ break;
+
+ case ModifyCard:
+ pas_backend_modify_card (backend, book, &req->modify);
+ break;
+
+ case CheckConnection:
+ pas_backend_check_connection (backend, book, &req->check_connection);
+ break;
+
+ case GetVCard:
+ pas_backend_get_vcard (backend, book, &req->get_vcard);
+ break;
+
+ case GetCursor:
+ pas_backend_get_cursor (backend, book, &req->get_cursor);
+ break;
+
+ case GetBookView:
+ pas_backend_get_book_view (backend, book, &req->get_book_view);
+ break;
+
+ case GetCompletionView:
+ pas_backend_get_completion_view (backend, book, &req->get_completion_view);
+ break;
+
+ case GetChanges:
+ pas_backend_get_changes (backend, book, &req->get_changes);
+ break;
+
+ case AuthenticateUser:
+ pas_backend_authenticate_user (backend, book, &req->auth_user);
+ break;
+
+ case GetSupportedFields:
+ pas_backend_get_supported_fields (backend, book, &req->get_supported_fields);
+ break;
+ }
+
+ pas_book_free_request (req);
+}
+
+static void
+book_destroy_cb (gpointer data, GObject *where_book_was)
+{
+ PASBackend *backend = PAS_BACKEND (data);
+
+ pas_backend_remove_client (backend, (PASBook *)where_book_was);
+}
+
+static void
+last_client_gone (PASBackend *backend)
+{
+ g_signal_emit (backend, pas_backend_signals[LAST_CLIENT_GONE], 0);
+}
+
+static gboolean
+add_client (PASBackend *backend,
+ GNOME_Evolution_Addressbook_BookListener listener)
+{
+ PASBook *book;
+
+ book = pas_book_new (backend, listener);
+ if (!book) {
+ if (!backend->priv->clients)
+ last_client_gone (backend);
+
+ return FALSE;
+ }
+
+ g_object_weak_ref (G_OBJECT (book), book_destroy_cb, backend);
+
+ g_signal_connect (book, "requests_queued",
+ G_CALLBACK (process_client_requests), backend);
+
+ backend->priv->clients = g_list_prepend (backend->priv->clients, book);
+
+ if (backend->priv->loaded) {
+ pas_book_respond_open (
+ book, GNOME_Evolution_Addressbook_BookListener_Success);
+ } else {
+ pas_book_respond_open (
+ book, GNOME_Evolution_Addressbook_BookListener_OtherError);
+ }
+
+ pas_book_report_writable (book, backend->priv->writable);
+
+ bonobo_object_unref (BONOBO_OBJECT (book));
+
+ return TRUE;
+}
+
/**
* pas_backend_add_client:
* @backend: An addressbook backend.
@@ -67,10 +341,9 @@ pas_backend_get_uri (PASBackend *backend)
* Return value: TRUE on success, FALSE on failure to add the client.
*/
gboolean
-pas_backend_add_client (PASBackend *backend,
+pas_backend_add_client (PASBackend *backend,
GNOME_Evolution_Addressbook_BookListener listener)
{
- g_return_val_if_fail (backend != NULL, FALSE);
g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE);
g_return_val_if_fail (listener != CORBA_OBJECT_NIL, FALSE);
@@ -79,13 +352,25 @@ pas_backend_add_client (PASBackend *backend,
return PAS_BACKEND_GET_CLASS (backend)->add_client (backend, listener);
}
+static void
+remove_client (PASBackend *backend,
+ PASBook *book)
+{
+ /* Disconnect */
+ backend->priv->clients = g_list_remove (backend->priv->clients, book);
+
+ /* When all clients go away, notify the parent factory about it so that
+ * it may decide whether to kill the backend or not.
+ */
+ if (!backend->priv->clients)
+ last_client_gone (backend);
+}
+
void
pas_backend_remove_client (PASBackend *backend,
PASBook *book)
{
- g_return_if_fail (backend != NULL);
g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (book != NULL);
g_return_if_fail (PAS_IS_BOOK (book));
g_assert (PAS_BACKEND_GET_CLASS (backend)->remove_client != NULL);
@@ -104,26 +389,64 @@ pas_backend_get_static_capabilities (PASBackend *backend)
return PAS_BACKEND_GET_CLASS (backend)->get_static_capabilities (backend);
}
-/**
- * pas_backend_last_client_gone:
- * @backend: An addressbook backend.
- *
- * Emits the "last_client_gone" signal for the specified backend. Should
- * only be called from backend implementations if the backend really does
- * not have any more clients.
- **/
+gboolean
+pas_backend_is_loaded (PASBackend *backend)
+{
+ g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE);
+
+ return backend->priv->loaded;
+}
+
void
-pas_backend_last_client_gone (PASBackend *backend)
+pas_backend_set_is_loaded (PASBackend *backend, gboolean is_loaded)
{
- g_return_if_fail (backend != NULL);
g_return_if_fail (PAS_IS_BACKEND (backend));
- g_signal_emit (backend, pas_backend_signals[LAST_CLIENT_GONE], 0);
+ backend->priv->loaded = is_loaded;
+}
+
+gboolean
+pas_backend_is_writable (PASBackend *backend)
+{
+ g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE);
+
+ return backend->priv->writable;
+}
+
+void
+pas_backend_set_is_writable (PASBackend *backend, gboolean is_writable)
+{
+ g_return_if_fail (PAS_IS_BACKEND (backend));
+
+ backend->priv->writable = is_writable;
}
static void
pas_backend_init (PASBackend *backend)
{
+ PASBackendPrivate *priv;
+
+ priv = g_new0 (PASBackendPrivate, 1);
+ priv->clients = NULL;
+
+ backend->priv = priv;
+}
+
+static void
+pas_backend_dispose (GObject *object)
+{
+ PASBackend *backend;
+
+ backend = PAS_BACKEND (object);
+
+ if (backend->priv) {
+ g_list_free (backend->priv->clients);
+ g_free (backend->priv);
+
+ backend->priv = NULL;
+ }
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
@@ -131,11 +454,14 @@ pas_backend_class_init (PASBackendClass *klass)
{
GObjectClass *object_class;
+ parent_class = g_type_class_peek_parent (klass);
+
object_class = (GObjectClass *) klass;
- klass->add_client = NULL;
- klass->remove_client = NULL;
- klass->get_static_capabilities = NULL;
+ klass->add_client = add_client;
+ klass->remove_client = remove_client;
+
+ object_class->dispose = pas_backend_dispose;
pas_backend_signals[LAST_CLIENT_GONE] =
g_signal_new ("last_client_gone",
diff --git a/addressbook/backend/pas/pas-backend.h b/addressbook/backend/pas/pas-backend.h
index d1d5705b0f..8c3cab2c60 100644
--- a/addressbook/backend/pas/pas-backend.h
+++ b/addressbook/backend/pas/pas-backend.h
@@ -53,6 +53,18 @@ typedef struct {
void (*remove_client) (PASBackend *backend, PASBook *book);
char *(*get_static_capabilities) (PASBackend *backend);
+ void (*create_card) (PASBackend *backend, PASBook *book, PASCreateCardRequest *req);
+ void (*remove_card) (PASBackend *backend, PASBook *book, PASRemoveCardRequest *req);
+ void (*modify_card) (PASBackend *backend, PASBook *book, PASModifyCardRequest *req);
+ void (*check_connection) (PASBackend *backend, PASBook *book, PASCheckConnectionRequest *req);
+ void (*get_vcard) (PASBackend *backend, PASBook *book, PASGetVCardRequest *req);
+ void (*get_cursor) (PASBackend *backend, PASBook *book, PASGetCursorRequest *req);
+ void (*get_book_view) (PASBackend *backend, PASBook *book, PASGetBookViewRequest *req);
+ void (*get_completion_view) (PASBackend *backend, PASBook *book, PASGetCompletionViewRequest *req);
+ void (*get_changes) (PASBackend *backend, PASBook *book, PASGetChangesRequest *req);
+ void (*authenticate_user) (PASBackend *backend, PASBook *book, PASAuthenticateUserRequest *req);
+ void (*get_supported_fields) (PASBackend *backend, PASBook *book, PASGetSupportedFieldsRequest *req);
+
/* Notification signals */
void (* last_client_gone) (PASBackend *backend);
} PASBackendClass;
@@ -72,9 +84,53 @@ void pas_backend_remove_client (PASBackend *backen
PASBook *book);
char *pas_backend_get_static_capabilities (PASBackend *backend);
-void pas_backend_last_client_gone (PASBackend *backend);
-
-GType pas_backend_get_type (void);
+gboolean pas_backend_is_loaded (PASBackend *backend);
+
+gboolean pas_backend_is_writable (PASBackend *backend);
+
+void pas_backend_create_card (PASBackend *backend,
+ PASBook *book,
+ PASCreateCardRequest *req);
+void pas_backend_remove_card (PASBackend *backend,
+ PASBook *book,
+ PASRemoveCardRequest *req);
+void pas_backend_modify_card (PASBackend *backend,
+ PASBook *book,
+ PASModifyCardRequest *req);
+void pas_backend_check_connection (PASBackend *backend,
+ PASBook *book,
+ PASCheckConnectionRequest *req);
+void pas_backend_get_vcard (PASBackend *backend,
+ PASBook *book,
+ PASGetVCardRequest *req);
+void pas_backend_get_cursor (PASBackend *backend,
+ PASBook *book,
+ PASGetCursorRequest *req);
+void pas_backend_get_book_view (PASBackend *backend,
+ PASBook *book,
+ PASGetBookViewRequest *req);
+void pas_backend_get_completion_view (PASBackend *backend,
+ PASBook *book,
+ PASGetCompletionViewRequest *req);
+void pas_backend_get_changes (PASBackend *backend,
+ PASBook *book,
+ PASGetChangesRequest *req);
+void pas_backend_authenticate_user (PASBackend *backend,
+ PASBook *book,
+ PASAuthenticateUserRequest *req);
+void pas_backend_get_supported_fields (PASBackend *backend,
+ PASBook *book,
+ PASGetSupportedFieldsRequest *req);
+
+
+GType pas_backend_get_type (void);
+
+
+/* protected functions for subclasses */
+void pas_backend_set_is_loaded (PASBackend *backend,
+ gboolean is_loaded);
+void pas_backend_set_is_writable (PASBackend *backend,
+ gboolean is_writable);
#endif /* ! __PAS_BACKEND_H__ */