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;
}
/**
 * e_book_backend_db_cache_get_contacts:
 * @db: DB Handle
 * @query: an s-expression
 *
 * Returns a list of #EContact elements from @cache matching @query.
 * When done with the list, the caller must unref the contacts and
 * free the list.
 *
 * Returns: A #GList of pointers to #EContact.
 **/
GList *
e_book_backend_db_cache_get_contacts (DB *db,
                                      const gchar *query)
{
	DBC	*dbc;
	DBT	uid_dbt, vcard_dbt;
	gint	db_error;
	GList *list = NULL;
	EBookBackendSExp *sexp = NULL;
	EContact *contact;

	if (query) {
		sexp = e_book_backend_sexp_new (query);
		if (!sexp)
			return NULL;
	}

	db_error = db->cursor (db, NULL, &dbc, 0);
	if (db_error != 0) {
		g_warning ("db->cursor failed with %d", db_error);
		if (sexp)
			g_object_unref (sexp);
		return NULL;
	}

	memset (&vcard_dbt, 0 , sizeof (vcard_dbt));
	memset (&uid_dbt, 0, sizeof (uid_dbt));
	db_error = dbc->c_get (dbc, &uid_dbt, &vcard_dbt, DB_FIRST);

	while (db_error == 0) {
		if (vcard_dbt.data && !strncmp (vcard_dbt.data, "BEGIN:VCARD", 11)) {
			contact = e_contact_new_from_vcard (vcard_dbt.data);

			if (!sexp || e_book_backend_sexp_match_contact (sexp, contact))
				list = g_list_prepend (list, contact);
			else
				g_object_unref (contact);
		}
		db_error = dbc->c_get (dbc, &uid_dbt, &vcard_dbt, DB_NEXT);
	}

	db_error = dbc->c_close (dbc);
	if (db_error != 0)
		g_warning ("db->c_close failed with %d", db_error);

	if (sexp)
		g_object_unref (sexp);

	return g_list_reverse (list);
}
static void
e_book_backend_vcf_get_contact_list (EBookBackendSync *backend,
				     EDataBook *book,
				     guint32 opid,
				     const gchar *query,
				     GList **contacts,
				     GError **perror)
{
	EBookBackendVCF *bvcf = E_BOOK_BACKEND_VCF (backend);
	const gchar *search = query;
	GetContactListClosure closure;

	closure.bvcf = bvcf;
	closure.search_needed = strcmp (search, "(contains \"x-evolution-any-field\" \"\")");
	closure.card_sexp = e_book_backend_sexp_new (search);
	closure.list = NULL;

	g_list_foreach (bvcf->priv->contact_list, (GFunc)foreach_get_contact_compare, &closure);

	g_object_unref (closure.card_sexp);

	*contacts = closure.list;
}
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;
}