aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook/backend
diff options
context:
space:
mode:
authorChris Toshok <toshok@ximian.com>2003-10-23 04:50:36 +0800
committerChris Toshok <toshok@src.gnome.org>2003-10-23 04:50:36 +0800
commitcbfab681c1576d4de27d48fbd6b4b7780670494a (patch)
tree70e99033907a1f5dada728e785835a07ca6ab98c /addressbook/backend
parentf7cbb839adf3fd47aa07ca2080063acd6fff6978 (diff)
downloadgsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.tar
gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.tar.gz
gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.tar.bz2
gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.tar.lz
gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.tar.xz
gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.tar.zst
gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.zip
use the synchronous api for this. simplifies it a bunch.
2003-10-21 Chris Toshok <toshok@ximian.com> * tools/evolution-addressbook-abuse.c: use the synchronous api for this. simplifies it a bunch. 2003-10-21 Chris Toshok <toshok@ximian.com> * backend/pas/pas-book.c (impl_GNOME_Evolution_Addressbook_Book_remove): we can ill afford bad debug spew. (view_listener_died_cb): implement. (impl_GNOME_Evolution_Addressbook_Book_getBookView): hook up an ORBit_small connection listener on the view's listener. (pas_book_respond_create): use e_contact_get_const instead of e_contact_get here. fixes a leak. * backend/pas/pas-book-view.c (impl_GNOME_Evolution_Addressbook_BookView_stop): implement, call pas_backend_stop_book_view. (pas_book_view_get_listener): return the book view's listener. (pas_book_view_class_init): fill in epv->stop. (pas_book_view_init): use a #define for THRESHOLD_MAX instead of the constant. * backend/pas/pas-book-view.h: add prototype for pas_book_view_get_listener. * backend/pas/pas-backend.c (pas_backend_stop_book_view): implement. (pas_backend_remove_book_view): implement. * backend/pas/pas-backend.h: add prototype for stop_book_view and remove_book_view. * backend/pas/pas-backend-vcf.c (load_file): pass in the fd and use fdopen here. (foreach_build_list): don't creat EContacts here, because we'll just be converting them back to vcards anyway. (save_file): use char*'s instead of EContacts, and split entries with 2 blank lines. Also, hold the lock over the entire function. (do_create): hold the lock around uid generation and touching the hash table. (pas_backend_vcf_process_remove_contacts): same. (pas_backend_vcf_process_modify_contact): same. (pas_backend_vcf_stop_book_view): new function, but leave unimplemented for now. (pas_backend_vcf_load_uri): the uri contains the directory name, not the filename. (pas_backend_vcf_dispose): grab the lock here just for sanity's sake. Also reorder things a bit, and free the hashtable and mutex. (pas_backend_vcf_init): init the mutex. * backend/pas/pas-backend-summary.c (pas_backend_summary_add_contact): don't unref the contact here. * backend/pas/pas-backend-ldap.c (pas_backend_ldap_process_stop_book_view): new function, but leave unimplemented for now. * backend/pas/pas-backend-file.c (build_summary): use an EContact for this call. (do_summary_query): nuke, the contents of this has been moved to start_book_view. (pas_backend_file_search_timeout): same. (pas_backend_file_search): same. (pas_backend_file_start_book_view): glom everything into here involving searching. This function could (and should) be renamed and reused from both this function and _get_contact_list. (pas_backend_file_stop_book_view): new function. (pas_backend_file_class_init): fill in backend->stop_book_view. * backend/pas/Makefile.am (LDAP_BACKEND): libpasldap.a -> libpasldap.la (noinst_LTLIBRARIES): *.a -> *.la. (libpas_la_SOURCES): same. (libpasfile_la_SOURCES): same. (libpasvcf_la_SOURCES): same. (libpasldap_la_SOURCES): same. * backend/idl/addressbook.idl: add BookView::stop. * backend/ebook/e-vcard.c (read_attribute_value): fix GString related leaks. (read_attribute_params): same. (parse): don't leak the EVCardAttributes corresponding to BEGIN/END:vCard. (free_gstring): new function (e_vcard_attribute_remove_values): free the decoded_values list, using free_gstring. * backend/ebook/e-book.c (e_book_response_get_book_view): ref the listener here. * backend/ebook/e-book-view.h: add prototype for e_book_view_stop. * backend/ebook/e-book-view.c (e_book_view_stop): new function. * backend/ebook/e-book-async.c (_get_book_view_response_dtor): unref the book view. svn path=/trunk/; revision=23000
Diffstat (limited to 'addressbook/backend')
-rw-r--r--addressbook/backend/ebook/e-book-async.c1
-rw-r--r--addressbook/backend/ebook/e-book-view.c12
-rw-r--r--addressbook/backend/ebook/e-book.c3
-rw-r--r--addressbook/backend/ebook/e-contact.h4
-rw-r--r--addressbook/backend/ebook/e-vcard.c34
-rw-r--r--addressbook/backend/idl/addressbook.idl1
-rw-r--r--addressbook/backend/pas/Makefile.am17
-rw-r--r--addressbook/backend/pas/pas-backend-file.c288
-rw-r--r--addressbook/backend/pas/pas-backend-ldap.c8
-rw-r--r--addressbook/backend/pas/pas-backend-summary.c2
-rw-r--r--addressbook/backend/pas/pas-backend-vcf.c95
-rw-r--r--addressbook/backend/pas/pas-backend.c23
-rw-r--r--addressbook/backend/pas/pas-backend.h6
-rw-r--r--addressbook/backend/pas/pas-book-view.c20
-rw-r--r--addressbook/backend/pas/pas-book-view.h1
-rw-r--r--addressbook/backend/pas/pas-book.c14
16 files changed, 330 insertions, 199 deletions
diff --git a/addressbook/backend/ebook/e-book-async.c b/addressbook/backend/ebook/e-book-async.c
index 2ccc565eb9..d21f22a739 100644
--- a/addressbook/backend/ebook/e-book-async.c
+++ b/addressbook/backend/ebook/e-book-async.c
@@ -969,6 +969,7 @@ _get_book_view_response_dtor (EBookMsg *msg)
GetBookViewResponse *resp = (GetBookViewResponse*)msg;
g_object_unref (resp->book);
+ g_object_unref (resp->book_view);
g_free (resp);
}
diff --git a/addressbook/backend/ebook/e-book-view.c b/addressbook/backend/ebook/e-book-view.c
index e8468e35de..c36e87967c 100644
--- a/addressbook/backend/ebook/e-book-view.c
+++ b/addressbook/backend/ebook/e-book-view.c
@@ -204,9 +204,17 @@ e_book_view_start (EBookView *book_view)
void
e_book_view_stop (EBookView *book_view)
{
+ CORBA_Environment ev;
+
g_return_if_fail (book_view && E_IS_BOOK_VIEW (book_view));
- if (book_view->priv->listener)
- e_book_view_listener_stop (book_view->priv->listener);
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Addressbook_BookView_stop (book_view->priv->corba_book_view, &ev);
+
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ g_warning ("corba exception._major = %d\n", ev._major);
+ }
}
static void
diff --git a/addressbook/backend/ebook/e-book.c b/addressbook/backend/ebook/e-book.c
index 3883cd4b15..c84b4c3f83 100644
--- a/addressbook/backend/ebook/e-book.c
+++ b/addressbook/backend/ebook/e-book.c
@@ -1027,6 +1027,8 @@ e_book_response_get_book_view (EBook *book,
op->status = status;
op->view = e_book_view_new (corba_book_view, op->listener);
+ bonobo_object_ref(BONOBO_OBJECT(op->listener));
+
pthread_cond_signal (&op->cond);
e_mutex_unlock (op->mutex);
@@ -1677,7 +1679,6 @@ e_book_load_uri (EBook *book,
&ev);
if (ev._major != CORBA_NO_EXCEPTION) {
-
e_book_clear_op (book, our_op);
CORBA_exception_free (&ev);
diff --git a/addressbook/backend/ebook/e-contact.h b/addressbook/backend/ebook/e-contact.h
index 8de02caa5f..21c0256ca9 100644
--- a/addressbook/backend/ebook/e-contact.h
+++ b/addressbook/backend/ebook/e-contact.h
@@ -127,6 +127,10 @@ typedef enum {
E_CONTACT_BIRTH_DATE, /* structured field (EContactDate) */
E_CONTACT_ANNIVERSARY, /* structured field (EContactDate) */
+ /* Security Fields */
+ E_CONTACT_X509_CERT, /* string field */
+ E_CONTACT_X509_CERT_SHA1_FINGERPRINT, /* string field */
+
E_CONTACT_FIELD_LAST,
/* useful constants */
diff --git a/addressbook/backend/ebook/e-vcard.c b/addressbook/backend/ebook/e-vcard.c
index 7ea1d9da84..5207d0fefe 100644
--- a/addressbook/backend/ebook/e-vcard.c
+++ b/addressbook/backend/ebook/e-vcard.c
@@ -252,8 +252,8 @@ read_attribute_value (EVCardAttribute *attr, char **p, gboolean quoted_printable
lp = g_utf8_next_char(lp);
}
else if (*lp == ';') {
- e_vcard_attribute_add_value (attr, g_string_free (str, FALSE));
- str = g_string_new ("");
+ e_vcard_attribute_add_value (attr, str->str);
+ g_string_assign (str, "");
lp = g_utf8_next_char(lp);
}
else {
@@ -261,8 +261,10 @@ read_attribute_value (EVCardAttribute *attr, char **p, gboolean quoted_printable
lp = g_utf8_next_char(lp);
}
}
- if (str)
- e_vcard_attribute_add_value (attr, g_string_free (str, FALSE));
+ if (str) {
+ e_vcard_attribute_add_value (attr, str->str);
+ g_string_free (str, TRUE);
+ }
if (*lp == '\r') {
lp = g_utf8_next_char (lp); /* \n */
@@ -290,7 +292,7 @@ read_attribute_params (EVCardAttribute *attr, char **p, gboolean *quoted_printab
if (*lp == '=') {
if (str->len > 0) {
param = e_vcard_attribute_param_new (str->str);
- str = g_string_assign (str, "");
+ g_string_assign (str, "");
lp = g_utf8_next_char (lp);
}
else {
@@ -311,7 +313,7 @@ read_attribute_params (EVCardAttribute *attr, char **p, gboolean *quoted_printab
if (param) {
if (str->len > 0) {
e_vcard_attribute_param_add_value (param, str->str);
- str = g_string_assign (str, "");
+ g_string_assign (str, "");
if (!colon)
lp = g_utf8_next_char (lp);
}
@@ -354,7 +356,7 @@ read_attribute_params (EVCardAttribute *attr, char **p, gboolean *quoted_printab
param = e_vcard_attribute_param_new (param_name);
e_vcard_attribute_param_add_value (param, str->str);
}
- str = g_string_assign (str, "");
+ g_string_assign (str, "");
if (!colon)
lp = g_utf8_next_char (lp);
}
@@ -376,7 +378,7 @@ read_attribute_params (EVCardAttribute *attr, char **p, gboolean *quoted_printab
}
else {
g_warning ("invalid character found in parameter spec");
- str = g_string_assign (str, "");
+ g_string_assign (str, "");
skip_until (&lp, ":;");
}
}
@@ -514,6 +516,8 @@ parse (EVCard *evc, const char *str)
if (!attr || attr->group || g_ascii_strcasecmp (attr->name, "begin")) {
g_warning ("vcard began without a BEGIN:VCARD\n");
}
+ if (attr)
+ e_vcard_attribute_free (attr);
while (*p) {
EVCardAttribute *next_attr = read_attribute (&p);
@@ -529,6 +533,9 @@ parse (EVCard *evc, const char *str)
g_warning ("vcard ended without END:VCARD\n");
}
+ if (attr && !g_ascii_strcasecmp (attr->name, "end"))
+ e_vcard_attribute_free (attr);
+
g_free (buf);
}
@@ -712,7 +719,8 @@ e_vcard_to_string_vcard_30 (EVCard *evc)
attr_str = g_string_append (attr_str, CRLF);
- str = g_string_append (str, g_string_free (attr_str, FALSE));
+ str = g_string_append (str, attr_str->str);
+ g_string_free (attr_str, TRUE);
}
str = g_string_append (str, "END:vCard");
@@ -925,11 +933,19 @@ e_vcard_attribute_add_values (EVCardAttribute *attr,
va_end (ap);
}
+static void
+free_gstring (GString *str)
+{
+ g_string_free (str, TRUE);
+}
+
void
e_vcard_attribute_remove_values (EVCardAttribute *attr)
{
g_list_foreach (attr->values, (GFunc)g_free, NULL);
g_list_free (attr->values);
+ g_list_foreach (attr->decoded_values, (GFunc)free_gstring, NULL);
+ g_list_free (attr->decoded_values);
attr->values = NULL;
}
diff --git a/addressbook/backend/idl/addressbook.idl b/addressbook/backend/idl/addressbook.idl
index 1ad3a62dd9..bfdbae6882 100644
--- a/addressbook/backend/idl/addressbook.idl
+++ b/addressbook/backend/idl/addressbook.idl
@@ -80,6 +80,7 @@ module Addressbook {
interface BookView : Bonobo::Unknown {
oneway void start ();
+ oneway void stop ();
};
interface Book : Bonobo::Unknown {
diff --git a/addressbook/backend/pas/Makefile.am b/addressbook/backend/pas/Makefile.am
index b602a21512..6217456006 100644
--- a/addressbook/backend/pas/Makefile.am
+++ b/addressbook/backend/pas/Makefile.am
@@ -35,14 +35,14 @@ LDAP_BACKEND_FILES = \
pas-backend-ldap.h
if ENABLE_LDAP
-LDAP_BACKEND = libpasldap.a
+LDAP_BACKEND = libpasldap.la
endif
ldapschemadir = $(privdatadir)
ldapschema_DATA= $(LDAP_SCHEMA)
-privlib_LIBRARIES = libpas.a
-noinst_LIBRARIES = libpasfile.a libpasvcf.a $(LDAP_BACKEND)
+privlib_LTLIBRARIES = libpas.la
+noinst_LTLIBRARIES = libpasfile.la libpasvcf.la $(LDAP_BACKEND)
pasincludedir = $(privincludedir)/pas
@@ -57,33 +57,34 @@ pasinclude_HEADERS = \
pas-backend-sync.h \
pas-types.h
-libpas_a_SOURCES = \
+libpas_la_SOURCES = \
$(pasinclude_HEADERS) \
$(CORBA_SOURCE_C) \
pas-book-factory.c \
pas-book-view.c \
pas-book.c \
pas-backend-card-sexp.c \
- pas-backend-file.c \
pas-backend.c \
pas-backend-summary.c \
pas-backend-sync.c \
pas-marshal.c \
ximian-vcard.h
-libpasfile_a_SOURCES = \
+libpasfile_la_SOURCES = \
pas-backend-file.c \
pas-backend-file.h
-libpasvcf_a_SOURCES = \
+libpasvcf_la_SOURCES = \
pas-backend-vcf.c \
pas-backend-vcf.h
if ENABLE_LDAP
-libpasldap_a_SOURCES = \
+libpasldap_la_SOURCES = \
$(LDAP_BACKEND_FILES)
endif
+libpas_la_LIBADD = libpasfile.la libpasvcf.la $(LDAP_BACKEND) $(DB3_LDADD)
+
MARSHAL_GENERATED = pas-marshal.c pas-marshal.h
@EVO_MARSHAL_RULE@
diff --git a/addressbook/backend/pas/pas-backend-file.c b/addressbook/backend/pas/pas-backend-file.c
index 06923d7b08..923c7e907d 100644
--- a/addressbook/backend/pas/pas-backend-file.c
+++ b/addressbook/backend/pas/pas-backend-file.c
@@ -90,8 +90,9 @@ build_summary (PASBackendFilePrivate *bfpriv)
/* don't include the version in the list of cards */
if (id_dbt.size != strlen(PAS_BACKEND_FILE_VERSION_NAME) + 1
|| strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) {
-
- pas_backend_summary_add_contact (bfpriv->summary, vcard_dbt.data);
+ EContact *contact = e_contact_new_from_vcard (vcard_dbt.data);
+ pas_backend_summary_add_contact (bfpriv->summary, contact);
+ g_object_unref (contact);
}
db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
@@ -99,52 +100,6 @@ build_summary (PASBackendFilePrivate *bfpriv)
}
}
-static void
-do_summary_query (PASBackendFile *bf,
- PASBookView *view)
-{
- GPtrArray *ids = pas_backend_summary_search (bf->priv->summary, pas_book_view_get_card_query (view));
- int db_error = 0;
- DB *db = bf->priv->file_db;
- DBT id_dbt, vcard_dbt;
- int i;
-
- for (i = 0; i < ids->len; i ++) {
- char *id = g_ptr_array_index (ids, i);
-
-#if SUMMARY_STORES_ENOUGH_INFO
- /* this is disabled for the time being because lists
- can have more than 3 email addresses and the
- summary only stores 3. */
-
- if (completion_search) {
- vcard = pas_backend_summary_get_summary_vcard (bf->priv->summary,
- id);
- if (vcard) {
- EContact *contact = e_contact_new_from_vcard (vcard_dbt.data);
- pas_book_view_notify_update (view, contact);
- g_object_unref (contact);
- }
- }
- else {
-#endif
- string_to_dbt (id, &id_dbt);
- memset (&vcard_dbt, 0, sizeof (vcard_dbt));
-
- db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
-
- if (db_error == 0)
- pas_book_view_notify_update (view, vcard_dbt.data);
-#if SUMMARY_STORES_ENOUGH_INFO
- }
-#endif
- }
-
- g_ptr_array_free (ids, TRUE);
-
- pas_book_view_notify_complete (view, GNOME_Evolution_Addressbook_Success);
-}
-
static char *
pas_backend_file_create_unique_id (void)
{
@@ -155,105 +110,6 @@ pas_backend_file_create_unique_id (void)
return g_strdup_printf (PAS_ID_PREFIX "%08lX%08X", time(NULL), c++);
}
-typedef struct {
- PASBackendFile *bf;
- PASBook *book;
- PASBookView *view;
- DBC *dbc;
-
- gboolean done_first;
-} FileBackendSearchClosure;
-
-static void
-free_search_closure (FileBackendSearchClosure *closure)
-{
- g_free (closure);
-}
-
-static gboolean
-pas_backend_file_search_timeout (gpointer data)
-{
- FileBackendSearchClosure *closure = data;
- int db_error = 0;
- DBT id_dbt, vcard_dbt;
- int file_version_name_len;
- DBC *dbc = closure->dbc;
-
- file_version_name_len = strlen (PAS_BACKEND_FILE_VERSION_NAME);
-
- memset (&id_dbt, 0, sizeof (id_dbt));
- memset (&vcard_dbt, 0, sizeof (vcard_dbt));
-
- if (closure->done_first) {
- db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
- }
- else {
- db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST);
- closure->done_first = TRUE;
- }
-
- while (db_error == 0) {
-
- /* don't include the version in the list of cards */
- if (strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) {
- char *vcard_string = vcard_dbt.data;
- EContact *contact = e_contact_new_from_vcard (vcard_string);
-
- /* notify_update will check if it matches for us */
- pas_book_view_notify_update (closure->view, contact);
- g_object_unref (contact);
- }
-
- db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
- }
-
- dbc->c_close (dbc);
-
- if (db_error != DB_NOTFOUND) {
- g_warning ("pas_backend_file_search: error building list\n");
- free_search_closure (closure);
- }
-
- pas_book_view_notify_complete (closure->view, GNOME_Evolution_Addressbook_Success);
-
- free_search_closure (closure);
-
- return FALSE;
-}
-
-
-static void
-pas_backend_file_search (PASBackendFile *bf,
- PASBookView *book_view)
-{
- const char *query = pas_book_view_get_card_query (book_view);
-
- if ( ! strcmp (query, "(contains \"x-evolution-any-field\" \"\")"))
- pas_book_view_notify_status_message (book_view, _("Loading..."));
- else
- pas_book_view_notify_status_message (book_view, _("Searching..."));
-
- if (pas_backend_summary_is_summary_query (bf->priv->summary, query)) {
- do_summary_query (bf, book_view);
- }
- else {
- FileBackendSearchClosure *closure = g_new0 (FileBackendSearchClosure, 1);
- DB *db = bf->priv->file_db;
- int db_error;
-
- closure->view = book_view;
- closure->bf = bf;
-
- db_error = db->cursor (db, NULL, &closure->dbc, 0);
-
- if (db_error != 0) {
- g_warning ("pas_backend_file_search: error building list\n");
- } else {
- g_idle_add (pas_backend_file_search_timeout, closure);
- }
- }
-}
-
static EContact *
do_create(PASBackendFile *bf,
const char *vcard_req)
@@ -509,11 +365,146 @@ pas_backend_file_get_contact_list (PASBackendSync *backend,
: GNOME_Evolution_Addressbook_Success;
}
+typedef struct {
+ GMutex *mutex;
+ gboolean stopped;
+} FileBackendSearchClosure;
+
static void
pas_backend_file_start_book_view (PASBackend *backend,
PASBookView *book_view)
{
- pas_backend_file_search (PAS_BACKEND_FILE (backend), book_view);
+ FileBackendSearchClosure *closure = g_new0 (FileBackendSearchClosure, 1);
+ PASBackendFile *bf = PAS_BACKEND_FILE (backend);
+ const char *query;
+ DB *db;
+ DBT id_dbt, vcard_dbt;
+ int db_error;
+ gboolean stopped = FALSE;
+
+ printf ("starting initial population of book view\n");
+
+ /* ref the book view because it'll be removed and unrefed
+ when/if it's stopped */
+ g_object_ref (book_view);
+
+ db = bf->priv->file_db;
+ query = pas_book_view_get_card_query (book_view);
+
+ closure->mutex = g_mutex_new();
+ closure->stopped = FALSE;
+ g_object_set_data (G_OBJECT (book_view), "PASBackendFile.BookView::closure", closure);
+
+ if ( ! strcmp (query, "(contains \"x-evolution-any-field\" \"\")"))
+ pas_book_view_notify_status_message (book_view, _("Loading..."));
+ else
+ pas_book_view_notify_status_message (book_view, _("Searching..."));
+
+ if (pas_backend_summary_is_summary_query (bf->priv->summary, query)) {
+ /* do a summary query */
+ GPtrArray *ids = pas_backend_summary_search (bf->priv->summary, pas_book_view_get_card_query (book_view));
+ int i;
+
+ for (i = 0; i < ids->len; i ++) {
+ char *id = g_ptr_array_index (ids, i);
+
+ g_mutex_lock (closure->mutex);
+ stopped = closure->stopped;
+ g_mutex_unlock (closure->mutex);
+
+ if (stopped) {
+ g_mutex_free (closure->mutex);
+ g_free (closure);
+ break;
+ }
+
+ string_to_dbt (id, &id_dbt);
+ memset (&vcard_dbt, 0, sizeof (vcard_dbt));
+
+ db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
+
+ if (db_error == 0) {
+ EContact *contact = e_contact_new_from_vcard (vcard_dbt.data);
+ pas_book_view_notify_update (book_view, contact);
+ g_object_unref (contact);
+ }
+ }
+
+ g_ptr_array_free (ids, TRUE);
+ }
+ else {
+ /* iterate over the db and do the query there */
+ DBC *dbc;
+
+ memset (&id_dbt, 0, sizeof (id_dbt));
+ memset (&vcard_dbt, 0, sizeof (vcard_dbt));
+
+ db_error = db->cursor (db, NULL, &dbc, 0);
+
+ db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST);
+ while (db_error == 0) {
+
+ g_mutex_lock (closure->mutex);
+ stopped = closure->stopped;
+ g_mutex_unlock (closure->mutex);
+
+ if (stopped) {
+ g_mutex_free (closure->mutex);
+ g_free (closure);
+ break;
+ }
+
+ /* don't include the version in the list of cards */
+ if (strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) {
+ char *vcard_string = vcard_dbt.data;
+ EContact *contact = e_contact_new_from_vcard (vcard_string);
+
+ /* notify_update will check if it matches for us */
+ pas_book_view_notify_update (book_view, contact);
+ g_object_unref (contact);
+ }
+
+ db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
+ }
+
+ dbc->c_close (dbc);
+
+ if (db_error != DB_NOTFOUND)
+ g_warning ("pas_backend_file_search: error building list\n");
+
+ }
+
+ g_mutex_lock (closure->mutex);
+ stopped = closure->stopped;
+ g_mutex_unlock (closure->mutex);
+ if (!stopped)
+ pas_book_view_notify_complete (book_view, GNOME_Evolution_Addressbook_Success);
+
+ g_mutex_free (closure->mutex);
+ g_free (closure);
+
+ g_object_set_data (G_OBJECT (book_view), "PASBackendFile.BookView::closure", NULL);
+
+ /* unref the */
+ g_object_unref (book_view);
+
+ printf ("finished initial population of book view\n");
+}
+
+static void
+pas_backend_file_stop_book_view (PASBackend *backend,
+ PASBookView *book_view)
+{
+ FileBackendSearchClosure *closure = g_object_get_data (G_OBJECT (book_view), "PASBackendFile.BookView::closure");
+ if (!closure) {
+ printf ("book view is already done populating\n");
+ return;
+ }
+
+ printf ("stopping book view!\n");
+ g_mutex_lock (closure->mutex);
+ closure->stopped = TRUE;
+ g_mutex_lock (closure->mutex);
}
typedef struct {
@@ -1108,6 +1099,7 @@ pas_backend_file_class_init (PASBackendFileClass *klass)
backend_class->load_uri = pas_backend_file_load_uri;
backend_class->get_static_capabilities = pas_backend_file_get_static_capabilities;
backend_class->start_book_view = pas_backend_file_start_book_view;
+ backend_class->stop_book_view = pas_backend_file_stop_book_view;
backend_class->cancel_operation = pas_backend_file_cancel_operation;
sync_class->remove_sync = pas_backend_file_remove;
diff --git a/addressbook/backend/pas/pas-backend-ldap.c b/addressbook/backend/pas/pas-backend-ldap.c
index 9c44e9983f..d4aa4ea82d 100644
--- a/addressbook/backend/pas/pas-backend-ldap.c
+++ b/addressbook/backend/pas/pas-backend-ldap.c
@@ -2820,6 +2820,13 @@ pas_backend_ldap_process_start_book_view (PASBackend *backend,
}
static void
+pas_backend_ldap_process_stop_book_view (PASBackend *backend,
+ PASBookView *view)
+{
+ /* FIXME we don't stop them... */
+}
+
+static void
pas_backend_ldap_process_get_changes (PASBackend *backend,
PASBook *book,
const char *change_id)
@@ -3146,6 +3153,7 @@ pas_backend_ldap_class_init (PASBackendLDAPClass *klass)
parent_class->modify_contact = pas_backend_ldap_process_modify_contact;
parent_class->get_contact = pas_backend_ldap_process_get_contact;
parent_class->start_book_view = pas_backend_ldap_process_start_book_view;
+ parent_class->stop_book_view = pas_backend_ldap_process_stop_book_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;
diff --git a/addressbook/backend/pas/pas-backend-summary.c b/addressbook/backend/pas/pas-backend-summary.c
index 15f12cebc1..268a0c7062 100644
--- a/addressbook/backend/pas/pas-backend-summary.c
+++ b/addressbook/backend/pas/pas-backend-summary.c
@@ -711,8 +711,6 @@ pas_backend_summary_add_contact (PASBackendSummary *summary, EContact *contact)
g_ptr_array_add (summary->priv->items, new_item);
g_hash_table_insert (summary->priv->id_to_item, new_item->id, new_item);
- g_object_unref (contact);
-
#ifdef SUMMARY_STATS
summary->priv->size += sizeof (PASBackendSummaryItem);
summary->priv->size += new_item->id ? strlen (new_item->id) : 0;
diff --git a/addressbook/backend/pas/pas-backend-vcf.c b/addressbook/backend/pas/pas-backend-vcf.c
index 3765fd978e..e82fe04f56 100644
--- a/addressbook/backend/pas/pas-backend-vcf.c
+++ b/addressbook/backend/pas/pas-backend-vcf.c
@@ -36,6 +36,7 @@ typedef struct _PASBackendVCFSearchContext PASBackendVCFSearchContext;
struct _PASBackendVCFPrivate {
char *uri;
char *filename;
+ GMutex *mutex;
GHashTable *contacts;
gboolean dirty;
int flush_timeout_tag;
@@ -122,13 +123,13 @@ insert_contact (PASBackendVCF *vcf, char *vcard)
}
static void
-load_file (PASBackendVCF *vcf)
+load_file (PASBackendVCF *vcf, int fd)
{
FILE *fp;
GString *str;
char buf[1024];
- fp = fopen (vcf->priv->filename, "r");
+ fp = fdopen (fd, "r");
if (!fp) {
g_warning ("failed to open `%s' for reading", vcf->priv->filename);
return;
@@ -160,30 +161,32 @@ load_file (PASBackendVCF *vcf)
static void
foreach_build_list (char *id, char *vcard_string, GList **list)
{
- *list = g_list_append (*list, e_contact_new_from_vcard (vcard_string));
+ *list = g_list_append (*list, vcard_string);
}
static gboolean
save_file (PASBackendVCF *vcf)
{
- GList *contacts = NULL;
+ GList *vcards = NULL;
GList *l;
char *new_path;
int fd, rv;
- g_hash_table_foreach (vcf->priv->contacts, (GHFunc)foreach_build_list, &contacts);
+ g_warning ("PASBackendVCF flushing file to disk");
+
+ g_mutex_lock (vcf->priv->mutex);
+ g_hash_table_foreach (vcf->priv->contacts, (GHFunc)foreach_build_list, &vcards);
new_path = g_strdup_printf ("%s.new", vcf->priv->filename);
fd = open (new_path, O_CREAT | O_TRUNC | O_WRONLY, 0666);
- for (l = contacts; l; l = l->next) {
- EContact *contact = l->data;
- char *vcard_str = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+ for (l = vcards; l; l = l->next) {
+ char *vcard_str = l->data;
int len = strlen (vcard_str);
rv = write (fd, vcard_str, len);
- g_free (vcard_str);
+
if (rv < len) {
/* XXX */
g_warning ("write failed. we need to handle short writes\n");
@@ -192,8 +195,8 @@ save_file (PASBackendVCF *vcf)
return FALSE;
}
- rv = write (fd, "\r\n", 2);
- if (rv < 2) {
+ rv = write (fd, "\r\n\r\n", 4);
+ if (rv < 4) {
/* XXX */
g_warning ("write failed. we need to handle short writes\n");
close (fd);
@@ -208,12 +211,13 @@ save_file (PASBackendVCF *vcf)
return FALSE;
}
- g_list_foreach (contacts, (GFunc)g_object_unref, NULL);
- g_list_free (contacts);
+ g_list_free (vcards);
g_free (new_path);
vcf->priv->dirty = FALSE;
+ g_mutex_unlock (vcf->priv->mutex);
+
return TRUE;
}
@@ -245,6 +249,10 @@ do_create(PASBackendVCF *bvcf,
EContact *contact;
char *vcard;
+ /* at the very least we need the unique_id generation to be
+ protected by the lock, even if the actual vcard parsing
+ isn't. */
+ g_mutex_lock (bvcf->priv->mutex);
id = pas_backend_vcf_create_unique_id ();
contact = e_contact_new_from_vcard (vcard_req);
@@ -261,6 +269,8 @@ do_create(PASBackendVCF *bvcf,
vcf_flush_file, bvcf);
}
+ g_mutex_unlock (bvcf->priv->mutex);
+
return contact;
}
@@ -292,8 +302,13 @@ pas_backend_vcf_process_remove_contacts (PASBackendSync *backend,
/* FIXME: make this handle bulk deletes like the file backend does */
PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend);
char *id = id_list->data;
+ gboolean success;
+
+ g_mutex_lock (bvcf->priv->mutex);
+ success = g_hash_table_remove (bvcf->priv->contacts, id);
- if (!g_hash_table_remove (bvcf->priv->contacts, id)) {
+ if (!success) {
+ g_mutex_unlock (bvcf->priv->mutex);
return GNOME_Evolution_Addressbook_ContactNotFound;
}
else {
@@ -301,6 +316,7 @@ pas_backend_vcf_process_remove_contacts (PASBackendSync *backend,
if (!bvcf->priv->flush_timeout_tag)
bvcf->priv->flush_timeout_tag = g_timeout_add (FILE_FLUSH_TIMEOUT,
vcf_flush_file, bvcf);
+ g_mutex_unlock (bvcf->priv->mutex);
*ids = g_list_append (*ids, id);
@@ -317,16 +333,26 @@ pas_backend_vcf_process_modify_contact (PASBackendSync *backend,
PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend);
char *old_id, *old_vcard_string;
const char *id;
+ gboolean success;
/* create a new ecard from the request data */
*contact = e_contact_new_from_vcard (vcard);
id = e_contact_get_const (*contact, E_CONTACT_UID);
- if (!g_hash_table_lookup_extended (bvcf->priv->contacts, id, (gpointer)&old_id, (gpointer)&old_vcard_string)) {
+ g_mutex_lock (bvcf->priv->mutex);
+ success = g_hash_table_lookup_extended (bvcf->priv->contacts, id, (gpointer)&old_id, (gpointer)&old_vcard_string);
+
+ if (!success) {
+ g_mutex_unlock (bvcf->priv->mutex);
return GNOME_Evolution_Addressbook_ContactNotFound;
}
else {
g_hash_table_insert (bvcf->priv->contacts, old_id, g_strdup (vcard));
+ bvcf->priv->dirty = TRUE;
+ if (!bvcf->priv->flush_timeout_tag)
+ bvcf->priv->flush_timeout_tag = g_timeout_add (FILE_FLUSH_TIMEOUT,
+ vcf_flush_file, bvcf);
+ g_mutex_unlock (bvcf->priv->mutex);
g_free (old_vcard_string);
@@ -400,6 +426,13 @@ pas_backend_vcf_start_book_view (PASBackend *backend,
pas_backend_vcf_search (PAS_BACKEND_VCF (backend), book_view);
}
+static void
+pas_backend_vcf_stop_book_view (PASBackend *backend,
+ PASBookView *book_view)
+{
+ /* XXX nothing here yet, and there should be. */
+}
+
static char *
pas_backend_vcf_extract_path_from_uri (const char *uri)
{
@@ -443,16 +476,17 @@ pas_backend_vcf_load_uri (PASBackend *backend,
gboolean only_if_exists)
{
PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend);
- char *filename;
+ char *dirname;
gboolean writable = FALSE;
int fd;
g_free(bvcf->priv->uri);
bvcf->priv->uri = g_strdup (uri);
- bvcf->priv->filename = filename = pas_backend_vcf_extract_path_from_uri (uri);
+ dirname = pas_backend_vcf_extract_path_from_uri (uri);
+ bvcf->priv->filename = g_build_filename (dirname, "addressbook.vcf", NULL);
- fd = open (filename, O_RDWR);
+ fd = open (bvcf->priv->filename, O_RDWR);
bvcf->priv->contacts = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_free);
@@ -460,10 +494,10 @@ pas_backend_vcf_load_uri (PASBackend *backend,
if (fd != -1) {
writable = TRUE;
} else {
- fd = open (filename, O_RDONLY);
+ fd = open (bvcf->priv->filename, O_RDONLY);
if (fd == -1) {
- fd = open (filename, O_CREAT, 0666);
+ fd = open (bvcf->priv->filename, O_CREAT, 0666);
if (fd != -1 && !only_if_exists) {
EContact *contact;
@@ -485,8 +519,7 @@ pas_backend_vcf_load_uri (PASBackend *backend,
return GNOME_Evolution_Addressbook_OtherError;
}
- close (fd); /* XXX ugh */
- load_file (bvcf);
+ load_file (bvcf, fd);
pas_backend_set_is_loaded (backend, TRUE);
pas_backend_set_is_writable (backend, writable);
@@ -546,17 +579,25 @@ pas_backend_vcf_dispose (GObject *object)
if (bvcf->priv) {
- if (bvcf->priv->dirty)
- save_file (bvcf);
+ g_mutex_lock (bvcf->priv->mutex);
if (bvcf->priv->flush_timeout_tag) {
g_source_remove (bvcf->priv->flush_timeout_tag);
bvcf->priv->flush_timeout_tag = 0;
}
+ if (bvcf->priv->dirty)
+ save_file (bvcf);
+
+ g_hash_table_destroy (bvcf->priv->contacts);
+
g_free (bvcf->priv->uri);
g_free (bvcf->priv->filename);
+ g_mutex_unlock (bvcf->priv->mutex);
+
+ g_mutex_free (bvcf->priv->mutex);
+
g_free (bvcf->priv);
bvcf->priv = NULL;
}
@@ -580,6 +621,7 @@ pas_backend_vcf_class_init (PASBackendVCFClass *klass)
backend_class->load_uri = pas_backend_vcf_load_uri;
backend_class->get_static_capabilities = pas_backend_vcf_get_static_capabilities;
backend_class->start_book_view = pas_backend_vcf_start_book_view;
+ backend_class->stop_book_view = pas_backend_vcf_stop_book_view;
backend_class->cancel_operation = pas_backend_vcf_cancel_operation;
sync_class->create_contact_sync = pas_backend_vcf_process_create_contact;
@@ -598,8 +640,9 @@ pas_backend_vcf_init (PASBackendVCF *backend)
{
PASBackendVCFPrivate *priv;
- priv = g_new0 (PASBackendVCFPrivate, 1);
- priv->uri = NULL;
+ priv = g_new0 (PASBackendVCFPrivate, 1);
+ priv->uri = NULL;
+ priv->mutex = g_mutex_new();
backend->priv = priv;
}
diff --git a/addressbook/backend/pas/pas-backend.c b/addressbook/backend/pas/pas-backend.c
index 076565de07..5b559940d1 100644
--- a/addressbook/backend/pas/pas-backend.c
+++ b/addressbook/backend/pas/pas-backend.c
@@ -201,6 +201,18 @@ pas_backend_start_book_view (PASBackend *backend,
}
void
+pas_backend_stop_book_view (PASBackend *backend,
+ PASBookView *book_view)
+{
+ g_return_if_fail (backend && PAS_IS_BACKEND (backend));
+ g_return_if_fail (book_view && PAS_IS_BOOK_VIEW (book_view));
+
+ g_assert (PAS_BACKEND_GET_CLASS (backend)->stop_book_view);
+
+ (* PAS_BACKEND_GET_CLASS (backend)->stop_book_view) (backend, book_view);
+}
+
+void
pas_backend_get_changes (PASBackend *backend,
PASBook *book,
const char *change_id)
@@ -308,6 +320,17 @@ pas_backend_add_book_view (PASBackend *backend,
g_mutex_unlock (backend->priv->views_mutex);
}
+void
+pas_backend_remove_book_view (PASBackend *backend,
+ PASBookView *view)
+{
+ g_mutex_lock (backend->priv->views_mutex);
+
+ e_list_remove (backend->priv->views, view);
+
+ g_mutex_unlock (backend->priv->views_mutex);
+}
+
/**
* pas_backend_add_client:
* @backend: An addressbook backend.
diff --git a/addressbook/backend/pas/pas-backend.h b/addressbook/backend/pas/pas-backend.h
index 41f6542213..b71d438441 100644
--- a/addressbook/backend/pas/pas-backend.h
+++ b/addressbook/backend/pas/pas-backend.h
@@ -58,6 +58,7 @@ struct _PASBackendClass {
void (*get_contact) (PASBackend *backend, PASBook *book, const char *id);
void (*get_contact_list) (PASBackend *backend, PASBook *book, const char *query);
void (*start_book_view) (PASBackend *backend, PASBookView *book_view);
+ void (*stop_book_view) (PASBackend *backend, PASBookView *book_view);
void (*get_changes) (PASBackend *backend, PASBook *book, const char *change_id);
void (*authenticate_user) (PASBackend *backend, PASBook *book, const char *user, const char *passwd, const char *auth_method);
void (*get_supported_fields) (PASBackend *backend, PASBook *book);
@@ -134,10 +135,15 @@ GNOME_Evolution_Addressbook_CallStatus pas_backend_cancel_operation (PASBackend
void pas_backend_start_book_view (PASBackend *backend,
PASBookView *view);
+void pas_backend_stop_book_view (PASBackend *backend,
+ PASBookView *view);
void pas_backend_add_book_view (PASBackend *backend,
PASBookView *view);
+void pas_backend_remove_book_view (PASBackend *backend,
+ PASBookView *view);
+
EList *pas_backend_get_book_views (PASBackend *backend);
void pas_backend_notify_update (PASBackend *backend,
diff --git a/addressbook/backend/pas/pas-book-view.c b/addressbook/backend/pas/pas-book-view.c
index 712997d258..afdfb1dacb 100644
--- a/addressbook/backend/pas/pas-book-view.c
+++ b/addressbook/backend/pas/pas-book-view.c
@@ -19,6 +19,8 @@ struct _PASBookViewPrivate {
GNOME_Evolution_Addressbook_BookViewListener listener;
#define INITIAL_THRESHOLD 20
+#define THRESHOLD_MAX 3000
+
GMutex *pending_mutex;
CORBA_sequence_GNOME_Evolution_Addressbook_VCard adds;
@@ -339,6 +341,15 @@ impl_GNOME_Evolution_Addressbook_BookView_start (PortableServer_Servant servant,
pas_backend_start_book_view (pas_book_view_get_backend (view), view);
}
+static void
+impl_GNOME_Evolution_Addressbook_BookView_stop (PortableServer_Servant servant,
+ CORBA_Environment *ev)
+{
+ PASBookView *view = PAS_BOOK_VIEW (bonobo_object (servant));
+
+ pas_backend_stop_book_view (pas_book_view_get_backend (view), view);
+}
+
/**
* pas_book_view_get_card_query
*/
@@ -363,6 +374,12 @@ pas_book_view_get_backend (PASBookView *book_view)
return book_view->priv->backend;
}
+GNOME_Evolution_Addressbook_BookViewListener
+pas_book_view_get_listener (PASBookView *book_view)
+{
+ return book_view->priv->listener;
+}
+
/**
* pas_book_view_new:
*/
@@ -423,6 +440,7 @@ pas_book_view_class_init (PASBookViewClass *klass)
epv = &klass->epv;
epv->start = impl_GNOME_Evolution_Addressbook_BookView_start;
+ epv->stop = impl_GNOME_Evolution_Addressbook_BookView_stop;
}
@@ -434,7 +452,7 @@ pas_book_view_init (PASBookView *book_view)
book_view->priv->pending_mutex = g_mutex_new();
book_view->priv->next_threshold = INITIAL_THRESHOLD;
- book_view->priv->threshold_max = 3000;
+ book_view->priv->threshold_max = THRESHOLD_MAX;
book_view->priv->ids = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, NULL);
diff --git a/addressbook/backend/pas/pas-book-view.h b/addressbook/backend/pas/pas-book-view.h
index 0cacab6bf0..3b292d11db 100644
--- a/addressbook/backend/pas/pas-book-view.h
+++ b/addressbook/backend/pas/pas-book-view.h
@@ -48,6 +48,7 @@ PASBookView *pas_book_view_new (PASBackend *b
const char* pas_book_view_get_card_query (PASBookView *book_view);
PASBackendCardSExp* pas_book_view_get_card_sexp (PASBookView *book_view);
PASBackend* pas_book_view_get_backend (PASBookView *book_view);
+GNOME_Evolution_Addressbook_BookViewListener pas_book_view_get_listener (PASBookView *book_view);
void pas_book_view_notify_update (PASBookView *book_view,
EContact *contact);
diff --git a/addressbook/backend/pas/pas-book.c b/addressbook/backend/pas/pas-book.c
index 7b6e0c9a2b..08078887b6 100644
--- a/addressbook/backend/pas/pas-book.c
+++ b/addressbook/backend/pas/pas-book.c
@@ -42,7 +42,7 @@ impl_GNOME_Evolution_Addressbook_Book_remove (PortableServer_Servant servant,
{
PASBook *book = PAS_BOOK (bonobo_object (servant));
- printf ("impl_GNOME_Evolution_Addressbook_Book_open\n");
+ printf ("impl_GNOME_Evolution_Addressbook_Book_remove\n");
pas_backend_remove (pas_book_get_backend (book), book);
}
@@ -122,6 +122,15 @@ impl_GNOME_Evolution_Addressbook_Book_modifyContact (PortableServer_Servant serv
}
static void
+view_listener_died_cb (gpointer cnx, gpointer user_data)
+{
+ PASBookView *book_view = PAS_BOOK_VIEW (user_data);
+
+ pas_backend_stop_book_view (pas_book_view_get_backend (book_view), book_view);
+ pas_backend_remove_book_view (pas_book_view_get_backend (book_view), book_view);
+}
+
+static void
impl_GNOME_Evolution_Addressbook_Book_getBookView (PortableServer_Servant servant,
const GNOME_Evolution_Addressbook_BookViewListener listener,
const CORBA_char *search,
@@ -154,6 +163,7 @@ impl_GNOME_Evolution_Addressbook_Book_getBookView (PortableServer_Servant servan
return;
}
+ ORBit_small_listen_for_broken (pas_book_view_get_listener (view), G_CALLBACK (view_listener_died_cb), view);
pas_backend_add_book_view (backend, view);
@@ -298,7 +308,7 @@ pas_book_respond_create (PASBook *book,
GNOME_Evolution_Addressbook_BookListener_notifyContactCreated (
book->priv->listener, status,
- e_contact_get (contact, E_CONTACT_UID), &ev);
+ e_contact_get_const (contact, E_CONTACT_UID), &ev);
if (ev._major != CORBA_NO_EXCEPTION) {
g_warning ("pas_book_respond_create: Exception "