From 200606f92810d3de322e5ee96f8326e1a656f8bb Mon Sep 17 00:00:00 2001 From: JP Rosevear Date: Fri, 7 Nov 2003 05:52:24 +0000 Subject: Various changes to merge in evolution-data-server reliance. svn path=/trunk/; revision=23206 --- addressbook/backend/pas/.cvsignore | 13 - addressbook/backend/pas/Makefile.am | 109 - addressbook/backend/pas/TODO | 2 - addressbook/backend/pas/evolutionperson.schema | 212 -- addressbook/backend/pas/pas-backend-card-sexp.c | 482 ---- addressbook/backend/pas/pas-backend-card-sexp.h | 56 - addressbook/backend/pas/pas-backend-file.c | 1169 --------- addressbook/backend/pas/pas-backend-file.h | 32 - addressbook/backend/pas/pas-backend-ldap.c | 3206 ----------------------- addressbook/backend/pas/pas-backend-ldap.h | 32 - addressbook/backend/pas/pas-backend-summary.c | 1078 -------- addressbook/backend/pas/pas-backend-summary.h | 72 - addressbook/backend/pas/pas-backend-sync.c | 395 --- addressbook/backend/pas/pas-backend-sync.h | 81 - addressbook/backend/pas/pas-backend-vcf.c | 675 ----- addressbook/backend/pas/pas-backend-vcf.h | 35 - addressbook/backend/pas/pas-backend.c | 671 ----- addressbook/backend/pas/pas-backend.h | 173 -- addressbook/backend/pas/pas-book-factory.c | 471 ---- addressbook/backend/pas/pas-book-factory.h | 53 - addressbook/backend/pas/pas-book-view.c | 465 ---- addressbook/backend/pas/pas-book-view.h | 64 - addressbook/backend/pas/pas-book.c | 770 ------ addressbook/backend/pas/pas-book.h | 96 - addressbook/backend/pas/pas-marshal.list | 2 - addressbook/backend/pas/pas-types.h | 32 - addressbook/backend/pas/ximian-vcard.h | 81 - 27 files changed, 10527 deletions(-) delete mode 100644 addressbook/backend/pas/.cvsignore delete mode 100644 addressbook/backend/pas/Makefile.am delete mode 100644 addressbook/backend/pas/TODO delete mode 100644 addressbook/backend/pas/evolutionperson.schema delete mode 100644 addressbook/backend/pas/pas-backend-card-sexp.c delete mode 100644 addressbook/backend/pas/pas-backend-card-sexp.h delete mode 100644 addressbook/backend/pas/pas-backend-file.c delete mode 100644 addressbook/backend/pas/pas-backend-file.h delete mode 100644 addressbook/backend/pas/pas-backend-ldap.c delete mode 100644 addressbook/backend/pas/pas-backend-ldap.h delete mode 100644 addressbook/backend/pas/pas-backend-summary.c delete mode 100644 addressbook/backend/pas/pas-backend-summary.h delete mode 100644 addressbook/backend/pas/pas-backend-sync.c delete mode 100644 addressbook/backend/pas/pas-backend-sync.h delete mode 100644 addressbook/backend/pas/pas-backend-vcf.c delete mode 100644 addressbook/backend/pas/pas-backend-vcf.h delete mode 100644 addressbook/backend/pas/pas-backend.c delete mode 100644 addressbook/backend/pas/pas-backend.h delete mode 100644 addressbook/backend/pas/pas-book-factory.c delete mode 100644 addressbook/backend/pas/pas-book-factory.h delete mode 100644 addressbook/backend/pas/pas-book-view.c delete mode 100644 addressbook/backend/pas/pas-book-view.h delete mode 100644 addressbook/backend/pas/pas-book.c delete mode 100644 addressbook/backend/pas/pas-book.h delete mode 100644 addressbook/backend/pas/pas-marshal.list delete mode 100644 addressbook/backend/pas/pas-types.h delete mode 100644 addressbook/backend/pas/ximian-vcard.h (limited to 'addressbook/backend/pas') diff --git a/addressbook/backend/pas/.cvsignore b/addressbook/backend/pas/.cvsignore deleted file mode 100644 index 6eb58802ec..0000000000 --- a/addressbook/backend/pas/.cvsignore +++ /dev/null @@ -1,13 +0,0 @@ -.deps -.libs -.pure -Makefile -Makefile.in -addressbook-stubs.c -addressbook-skels.c -addressbook-common.c -addressbook.h -*.lo -*.la -pas-marshal.c -pas-marshal.h \ No newline at end of file diff --git a/addressbook/backend/pas/Makefile.am b/addressbook/backend/pas/Makefile.am deleted file mode 100644 index 269bb8656f..0000000000 --- a/addressbook/backend/pas/Makefile.am +++ /dev/null @@ -1,109 +0,0 @@ -CORBA_SOURCE_H = addressbook.h - -CORBA_SOURCE_C = \ - addressbook-common.c \ - addressbook-stubs.c \ - addressbook-skels.c - -CORBA_SOURCE = $(CORBA_SOURCE_H) $(CORBA_SOURCE_C) - -idls = \ - $(srcdir)/../idl/addressbook.idl - -$(CORBA_SOURCE_H): $(idls) - $(ORBIT_IDL) $(IDL_INCLUDES) -I $(srcdir) $(srcdir)/../idl/addressbook.idl - -$(CORBA_SOURCE_C): $(CORBA_SOURCE_H) - - -INCLUDES = \ - $(DB3_CFLAGS) \ - $(LDAP_CFLAGS) \ - -DG_LOG_DOMAIN=\"wombat-pas\" \ - -I$(top_srcdir) \ - -I$(top_srcdir)/addressbook/backend \ - -I$(top_builddir)/addressbook/backend \ - -DG_DISABLE_DEPRECATED \ - -DLIBGNOME_DISABLE_DEPRECATED \ - $(EVOLUTION_ADDRESSBOOK_CFLAGS) - -LDAP_SCHEMA = \ - evolutionperson.schema - -LDAP_BACKEND_FILES = \ - pas-backend-ldap.c \ - pas-backend-ldap.h - -if ENABLE_LDAP -LDAP_BACKEND = libpasldap.la -endif - -ldapschemadir = $(privdatadir) -ldapschema_DATA= $(LDAP_SCHEMA) - -privlib_LTLIBRARIES = libpas.la -noinst_LTLIBRARIES = libpasfile.la libpasvcf.la $(LDAP_BACKEND) - -pasincludedir = $(privincludedir)/pas - -pasinclude_HEADERS = \ - $(CORBA_SOURCE_H) \ - pas-book-factory.h \ - pas-book-view.h \ - pas-book.h \ - pas-backend-card-sexp.h \ - pas-backend.h \ - pas-backend-summary.h \ - pas-backend-sync.h \ - pas-types.h - -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.c \ - pas-backend-summary.c \ - pas-backend-sync.c \ - pas-marshal.c \ - ximian-vcard.h - -libpas_la_LIBADD = \ - $(top_builddir)/addressbook/backend/ebook/libebook.la - -libpasfile_la_SOURCES = \ - pas-backend-file.c \ - pas-backend-file.h - -libpasfile_la_LIBADD = \ - libpas.la \ - $(top_builddir)/e-util/libedb3util.la - -libpasvcf_la_SOURCES = \ - pas-backend-vcf.c \ - pas-backend-vcf.h - -libpasvcf_la_LIBADD = \ - libpas.la - -if ENABLE_LDAP -libpasldap_la_SOURCES = \ - $(LDAP_BACKEND_FILES) - -libpasldap_la_LIBADD = \ - libpas.la \ - $(LDAP_LIBS) -endif - -MARSHAL_GENERATED = pas-marshal.c pas-marshal.h -@EVO_MARSHAL_RULE@ - -BUILT_SOURCES = $(CORBA_SOURCE) $(MARSHAL_GENERATED) -CLEANFILES = $(BUILT_SOURCES) - -dist-hook: - cd $(distdir); rm -f $(BUILT_SOURCES) - -EXTRA_DIST = $(LDAP_BACKEND_FILES) $(LDAP_SCHEMA) pas-marshal.list diff --git a/addressbook/backend/pas/TODO b/addressbook/backend/pas/TODO deleted file mode 100644 index 0c77c1b200..0000000000 --- a/addressbook/backend/pas/TODO +++ /dev/null @@ -1,2 +0,0 @@ -* Implement pas_book_factory_activate -* Authentication \ No newline at end of file diff --git a/addressbook/backend/pas/evolutionperson.schema b/addressbook/backend/pas/evolutionperson.schema deleted file mode 100644 index cc32a96262..0000000000 --- a/addressbook/backend/pas/evolutionperson.schema +++ /dev/null @@ -1,212 +0,0 @@ -# -# Depends upon -# Definition of an X.500 Attribute Type and an Object Class to Hold -# Uniform Resource Identifiers (URIs) [RFC2079] -# (core.schema) -# -# A Summary of the X.500(96) User Schema for use with LDAPv3 [RFC2256] -# (core.schema) -# -# The COSINE and Internet X.500 Schema [RFC1274] (cosine.schema) -# -# The Internet Organizational Person Schema (inetorgperson) -# -# OIDs are broken up into the following: -# 1.3.6.1.4.1.8506.1.? -# .1 Syntaxes -# .2 Attributes -# .3 Objectclasses - -# primaryPhone -attributetype ( 1.3.6.1.4.1.8506.1.2.1 - NAME 'primaryPhone' - DESC 'preferred phone number used to contact a person' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 - SINGLE-VALUE ) - -# carPhone -attributetype ( 1.3.6.1.4.1.8506.1.2.2 - NAME 'carPhone' - DESC 'car phone telephone number of the person' - EQUALITY telephoneNumberMatch - SUBSTR telephoneNumberSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 - SINGLE-VALUE ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.3 - NAME ( 'homeFacsimileTelephoneNumber' 'homeFax' ) - SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.4 - NAME 'otherPhone' - EQUALITY telephoneNumberMatch - SUBSTR telephoneNumberSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.5 - NAME 'businessRole' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.6 - NAME 'managerName' - SUP name ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.7 - NAME 'assistantName' - SUP name ) - -# spouseName -# single valued (/me smirks) -attributetype ( 1.3.6.1.4.1.8506.1.2.8 - NAME 'spouseName' - SUP name - SINGLE-VALUE ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.9 - NAME 'otherPostalAddress' - EQUALITY caseIgnoreListMatch - SUBSTR caseIgnoreListSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.10 - NAME ( 'mailer' 'mua' ) - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32} ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.11 - NAME ( 'birthDate' 'dob' ) - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.12 - NAME 'anniversary' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.13 - NAME 'note' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.14 - NAME 'evolutionArbitrary' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} ) - ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.15 - NAME 'fileAs' - SUP name ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.16 - NAME 'assistantPhone' - EQUALITY telephoneNumberMatch - SUBSTR telephoneNumberSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.17 - NAME 'companyPhone' - EQUALITY telephoneNumberMatch - SUBSTR telephoneNumberSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.18 - NAME 'callbackPhone' - EQUALITY telephoneNumberMatch - SUBSTR telephoneNumberSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.19 - NAME ( 'otherFacsimileTelephoneNumber' 'otherFax' ) - SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.20 - NAME 'radio' - EQUALITY telephoneNumberMatch - SUBSTR telephoneNumberSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.21 - NAME 'telex' - EQUALITY telephoneNumberMatch - SUBSTR telephoneNumberSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.22 - NAME 'tty' - EQUALITY telephoneNumberMatch - SUBSTR telephoneNumberSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 ) - -# deprecated - use the multivalued category -attributetype ( 1.3.6.1.4.1.8506.1.2.23 - NAME 'categories' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.24 - NAME 'contact' - EQUALITY distinguishedNameMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.25 - NAME 'listName' - SUP name - SINGLE-VALUE ) - -# deprecated - use calEntry and its attributes from RFC 2739 -attributetype ( 1.3.6.1.4.1.8506.1.2.26 - NAME 'calendarURI' - EQUALITY caseExactIA5Match - SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 - SINGLE-VALUE ) - -# deprecated - use calEntry and its attributes from RFC 2739 -attributetype ( 1.3.6.1.4.1.8506.1.2.27 - NAME 'freeBusyURI' - EQUALITY caseExactIA5Match - SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 - SINGLE-VALUE ) - -attributetype ( 1.3.6.1.4.1.8506.1.2.28 - NAME 'category' - EQUALITY caseIgnoreMatch - SUBSTR caseIgnoreSubstringsMatch - SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} ) - - -# evolutionPerson -objectclass ( 1.3.6.1.4.1.8506.1.3.1 - NAME 'evolutionPerson' - DESC 'Objectclass geared to Evolution Usage' - SUP inetOrgPerson - STRUCTURAL - MAY ( - fileAs $ primaryPhone $ carPhone $ homeFacsimileTelephoneNumber $ - otherPhone $ businessRole $ managerName $ assistantName $ assistantPhone $ - otherPostalAddress $ mailer $ birthDate $ anniversary $ spouseName $ - note $ companyPhone $ callbackPhone $ otherFacsimileTelephoneNumber $ - radio $ telex $ tty $ categories $ category $ calendarURI $ freeBusyURI ) - ) - -# evolutionPersonList -objectclass ( 1.3.6.1.4.1.8506.1.3.2 - NAME 'evolutionPersonList' - DESC 'Objectclass geared to Evolution Contact Lists' - SUP top - STRUCTURAL - MUST ( - listName ) - MAY ( - mail $ contact ) - ) diff --git a/addressbook/backend/pas/pas-backend-card-sexp.c b/addressbook/backend/pas/pas-backend-card-sexp.c deleted file mode 100644 index 1ccb4f2433..0000000000 --- a/addressbook/backend/pas/pas-backend-card-sexp.c +++ /dev/null @@ -1,482 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * pas-backend-card-sexp.c - * Copyright 1999, 2000, 2001, Ximian, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#include "pas-backend-card-sexp.h" - -#include -#include -#include - -static GObjectClass *parent_class; - -typedef struct _SearchContext SearchContext; - -struct _PASBackendCardSExpPrivate { - ESExp *search_sexp; - SearchContext *search_context; -}; - -struct _SearchContext { - EContact *contact; -}; - -static gboolean -compare_email (EContact *contact, const char *str, - char *(*compare)(const char*, const char*)) -{ - int i; - - for (i = E_CONTACT_EMAIL_1; i <= E_CONTACT_EMAIL_3; i ++) { - const char *email = e_contact_get_const (contact, i); - - if (email && compare(email, str)) - return TRUE; - } - - return FALSE; -} - -static gboolean -compare_phone (EContact *contact, const char *str, - char *(*compare)(const char*, const char*)) -{ - int i; - gboolean rv = FALSE; - - for (i = E_CONTACT_FIRST_PHONE_ID; i <= E_CONTACT_LAST_PHONE_ID; i ++) { - char *phone = e_contact_get (contact, i); - - rv = phone && compare(phone, str); - g_free (phone); - - if (rv) - break; - } - - return rv; -} - -static gboolean -compare_name (EContact *contact, const char *str, - char *(*compare)(const char*, const char*)) -{ - const char *name; - - name = e_contact_get_const (contact, E_CONTACT_FULL_NAME); - if (name && compare (name, str)) - return TRUE; - - name = e_contact_get_const (contact, E_CONTACT_FAMILY_NAME); - if (name && compare (name, str)) - return TRUE; - - return FALSE; -} - -static gboolean -compare_address (EContact *contact, const char *str, - char *(*compare)(const char*, const char*)) -{ - g_warning("address searching not implemented\n"); - return FALSE; -} - -static gboolean -compare_category (EContact *contact, const char *str, - char *(*compare)(const char*, const char*)) -{ - GList *categories; - GList *iterator; - gboolean ret_val = FALSE; - - categories = e_contact_get (contact, E_CONTACT_CATEGORY_LIST); - - for (iterator = categories; iterator; iterator = iterator->next) { - const char *category = iterator->data; - - if (compare(category, str)) { - ret_val = TRUE; - break; - } - } - - g_list_foreach (categories, (GFunc)g_free, NULL); - g_list_free (categories); - - return ret_val; -} - -static struct prop_info { - EContactField field_id; - const char *query_prop; -#define PROP_TYPE_NORMAL 0x01 -#define PROP_TYPE_LIST 0x02 - int prop_type; - gboolean (*list_compare)(EContact *contact, const char *str, - char *(*compare)(const char*, const char*)); - -} prop_info_table[] = { -#define NORMAL_PROP(f,q) {f, q, PROP_TYPE_NORMAL, NULL} -#define LIST_PROP(q,c) {0, q, PROP_TYPE_LIST, c} - - /* query prop, type, list compare function */ - NORMAL_PROP ( E_CONTACT_FILE_AS, "file_as" ), - LIST_PROP ( "full_name", compare_name), /* not really a list, but we need to compare both full and surname */ - NORMAL_PROP ( E_CONTACT_HOMEPAGE_URL, "url"), - NORMAL_PROP ( E_CONTACT_MAILER, "mailer"), - NORMAL_PROP ( E_CONTACT_ORG, "org"), - NORMAL_PROP ( E_CONTACT_ORG_UNIT, "org_unit"), - NORMAL_PROP ( E_CONTACT_OFFICE, "office"), - NORMAL_PROP ( E_CONTACT_TITLE, "title"), - NORMAL_PROP ( E_CONTACT_ROLE, "role"), - NORMAL_PROP ( E_CONTACT_MANAGER, "manager"), - NORMAL_PROP ( E_CONTACT_ASSISTANT, "assistant"), - NORMAL_PROP ( E_CONTACT_NICKNAME, "nickname"), - NORMAL_PROP ( E_CONTACT_SPOUSE, "spouse" ), - NORMAL_PROP ( E_CONTACT_NOTE, "note"), - NORMAL_PROP ( E_CONTACT_UID, "id"), - LIST_PROP ( "email", compare_email ), - LIST_PROP ( "phone", compare_phone ), - LIST_PROP ( "address", compare_address ), - LIST_PROP ( "category", compare_category ), -}; -static int num_prop_infos = sizeof(prop_info_table) / sizeof(prop_info_table[0]); - -static ESExpResult * -entry_compare(SearchContext *ctx, struct _ESExp *f, - int argc, struct _ESExpResult **argv, - char *(*compare)(const char*, const char*)) -{ - ESExpResult *r; - int truth = FALSE; - - if (argc == 2 - && argv[0]->type == ESEXP_RES_STRING - && argv[1]->type == ESEXP_RES_STRING) { - char *propname; - struct prop_info *info = NULL; - int i; - gboolean any_field; - - propname = argv[0]->value.string; - - any_field = !strcmp(propname, "x-evolution-any-field"); - for (i = 0; i < num_prop_infos; i ++) { - if (any_field - || !strcmp (prop_info_table[i].query_prop, propname)) { - info = &prop_info_table[i]; - - if (info->prop_type == PROP_TYPE_NORMAL) { - const char *prop = NULL; - /* straight string property matches */ - - prop = e_contact_get_const (ctx->contact, info->field_id); - - if (prop && compare(prop, argv[1]->value.string)) { - truth = TRUE; - } - if ((!prop) && compare("", argv[1]->value.string)) { - truth = TRUE; - } - } - else if (info->prop_type == PROP_TYPE_LIST) { - /* the special searches that match any of the list elements */ - truth = info->list_compare (ctx->contact, argv[1]->value.string, compare); - } - - /* if we're looking at all fields and find a match, - or if we're just looking at this one field, - break. */ - if ((any_field && truth) - || !any_field) - break; - } - } - - } - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = truth; - - return r; -} - -static ESExpResult * -func_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - SearchContext *ctx = data; - - return entry_compare (ctx, f, argc, argv, (char *(*)(const char*, const char*)) e_utf8_strstrcase); -} - -static char * -is_helper (const char *s1, const char *s2) -{ - if (!strcasecmp(s1, s2)) - return (char*)s1; - else - return NULL; -} - -static ESExpResult * -func_is(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - SearchContext *ctx = data; - - return entry_compare (ctx, f, argc, argv, is_helper); -} - -static char * -endswith_helper (const char *s1, const char *s2) -{ - char *p; - if ((p = (char*)e_utf8_strstrcase(s1, s2)) - && (strlen(p) == strlen(s2))) - return p; - else - return NULL; -} - -static ESExpResult * -func_endswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - SearchContext *ctx = data; - - return entry_compare (ctx, f, argc, argv, endswith_helper); -} - -static char * -beginswith_helper (const char *s1, const char *s2) -{ - char *p; - if ((p = (char*)e_utf8_strstrcase(s1, s2)) - && (p == s1)) - return p; - else - return NULL; -} - -static ESExpResult * -func_beginswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - SearchContext *ctx = data; - - return entry_compare (ctx, f, argc, argv, beginswith_helper); -} - -static ESExpResult * -func_exists(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - SearchContext *ctx = data; - ESExpResult *r; - int truth = FALSE; - - if (argc == 1 - && argv[0]->type == ESEXP_RES_STRING) { - char *propname; - struct prop_info *info = NULL; - int i; - - propname = argv[0]->value.string; - - for (i = 0; i < num_prop_infos; i ++) { - if (!strcmp (prop_info_table[i].query_prop, propname)) { - info = &prop_info_table[i]; - - if (info->prop_type == PROP_TYPE_NORMAL) { - const char *prop = NULL; - /* searches where the query's property - maps directly to an ecard property */ - - prop = e_contact_get_const (ctx->contact, info->field_id); - - if (prop && *prop) - truth = TRUE; - } - else if (info->prop_type == PROP_TYPE_LIST) { - /* the special searches that match any of the list elements */ - truth = info->list_compare (ctx->contact, "", (char *(*)(const char*, const char*)) e_utf8_strstrcase); - } - - break; - } - } - - } - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = truth; - - return r; -} - -/* 'builtin' functions */ -static struct { - char *name; - ESExpFunc *func; - int type; /* set to 1 if a function can perform shortcut evaluation, or - doesn't execute everything, 0 otherwise */ -} symbols[] = { - { "contains", func_contains, 0 }, - { "is", func_is, 0 }, - { "beginswith", func_beginswith, 0 }, - { "endswith", func_endswith, 0 }, - { "exists", func_exists, 0 }, -}; - -gboolean -pas_backend_card_sexp_match_contact (PASBackendCardSExp *sexp, EContact *contact) -{ - ESExpResult *r; - gboolean retval; - - if (!contact) { - g_warning ("null EContact passed to pas_backend_card_sexp_match_contact"); - return FALSE; - } - - sexp->priv->search_context->contact = g_object_ref (contact); - - r = e_sexp_eval(sexp->priv->search_sexp); - - retval = (r && r->type == ESEXP_RES_BOOL && r->value.bool); - - g_object_unref(sexp->priv->search_context->contact); - - e_sexp_result_free(sexp->priv->search_sexp, r); - - return retval; -} - -gboolean -pas_backend_card_sexp_match_vcard (PASBackendCardSExp *sexp, const char *vcard) -{ - EContact *contact; - gboolean retval; - - contact = e_contact_new_from_vcard (vcard); - - retval = pas_backend_card_sexp_match_contact (sexp, contact); - - g_object_unref(contact); - - return retval; -} - - - -/** - * pas_backend_card_sexp_new: - */ -PASBackendCardSExp * -pas_backend_card_sexp_new (const char *text) -{ - PASBackendCardSExp *sexp = g_object_new (PAS_TYPE_BACKEND_CARD_SEXP, NULL); - int esexp_error; - int i; - - sexp->priv->search_sexp = e_sexp_new(); - - for(i=0;ipriv->search_sexp, 0, symbols[i].name, - (ESExpIFunc *)symbols[i].func, sexp->priv->search_context); - } - else { - e_sexp_add_function(sexp->priv->search_sexp, 0, symbols[i].name, - symbols[i].func, sexp->priv->search_context); - } - } - - e_sexp_input_text(sexp->priv->search_sexp, text, strlen(text)); - esexp_error = e_sexp_parse(sexp->priv->search_sexp); - - if (esexp_error == -1) { - g_object_unref (sexp); - sexp = NULL; - } - - return sexp; -} - -static void -pas_backend_card_sexp_dispose (GObject *object) -{ - PASBackendCardSExp *sexp = PAS_BACKEND_CARD_SEXP (object); - - if (sexp->priv) { - e_sexp_unref(sexp->priv->search_sexp); - - g_free (sexp->priv->search_context); - g_free (sexp->priv); - sexp->priv = NULL; - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -pas_backend_card_sexp_class_init (PASBackendCardSExpClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - /* Set the virtual methods. */ - - object_class->dispose = pas_backend_card_sexp_dispose; -} - -static void -pas_backend_card_sexp_init (PASBackendCardSExp *sexp) -{ - PASBackendCardSExpPrivate *priv; - - priv = g_new0 (PASBackendCardSExpPrivate, 1); - - sexp->priv = priv; - priv->search_context = g_new (SearchContext, 1); -} - -/** - * pas_backend_card_sexp_get_type: - */ -GType -pas_backend_card_sexp_get_type (void) -{ - static GType type = 0; - - if (! type) { - GTypeInfo info = { - sizeof (PASBackendCardSExpClass), - NULL, /* base_class_init */ - NULL, /* base_class_finalize */ - (GClassInitFunc) pas_backend_card_sexp_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PASBackendCardSExp), - 0, /* n_preallocs */ - (GInstanceInitFunc) pas_backend_card_sexp_init - }; - - type = g_type_register_static (G_TYPE_OBJECT, "PASBackendCardSExp", &info, 0); - } - - return type; -} diff --git a/addressbook/backend/pas/pas-backend-card-sexp.h b/addressbook/backend/pas/pas-backend-card-sexp.h deleted file mode 100644 index 7efb697fb0..0000000000 --- a/addressbook/backend/pas/pas-backend-card-sexp.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * pas-backend-card-sexp.h - * Copyright 2000, 2001, Ximian, Inc. - * - * Authors: - * Chris Lahey - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifndef __PAS_BACKEND_CARD_SEXP_H__ -#define __PAS_BACKEND_CARD_SEXP_H__ - -#include -#include -#include -#include - -#define PAS_TYPE_BACKEND_CARD_SEXP (pas_backend_card_sexp_get_type ()) -#define PAS_BACKEND_CARD_SEXP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_CARD_SEXP, PASBackendCardSExp)) -#define PAS_BACKEND_CARD_SEXP_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_BACKEND_TYPE, PASBackendCardSExpClass)) -#define PAS_IS_BACKEND_CARD_SEXP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BACKEND_CARD_SEXP)) -#define PAS_IS_BACKEND_CARD_SEXP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BACKEND_CARD_SEXP)) -#define PAS_BACKEND_CARD_SEXP_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BACKEND_CARD_SEXP, PASBackendCardSExpClass)) - -typedef struct _PASBackendCardSExpPrivate PASBackendCardSExpPrivate; - -struct _PASBackendCardSExp { - GObject parent_object; - PASBackendCardSExpPrivate *priv; -}; - -struct _PASBackendCardSExpClass { - GObjectClass parent_class; -}; - -PASBackendCardSExp *pas_backend_card_sexp_new (const char *text); -GType pas_backend_card_sexp_get_type (void); - -gboolean pas_backend_card_sexp_match_vcard (PASBackendCardSExp *sexp, const char *vcard); -gboolean pas_backend_card_sexp_match_contact (PASBackendCardSExp *sexp, EContact *contact); - -#endif /* __PAS_BACKEND_CARD_SEXP_H__ */ diff --git a/addressbook/backend/pas/pas-backend-file.c b/addressbook/backend/pas/pas-backend-file.c deleted file mode 100644 index 73f1797320..0000000000 --- a/addressbook/backend/pas/pas-backend-file.c +++ /dev/null @@ -1,1169 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#include "config.h" -#include "pas-backend-file.h" -#include "pas-backend-card-sexp.h" -#include "pas-backend-summary.h" -#include "pas-book.h" -#include "pas-book-view.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#if DB_VERSION_MAJOR != 3 || \ - DB_VERSION_MINOR != 1 || \ - DB_VERSION_PATCH != 17 -#error Including wrong DB3. Need libdb 3.1.17. -#endif - -#include -#include - -#include -#include -#include -#include - -#define CHANGES_DB_SUFFIX ".changes.db" - -#define PAS_BACKEND_FILE_VERSION_NAME "PAS-DB-VERSION" -#define PAS_BACKEND_FILE_VERSION "0.2" - -#define PAS_ID_PREFIX "pas-id-" -#define SUMMARY_FLUSH_TIMEOUT 5000 - -static PASBackendSyncClass *pas_backend_file_parent_class; - -struct _PASBackendFilePrivate { - char *uri; - char *dirname; - char *filename; - char *summary_filename; - DB *file_db; - PASBackendSummary *summary; -}; - -static void -string_to_dbt(const char *str, DBT *dbt) -{ - memset (dbt, 0, sizeof (*dbt)); - dbt->data = (void*)str; - dbt->size = strlen (str) + 1; -} - -static void -build_summary (PASBackendFilePrivate *bfpriv) -{ - DB *db = bfpriv->file_db; - DBC *dbc; - int db_error; - DBT id_dbt, vcard_dbt; - - db_error = db->cursor (db, NULL, &dbc, 0); - - if (db_error != 0) { - g_warning ("build_summary: error building list\n"); - return; - } - - memset (&vcard_dbt, 0, sizeof (vcard_dbt)); - memset (&id_dbt, 0, sizeof (id_dbt)); - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST); - - while (db_error == 0) { - - /* 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)) { - 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); - - } -} - -static char * -pas_backend_file_create_unique_id (void) -{ - /* use a 32 counter and the 32 bit timestamp to make an id. - it's doubtful 2^32 id's will be created in a second, so we - should be okay. */ - static guint c = 0; - return g_strdup_printf (PAS_ID_PREFIX "%08lX%08X", time(NULL), c++); -} - -static EContact * -do_create(PASBackendFile *bf, - const char *vcard_req) -{ - DB *db = bf->priv->file_db; - DBT id_dbt, vcard_dbt; - int db_error; - char *id; - EContact *contact; - char *vcard; - - id = pas_backend_file_create_unique_id (); - - string_to_dbt (id, &id_dbt); - - contact = e_contact_new_from_vcard (vcard_req); - e_contact_set(contact, E_CONTACT_UID, id); - vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); - - string_to_dbt (vcard, &vcard_dbt); - - db_error = db->put (db, NULL, &id_dbt, &vcard_dbt, 0); - - g_free (vcard); - - if (0 == db_error) { - db_error = db->sync (db, 0); - if (db_error != 0) - g_warning ("db->sync failed.\n"); - } - else { - g_object_unref (contact); - contact = NULL; - } - - g_free (id); - return contact; -} - -static PASBackendSyncStatus -pas_backend_file_create_contact (PASBackendSync *backend, - PASBook *book, - const char *vcard, - EContact **contact) -{ - PASBackendFile *bf = PAS_BACKEND_FILE (backend); - - *contact = do_create (bf, vcard); - if (*contact) { - pas_backend_summary_add_contact (bf->priv->summary, *contact); - return GNOME_Evolution_Addressbook_Success; - } - else { - /* XXX need a different call status for this case, i - think */ - return GNOME_Evolution_Addressbook_ContactNotFound; - } -} - -static PASBackendSyncStatus -pas_backend_file_remove_contacts (PASBackendSync *backend, - PASBook *book, - GList *id_list, - GList **ids) -{ - PASBackendFile *bf = PAS_BACKEND_FILE (backend); - DB *db = bf->priv->file_db; - DBT id_dbt, vcard_dbt; - int db_error; - char *id; - GList *l; - GList *removed_cards = NULL; - GNOME_Evolution_Addressbook_CallStatus rv = GNOME_Evolution_Addressbook_Success; - - for (l = id_list; l; l = l->next) { - id = l->data; - - 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 (0 != db_error) { - rv = GNOME_Evolution_Addressbook_ContactNotFound; - continue; - } - - db_error = db->del (db, NULL, &id_dbt, 0); - if (0 != db_error) { - rv = GNOME_Evolution_Addressbook_ContactNotFound; - continue; - } - - removed_cards = g_list_prepend (removed_cards, id); - } - - /* if we actually removed some, try to sync */ - if (removed_cards) { - db_error = db->sync (db, 0); - if (db_error != 0) - g_warning ("db->sync failed.\n"); - } - - *ids = removed_cards; - - for (l = removed_cards; l; l = l->next) { - char *id = l->data; - pas_backend_summary_remove_contact (bf->priv->summary, id); - } - - return rv; -} - -static PASBackendSyncStatus -pas_backend_file_modify_contact (PASBackendSync *backend, - PASBook *book, - const char *vcard, - EContact **contact) -{ - PASBackendFile *bf = PAS_BACKEND_FILE (backend); - DB *db = bf->priv->file_db; - DBT id_dbt, vcard_dbt; - int db_error; - char *id, *lookup_id; - - *contact = e_contact_new_from_vcard (vcard); - id = e_contact_get(*contact, E_CONTACT_UID); - - /* This is disgusting, but for a time cards were added with - ID's that are no longer used (they contained both the uri - and the id.) If we recognize it as a uri (file:///...) trim - off everything before the last '/', and use that as the - id.*/ - if (!strncmp (id, "file:///", strlen ("file:///"))) { - lookup_id = strrchr (id, '/') + 1; - } - else - lookup_id = id; - - string_to_dbt (lookup_id, &id_dbt); - memset (&vcard_dbt, 0, sizeof (vcard_dbt)); - - /* get the old ecard - the one that's presently in the db */ - db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0); - if (0 != db_error) - return GNOME_Evolution_Addressbook_ContactNotFound; - - string_to_dbt (vcard, &vcard_dbt); - - db_error = db->put (db, NULL, &id_dbt, &vcard_dbt, 0); - - if (0 == db_error) { - db_error = db->sync (db, 0); - if (db_error != 0) - g_warning ("db->sync failed.\n"); - - pas_backend_summary_remove_contact (bf->priv->summary, id); - pas_backend_summary_add_contact (bf->priv->summary, *contact); - } - g_free (id); - - if (0 == db_error) - return GNOME_Evolution_Addressbook_Success; - else - return GNOME_Evolution_Addressbook_ContactNotFound; -} - -static PASBackendSyncStatus -pas_backend_file_get_contact (PASBackendSync *backend, - PASBook *book, - const char *id, - char **vcard) -{ - PASBackendFile *bf; - DB *db; - DBT id_dbt, vcard_dbt; - int db_error = 0; - - bf = PAS_BACKEND_FILE (pas_book_get_backend (book)); - db = bf->priv->file_db; - - 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) { - *vcard = g_strdup (vcard_dbt.data); - return GNOME_Evolution_Addressbook_Success; - } else { - *vcard = g_strdup (""); - return GNOME_Evolution_Addressbook_ContactNotFound; - } -} - -static PASBackendSyncStatus -pas_backend_file_get_contact_list (PASBackendSync *backend, - PASBook *book, - const char *query, - GList **contacts) -{ - PASBackendFile *bf = PAS_BACKEND_FILE (backend); - DB *db = bf->priv->file_db; - DBC *dbc; - int db_error; - DBT id_dbt, vcard_dbt; - PASBackendCardSExp *card_sexp = NULL; - gboolean search_needed; - const char *search = query; - GList *contact_list = NULL; - - printf ("pas_backend_file_get_contact_list (%s)\n", search); - - search_needed = TRUE; - - if (!strcmp (search, "(contains \"x-evolution-any-field\" \"\")")) - search_needed = FALSE; - - card_sexp = pas_backend_card_sexp_new (search); - if (!card_sexp) { - /* XXX this needs to be an invalid query error of some sort*/ - return GNOME_Evolution_Addressbook_ContactNotFound; - } - - db_error = db->cursor (db, NULL, &dbc, 0); - - if (db_error != 0) { - /* XXX this needs to be some CouldNotOpen error */ - return GNOME_Evolution_Addressbook_ContactNotFound; - } - - memset (&vcard_dbt, 0, sizeof (vcard_dbt)); - memset (&id_dbt, 0, sizeof (id_dbt)); - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST); - - while (db_error == 0) { - - /* 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)) { - - if ((!search_needed) || (card_sexp != NULL && pas_backend_card_sexp_match_vcard (card_sexp, vcard_dbt.data))) { - contact_list = g_list_append (contact_list, g_strdup (vcard_dbt.data)); - } - } - - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT); - - } - - *contacts = contact_list; - return db_error != DB_NOTFOUND - ? GNOME_Evolution_Addressbook_OtherError - : GNOME_Evolution_Addressbook_Success; -} - -typedef struct { - GMutex *mutex; - gboolean stopped; -} FileBackendSearchClosure; - -static void -pas_backend_file_start_book_view (PASBackend *backend, - PASBookView *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 { - DB *db; - - GList *add_cards; - GList *add_ids; - GList *mod_cards; - GList *mod_ids; - GList *del_ids; - GList *del_cards; -} PASBackendFileChangeContext; - -static void -pas_backend_file_changes_foreach_key (const char *key, gpointer user_data) -{ - PASBackendFileChangeContext *ctx = user_data; - DB *db = ctx->db; - DBT id_dbt, vcard_dbt; - int db_error = 0; - - string_to_dbt (key, &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; - char *id = id_dbt.data; - char *vcard_string; - - contact = e_contact_new (); - e_contact_set (contact, E_CONTACT_UID, id); - - vcard_string = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); - - ctx->del_ids = g_list_append (ctx->del_ids, - g_strdup (id)); - ctx->del_cards = g_list_append (ctx->del_cards, - vcard_string); - - g_object_unref (contact); - } -} - -static PASBackendSyncStatus -pas_backend_file_get_changes (PASBackendSync *backend, - PASBook *book, - const char *change_id, - GList **changes_out) -{ - PASBackendFile *bf = PAS_BACKEND_FILE (backend); - int db_error = 0; - DBT id_dbt, vcard_dbt; - char *filename; - EDbHash *ehash; - GList *i, *v; - DB *db = bf->priv->file_db; - DBC *dbc; - GList *changes = NULL; - PASBackendFileChangeContext ctx; - PASBackendSyncStatus result; - - memset (&id_dbt, 0, sizeof (id_dbt)); - memset (&vcard_dbt, 0, sizeof (vcard_dbt)); - - memset (&ctx, 0, sizeof (ctx)); - - ctx.db = db; - - /* Find the changed ids */ - filename = g_strdup_printf ("%s/%s" CHANGES_DB_SUFFIX, bf->priv->dirname, change_id); - ehash = e_dbhash_new (filename); - g_free (filename); - - db_error = db->cursor (db, NULL, &dbc, 0); - - if (db_error != 0) { - g_warning ("pas_backend_file_changes: error building list\n"); - } else { - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST); - - while (db_error == 0) { - - /* 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)) { - EContact *contact; - char *id = id_dbt.data; - char *vcard_string; - - /* Remove fields the user can't change - * and can change without the rest of the - * card changing - */ - contact = e_contact_new_from_vcard (vcard_dbt.data); -#if notyet - g_object_set (card, "last_use", NULL, "use_score", 0.0, NULL); -#endif - vcard_string = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); - g_object_unref (contact); - - /* check what type of change has occurred, if any */ - switch (e_dbhash_compare (ehash, id, vcard_string)) { - case E_DBHASH_STATUS_SAME: - break; - case E_DBHASH_STATUS_NOT_FOUND: - ctx.add_cards = g_list_append (ctx.add_cards, vcard_string); - ctx.add_ids = g_list_append (ctx.add_ids, g_strdup(id)); - break; - case E_DBHASH_STATUS_DIFFERENT: - ctx.mod_cards = g_list_append (ctx.mod_cards, vcard_string); - ctx.mod_ids = g_list_append (ctx.mod_ids, g_strdup(id)); - break; - } - } - - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT); - } - dbc->c_close (dbc); - } - - e_dbhash_foreach_key (ehash, (EDbHashFunc)pas_backend_file_changes_foreach_key, &ctx); - - /* Send the changes */ - if (db_error != DB_NOTFOUND) { - g_warning ("pas_backend_file_changes: error building list\n"); - *changes_out = NULL; - result = GNOME_Evolution_Addressbook_OtherError; - } - else { - /* Update the hash and build our changes list */ - for (i = ctx.add_ids, v = ctx.add_cards; i != NULL; i = i->next, v = v->next){ - char *id = i->data; - char *vcard = v->data; - - e_dbhash_add (ehash, id, vcard); - changes = g_list_prepend (changes, - pas_backend_change_add_new (vcard)); - - g_free (i->data); - g_free (v->data); - } - for (i = ctx.mod_ids, v = ctx.mod_cards; i != NULL; i = i->next, v = v->next){ - char *id = i->data; - char *vcard = v->data; - - e_dbhash_add (ehash, id, vcard); - changes = g_list_prepend (changes, - pas_backend_change_modify_new (vcard)); - - g_free (i->data); - g_free (v->data); - } - for (i = ctx.del_ids, v = ctx.del_cards; i != NULL; i = i->next, v = v->next){ - char *id = i->data; - char *vcard = v->data; - - e_dbhash_remove (ehash, id); - - changes = g_list_prepend (changes, - pas_backend_change_delete_new (vcard)); - g_free (i->data); - g_free (v->data); - } - - e_dbhash_write (ehash); - - result = GNOME_Evolution_Addressbook_Success; - *changes_out = changes; - } - - e_dbhash_destroy (ehash); - - return GNOME_Evolution_Addressbook_Success; -} - -static char * -pas_backend_file_extract_path_from_uri (const char *uri) -{ - g_assert (strncasecmp (uri, "file://", 7) == 0); - - return g_strdup (uri + 7); -} - -static PASBackendSyncStatus -pas_backend_file_authenticate_user (PASBackendSync *backend, - PASBook *book, - const char *user, - const char *passwd, - const char *auth_method) -{ - return GNOME_Evolution_Addressbook_Success; -} - -static PASBackendSyncStatus -pas_backend_file_get_supported_fields (PASBackendSync *backend, - PASBook *book, - GList **fields_out) -{ - GList *fields = NULL; - int i; - - /* XXX we need a way to say "we support everything", since the - file backend does */ - for (i = 1; i < E_CONTACT_FIELD_LAST; i ++) - fields = g_list_append (fields, g_strdup (e_contact_field_name (i))); - - *fields_out = fields; - return GNOME_Evolution_Addressbook_Success; -} - -/* -** versions: -** -** 0.0 just a list of cards -** -** 0.1 same as 0.0, but with the version tag -** -** 0.2 not a real format upgrade, just a hack to fix broken ids caused -** by a bug in early betas, but we only need to convert them if -** the previous version is 0.1, since the bug existed after 0.1 -** came about. -*/ -static gboolean -pas_backend_file_upgrade_db (PASBackendFile *bf, char *old_version) -{ - DB *db = bf->priv->file_db; - int db_error; - DBT version_name_dbt, version_dbt; - - if (strcmp (old_version, "0.0") - && strcmp (old_version, "0.1")) { - g_warning ("unsupported version '%s' found in PAS backend file\n", - old_version); - return FALSE; - } - - if (!strcmp (old_version, "0.1")) { - /* we just loop through all the cards in the db, - giving them valid ids if they don't have them */ - DBT id_dbt, vcard_dbt; - DBC *dbc; - int card_failed = 0; - - db_error = db->cursor (db, NULL, &dbc, 0); - if (db_error != 0) { - g_warning ("unable to get cursor"); - return FALSE; - } - - memset (&id_dbt, 0, sizeof (id_dbt)); - memset (&vcard_dbt, 0, sizeof (vcard_dbt)); - - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST); - - while (db_error == 0) { - if (id_dbt.size != strlen(PAS_BACKEND_FILE_VERSION_NAME) + 1 - || strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) { - EContact *contact; - - contact = e_contact_new_from_vcard (vcard_dbt.data); - - /* the cards we're looking for are - created with a normal id dbt, but - with the id field in the vcard set - to something that doesn't match. - so, we need to modify the card to - have the same id as the the dbt. */ - if (strcmp (id_dbt.data, e_contact_get_const (contact, E_CONTACT_UID))) { - char *vcard; - - e_contact_set (contact, E_CONTACT_UID, id_dbt.data); - - vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); - string_to_dbt (vcard, &vcard_dbt); - - db_error = db->put (db, NULL, - &id_dbt, &vcard_dbt, 0); - - g_free (vcard); - - if (db_error != 0) - card_failed++; - } - - g_object_unref (contact); - } - - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT); - } - - if (card_failed) { - g_warning ("failed to update %d cards\n", card_failed); - return FALSE; - } - } - - string_to_dbt (PAS_BACKEND_FILE_VERSION_NAME, &version_name_dbt); - string_to_dbt (PAS_BACKEND_FILE_VERSION, &version_dbt); - - db_error = db->put (db, NULL, &version_name_dbt, &version_dbt, 0); - if (db_error == 0) - return TRUE; - else - return FALSE; -} - -static gboolean -pas_backend_file_maybe_upgrade_db (PASBackendFile *bf) -{ - DB *db = bf->priv->file_db; - DBT version_name_dbt, version_dbt; - int db_error; - char *version; - gboolean ret_val = TRUE; - - string_to_dbt (PAS_BACKEND_FILE_VERSION_NAME, &version_name_dbt); - memset (&version_dbt, 0, sizeof (version_dbt)); - - db_error = db->get (db, NULL, &version_name_dbt, &version_dbt, 0); - if (db_error == 0) { - /* success */ - version = g_strdup (version_dbt.data); - } - else { - /* key was not in file */ - version = g_strdup ("0.0"); - } - - if (strcmp (version, PAS_BACKEND_FILE_VERSION)) - ret_val = pas_backend_file_upgrade_db (bf, version); - - g_free (version); - - return ret_val; -} - -#include "ximian-vcard.h" - -static GNOME_Evolution_Addressbook_CallStatus -pas_backend_file_load_uri (PASBackend *backend, - const char *uri, - gboolean only_if_exists) -{ - PASBackendFile *bf = PAS_BACKEND_FILE (backend); - char *dirname, *filename; - gboolean writable = FALSE; - int db_error; - DB *db; - int major, minor, patch; - time_t db_mtime; - struct stat sb; - - g_free(bf->priv->uri); - bf->priv->uri = g_strdup (uri); - - db_version (&major, &minor, &patch); - - if (major != 3 || - minor != 1 || - patch != 17) { - g_warning ("Wrong version of libdb."); - return GNOME_Evolution_Addressbook_OtherError; - } - - dirname = pas_backend_file_extract_path_from_uri (uri); - filename = g_build_filename (dirname, "addressbook.db", NULL); - - db_error = e_db3_utils_maybe_recover (filename); - if (db_error != 0) - return GNOME_Evolution_Addressbook_OtherError; - - db_error = db_create (&db, NULL, 0); - if (db_error != 0) - return GNOME_Evolution_Addressbook_OtherError; - - db_error = db->open (db, filename, NULL, DB_HASH, 0, 0666); - - if (db_error == DB_OLD_VERSION) { - db_error = e_db3_utils_upgrade_format (filename); - - if (db_error != 0) - return GNOME_Evolution_Addressbook_OtherError; - - db_error = db->open (db, filename, NULL, DB_HASH, 0, 0666); - } - - bf->priv->file_db = db; - - if (db_error == 0) { - writable = TRUE; - } else { - db_error = db->open (db, filename, NULL, DB_HASH, DB_RDONLY, 0666); - - if (db_error != 0) { - int rv; - - /* the database didn't exist, so we create the - directory then the .db */ - rv = mkdir (dirname, 0777); - if (rv == -1 && errno != EEXIST) { - g_warning ("failed to make directory %s: %s", dirname, strerror (errno)); - if (errno == EACCES || errno == EPERM) - return GNOME_Evolution_Addressbook_PermissionDenied; - else - return GNOME_Evolution_Addressbook_OtherError; - } - - db_error = db->open (db, filename, NULL, DB_HASH, DB_CREATE, 0666); - - if (db_error == 0 && !only_if_exists) { - EContact *contact; - - contact = do_create(bf, XIMIAN_VCARD); - /* XXX check errors here */ - g_object_unref (contact); - - writable = TRUE; - } - } - } - - if (db_error != 0) { - bf->priv->file_db = NULL; - return GNOME_Evolution_Addressbook_OtherError; - } - - if (!pas_backend_file_maybe_upgrade_db (bf)) { - db->close (db, 0); - bf->priv->file_db = NULL; - return GNOME_Evolution_Addressbook_OtherError; - } - - g_free (bf->priv->dirname); - g_free (bf->priv->filename); - bf->priv->dirname = dirname; - bf->priv->filename = filename; - - if (stat (bf->priv->filename, &sb) == -1) { - db->close (db, 0); - bf->priv->file_db = NULL; - return GNOME_Evolution_Addressbook_OtherError; - } - db_mtime = sb.st_mtime; - - g_free (bf->priv->summary_filename); - bf->priv->summary_filename = g_strconcat (bf->priv->filename, ".summary", NULL); - bf->priv->summary = pas_backend_summary_new (bf->priv->summary_filename, SUMMARY_FLUSH_TIMEOUT); - - if (pas_backend_summary_is_up_to_date (bf->priv->summary, db_mtime) == FALSE - || pas_backend_summary_load (bf->priv->summary) == FALSE ) { - build_summary (bf->priv); - } - - pas_backend_set_is_loaded (backend, TRUE); - pas_backend_set_is_writable (backend, writable); - - return GNOME_Evolution_Addressbook_Success; -} - -static int -select_changes (const struct dirent *d) -{ - char *p; - - if (strlen (d->d_name) < strlen (CHANGES_DB_SUFFIX)) - return 0; - - p = strstr (d->d_name, CHANGES_DB_SUFFIX); - if (!p) - return 0; - - if (strlen (p) != strlen (CHANGES_DB_SUFFIX)) - return 0; - - return 1; -} - -static PASBackendSyncStatus -pas_backend_file_remove (PASBackendSync *backend, - PASBook *book) -{ - PASBackendFile *bf = PAS_BACKEND_FILE (backend); - struct dirent **namelist; - int n; - - if (-1 == unlink (bf->priv->filename)) { - if (errno == EACCES || errno == EPERM) - return GNOME_Evolution_Addressbook_PermissionDenied; - else - return GNOME_Evolution_Addressbook_OtherError; - } - - /* unref the summary before we remove the file so it's not written out again */ - g_object_unref (bf->priv->summary); - bf->priv->summary = NULL; - if (-1 == unlink (bf->priv->filename)) - g_warning ("failed to remove summary file `%s`: %s", bf->priv->summary_filename, strerror (errno)); - - /* scandir to select all the "*.changes.db" files, then remove them */ - n = scandir (bf->priv->dirname, - &namelist, select_changes, alphasort); - if (n < 0) { - g_warning ("scandir of directory `%s' failed: %s", bf->priv->dirname, strerror (errno)); - } - else { - while (n -- ) { - char *full_path = g_build_filename (bf->priv->dirname, namelist[n]->d_name, NULL); - if (-1 == unlink (full_path)) { - g_warning ("failed to remove change db `%s': %s", full_path, strerror (errno)); - } - g_free (full_path); - free (namelist[n]); - } - free (namelist); - } - - if (-1 == rmdir (bf->priv->dirname)) - g_warning ("failed to remove directory `%s`: %s", bf->priv->dirname, strerror (errno)); - - /* we may not have actually succeeded in removing the - backend's files/dirs, but there's nothing we can do about - it here.. the only time we should return failure is if we - failed to remove the actual data. a failure should mean - that the addressbook is still valid */ - return GNOME_Evolution_Addressbook_Success; -} - -static char * -pas_backend_file_get_static_capabilities (PASBackend *backend) -{ - return g_strdup("local,do-initial-query,bulk-removes"); -} - -static GNOME_Evolution_Addressbook_CallStatus -pas_backend_file_cancel_operation (PASBackend *backend, PASBook *book) -{ - return GNOME_Evolution_Addressbook_CouldNotCancel; -} - -static gboolean -pas_backend_file_construct (PASBackendFile *backend) -{ - g_assert (backend != NULL); - g_assert (PAS_IS_BACKEND_FILE (backend)); - - if (! pas_backend_construct (PAS_BACKEND (backend))) - return FALSE; - - return TRUE; -} - -/** - * pas_backend_file_new: - */ -PASBackend * -pas_backend_file_new (void) -{ - PASBackendFile *backend; - - backend = g_object_new (PAS_TYPE_BACKEND_FILE, NULL); - - if (! pas_backend_file_construct (backend)) { - g_object_unref (backend); - - return NULL; - } - - return PAS_BACKEND (backend); -} - -static void -pas_backend_file_dispose (GObject *object) -{ - PASBackendFile *bf; - - bf = PAS_BACKEND_FILE (object); - - if (bf->priv) { - if (bf->priv->summary) - g_object_unref(bf->priv->summary); - g_free (bf->priv->uri); - g_free (bf->priv->filename); - g_free (bf->priv->dirname); - g_free (bf->priv->summary_filename); - - g_free (bf->priv); - bf->priv = NULL; - } - - G_OBJECT_CLASS (pas_backend_file_parent_class)->dispose (object); -} - -static void -pas_backend_file_class_init (PASBackendFileClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - PASBackendSyncClass *sync_class; - PASBackendClass *backend_class; - - pas_backend_file_parent_class = g_type_class_peek_parent (klass); - - sync_class = PAS_BACKEND_SYNC_CLASS (klass); - backend_class = PAS_BACKEND_CLASS (klass); - - /* Set the virtual methods. */ - 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; - sync_class->create_contact_sync = pas_backend_file_create_contact; - sync_class->remove_contacts_sync = pas_backend_file_remove_contacts; - sync_class->modify_contact_sync = pas_backend_file_modify_contact; - sync_class->get_contact_sync = pas_backend_file_get_contact; - sync_class->get_contact_list_sync = pas_backend_file_get_contact_list; - sync_class->get_changes_sync = pas_backend_file_get_changes; - sync_class->authenticate_user_sync = pas_backend_file_authenticate_user; - sync_class->get_supported_fields_sync = pas_backend_file_get_supported_fields; - - object_class->dispose = pas_backend_file_dispose; -} - -static void -pas_backend_file_init (PASBackendFile *backend) -{ - PASBackendFilePrivate *priv; - - priv = g_new0 (PASBackendFilePrivate, 1); - priv->uri = NULL; - - backend->priv = priv; -} - -/** - * pas_backend_file_get_type: - */ -GType -pas_backend_file_get_type (void) -{ - static GType type = 0; - - if (! type) { - GTypeInfo info = { - sizeof (PASBackendFileClass), - NULL, /* base_class_init */ - NULL, /* base_class_finalize */ - (GClassInitFunc) pas_backend_file_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PASBackendFile), - 0, /* n_preallocs */ - (GInstanceInitFunc) pas_backend_file_init - }; - - type = g_type_register_static (PAS_TYPE_BACKEND_SYNC, "PASBackendFile", &info, 0); - } - - return type; -} diff --git a/addressbook/backend/pas/pas-backend-file.h b/addressbook/backend/pas/pas-backend-file.h deleted file mode 100644 index 6e1a77b119..0000000000 --- a/addressbook/backend/pas/pas-backend-file.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2000, Ximian, Inc. - */ - -#ifndef __PAS_BACKEND_FILE_H__ -#define __PAS_BACKEND_FILE_H__ - -#include "pas-backend-sync.h" - -#define PAS_TYPE_BACKEND_FILE (pas_backend_file_get_type ()) -#define PAS_BACKEND_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_FILE, PASBackendFile)) -#define PAS_BACKEND_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_BACKEND_TYPE, PASBackendFileClass)) -#define PAS_IS_BACKEND_FILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BACKEND_FILE)) -#define PAS_IS_BACKEND_FILE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BACKEND_FILE)) -#define PAS_BACKEND_FILE_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BACKEND_FILE, PASBackendFileClass)) - -typedef struct _PASBackendFilePrivate PASBackendFilePrivate; - -typedef struct { - PASBackendSync parent_object; - PASBackendFilePrivate *priv; -} PASBackendFile; - -typedef struct { - PASBackendSyncClass parent_class; -} PASBackendFileClass; - -PASBackend *pas_backend_file_new (void); -GType pas_backend_file_get_type (void); - -#endif /* ! __PAS_BACKEND_FILE_H__ */ - diff --git a/addressbook/backend/pas/pas-backend-ldap.c b/addressbook/backend/pas/pas-backend-ldap.c deleted file mode 100644 index d4aa4ea82d..0000000000 --- a/addressbook/backend/pas/pas-backend-ldap.c +++ /dev/null @@ -1,3206 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author: - * Chris Toshok (toshok@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#define DEBUG - -#include "config.h" -#include -#include - -#ifdef DEBUG -#define LDAP_DEBUG -#define LDAP_DEBUG_ADD -#endif -#include -#ifdef DEBUG -#undef LDAP_DEBUG -#endif - -#if LDAP_VENDOR_VERSION > 20000 -#define OPENLDAP2 -#else -#define OPENLDAP1 -#endif - -#ifdef OPENLDAP2 -#include -#endif - -#include - -#include -#include -#include - -#include "pas-backend-ldap.h" -#include "pas-backend-card-sexp.h" -#include "pas-book.h" -#include "pas-book-view.h" - -#include - -/* this is broken currently, don't enable it */ -/*#define ENABLE_SASL_BINDS*/ - -typedef enum { - PAS_BACKEND_LDAP_TLS_NO, - PAS_BACKEND_LDAP_TLS_ALWAYS, - PAS_BACKEND_LDAP_TLS_WHEN_POSSIBLE, -} PASBackendLDAPUseTLS; - -/* interval for our poll_ldap timeout */ -#define LDAP_POLL_INTERVAL 20 - -/* timeout for ldap_result */ -#define LDAP_RESULT_TIMEOUT_MILLIS 10 - -#define TV_TO_MILLIS(timeval) ((timeval).tv_sec * 1000 + (timeval).tv_usec / 1000) - -/* the objectClasses we need */ -#define TOP "top" -#define PERSON "person" -#define ORGANIZATIONALPERSON "organizationalPerson" -#define INETORGPERSON "inetOrgPerson" -#define CALENTRY "calEntry" -#define EVOLUTIONPERSON "evolutionPerson" - -static gchar *query_prop_to_ldap(gchar *query_prop); - -static PASBackendClass *pas_backend_ldap_parent_class; -typedef struct _PASBackendLDAPCursorPrivate PASBackendLDAPCursorPrivate; -typedef struct _PASBackendLDAPBookView PASBackendLDAPBookView; -typedef struct LDAPOp LDAPOp; - - -struct _PASBackendLDAPPrivate { - char *uri; - gboolean connected; - - gchar *ldap_host; /* the hostname of the server */ - int ldap_port; /* the port of the server */ - char *schema_dn; /* the base dn for schema information */ - gchar *ldap_rootdn; /* the base dn of our searches */ - int ldap_scope; /* the scope used for searches */ - int ldap_limit; /* the search limit */ - int ldap_timeout; /* the search timeout */ - - gchar *auth_dn; - gchar *auth_passwd; - - gboolean ldap_v3; /* TRUE if the server supports protocol - revision 3 (necessary for TLS) */ - gboolean starttls; /* TRUE if the *library* supports - starttls. will be false if openssl - was not built into openldap. */ - PASBackendLDAPUseTLS use_tls; - - LDAP *ldap; - - GList *supported_fields; - GList *supported_auth_methods; - - /* whether or not there's support for the objectclass we need - to store all our additional fields */ - gboolean evolutionPersonSupported; - gboolean calEntrySupported; - gboolean evolutionPersonChecked; - - /* our operations */ - GHashTable *id_to_op; - int active_ops; - int poll_timeout; -}; - -struct _PASBackendLDAPCursorPrivate { - PASBackend *backend; - PASBook *book; - - GList *elements; - long num_elements; -}; - -struct _PASBackendLDAPBookView { - PASBookView *book_view; - PASBackendLDAPPrivate *blpriv; - gchar *search; - int limit; - - LDAPOp *search_op; -}; - -typedef void (*LDAPOpHandler)(LDAPOp *op, LDAPMessage *res); -typedef void (*LDAPOpDtor)(LDAPOp *op); - -struct LDAPOp { - LDAPOpHandler handler; - LDAPOpDtor dtor; - PASBackend *backend; - PASBook *book; - PASBookView *view; - int id; -}; - -static void ldap_op_add (LDAPOp *op, PASBackend *backend, PASBook *book, - PASBookView *view, int id, LDAPOpHandler handler, LDAPOpDtor dtor); -static void ldap_op_finished (LDAPOp *op); - -static gboolean poll_ldap (PASBackendLDAP *bl); - -static EContact *build_contact_from_entry (LDAP *ldap, LDAPMessage *e, GList **existing_objectclasses); - -static void email_populate (EContact *contact, char **values); -struct berval** email_ber (EContact *contact); -static gboolean email_compare (EContact *contact1, EContact *contact2); - -static void homephone_populate (EContact *contact, char **values); -struct berval** homephone_ber (EContact *contact); -static gboolean homephone_compare (EContact *contact1, EContact *contact2); - -static void business_populate (EContact *contact, char **values); -struct berval** business_ber (EContact *contact); -static gboolean business_compare (EContact *contact1, EContact *contact2); - -static void anniversary_populate (EContact *contact, char **values); -struct berval** anniversary_ber (EContact *contact); -static gboolean anniversary_compare (EContact *contact1, EContact *contact2); - -static void birthday_populate (EContact *contact, char **values); -struct berval** birthday_ber (EContact *contact); -static gboolean birthday_compare (EContact *contact1, EContact *contact2); - -static void category_populate (EContact *contact, char **values); -struct berval** category_ber (EContact *contact); -static gboolean category_compare (EContact *contact1, EContact *contact2); - -static void photo_populate (EContact *contact, struct berval **ber_values); - -struct prop_info { - EContactField field_id; - char *ldap_attr; -#define PROP_TYPE_STRING 0x01 -#define PROP_TYPE_COMPLEX 0x02 -#define PROP_TYPE_BINARY 0x04 -#define PROP_DN 0x08 -#define PROP_EVOLVE 0x10 -#define PROP_WRITE_ONLY 0x20 - int prop_type; - - /* the remaining items are only used for the TYPE_COMPLEX props */ - - /* used when reading from the ldap server populates EContact with the values in **values. */ - void (*populate_contact_func)(EContact *contact, char **values); - /* used when writing to an ldap server. returns a NULL terminated array of berval*'s */ - struct berval** (*ber_func)(EContact *contact); - /* used to compare list attributes */ - gboolean (*compare_func)(EContact *contact1, EContact *contact2); - - void (*binary_populate_contact_func)(EContact *contact, struct berval **ber_values); - -} prop_info[] = { - -#define BINARY_PROP(fid,a,ctor,ber,cmp) {fid, a, PROP_TYPE_BINARY, NULL, ber, cmp, ctor} -#define COMPLEX_PROP(fid,a,ctor,ber,cmp) {fid, a, PROP_TYPE_COMPLEX, ctor, ber, cmp} -#define E_COMPLEX_PROP(fid,a,ctor,ber,cmp) {fid, a, PROP_TYPE_COMPLEX | PROP_EVOLVE, ctor, ber, cmp} -#define STRING_PROP(fid,a) {fid, a, PROP_TYPE_STRING} -#define WRITE_ONLY_STRING_PROP(fid,a) {fid, a, PROP_TYPE_STRING | PROP_WRITE_ONLY} -#define E_STRING_PROP(fid,a) {fid, a, PROP_TYPE_STRING | PROP_EVOLVE} - - - /* name fields */ - STRING_PROP (E_CONTACT_FULL_NAME, "cn" ), - WRITE_ONLY_STRING_PROP (E_CONTACT_FAMILY_NAME, "sn" ), - - /* email addresses */ - COMPLEX_PROP (E_CONTACT_EMAIL, "mail", email_populate, email_ber, email_compare), - - /* phone numbers */ - E_STRING_PROP (E_CONTACT_PHONE_PRIMARY, "primaryPhone"), - COMPLEX_PROP (E_CONTACT_PHONE_BUSINESS, "telephoneNumber", business_populate, business_ber, business_compare), - COMPLEX_PROP (E_CONTACT_PHONE_HOME, "homePhone", homephone_populate, homephone_ber, homephone_compare), - STRING_PROP (E_CONTACT_PHONE_MOBILE, "mobile"), - E_STRING_PROP (E_CONTACT_PHONE_CAR, "carPhone"), - STRING_PROP (E_CONTACT_PHONE_BUSINESS_FAX, "facsimileTelephoneNumber"), - E_STRING_PROP (E_CONTACT_PHONE_HOME_FAX, "homeFacsimileTelephoneNumber"), - E_STRING_PROP (E_CONTACT_PHONE_OTHER, "otherPhone"), - E_STRING_PROP (E_CONTACT_PHONE_OTHER_FAX, "otherFacsimileTelephoneNumber"), - STRING_PROP (E_CONTACT_PHONE_ISDN, "internationaliSDNNumber"), - STRING_PROP (E_CONTACT_PHONE_PAGER, "pager"), - E_STRING_PROP (E_CONTACT_PHONE_RADIO, "radio"), - E_STRING_PROP (E_CONTACT_PHONE_TELEX, "telex"), - E_STRING_PROP (E_CONTACT_PHONE_ASSISTANT, "assistantPhone"), - E_STRING_PROP (E_CONTACT_PHONE_COMPANY, "companyPhone"), - E_STRING_PROP (E_CONTACT_PHONE_CALLBACK, "callbackPhone"), - E_STRING_PROP (E_CONTACT_PHONE_TTYTDD, "tty"), - - /* org information */ - STRING_PROP (E_CONTACT_ORG, "o"), - STRING_PROP (E_CONTACT_ORG_UNIT, "ou"), - STRING_PROP (E_CONTACT_OFFICE, "roomNumber"), - STRING_PROP (E_CONTACT_TITLE, "title"), - E_STRING_PROP (E_CONTACT_ROLE, "businessRole"), - E_STRING_PROP (E_CONTACT_MANAGER, "managerName"), - E_STRING_PROP (E_CONTACT_ASSISTANT, "assistantName"), - - /* addresses */ - STRING_PROP (E_CONTACT_ADDRESS_LABEL_WORK, "postalAddress"), - STRING_PROP (E_CONTACT_ADDRESS_LABEL_HOME, "homePostalAddress"), - E_STRING_PROP (E_CONTACT_ADDRESS_LABEL_OTHER, "otherPostalAddress"), - - /* photos */ - BINARY_PROP (E_CONTACT_PHOTO, "jpegPhoto", photo_populate, NULL/*XXX*/, NULL/*XXX*/), - - /* misc fields */ - STRING_PROP (E_CONTACT_HOMEPAGE_URL, "labeledURI"), - /* map nickname to displayName */ - STRING_PROP (E_CONTACT_NICKNAME, "displayName"), - E_STRING_PROP (E_CONTACT_SPOUSE, "spouseName"), - E_STRING_PROP (E_CONTACT_NOTE, "note"), - E_COMPLEX_PROP (E_CONTACT_ANNIVERSARY, "anniversary", anniversary_populate, anniversary_ber, anniversary_compare), - E_COMPLEX_PROP (E_CONTACT_BIRTH_DATE, "birthDate", birthday_populate, birthday_ber, birthday_compare), - E_STRING_PROP (E_CONTACT_MAILER, "mailer"), - - E_STRING_PROP (E_CONTACT_FILE_AS, "fileAs"), -#if notyet - E_COMPLEX_PROP (E_CONTACT_CATEGORIES, "category", category_populate, category_ber, category_compare), - - STRING_PROP (E_CONTACT_CALURI, "calCalURI"), - STRING_PROP (E_CONTACT_FBURL, "calFBURL"), - STRING_PROP (E_CONTACT_ICSCALENDAR, "icsCalendar"), -#endif - -#undef E_STRING_PROP -#undef STRING_PROP -#undef E_COMPLEX_PROP -#undef COMPLEX_PROP -}; - -static int num_prop_infos = sizeof(prop_info) / sizeof(prop_info[0]); - -#if 0 -static void -remove_view (int msgid, LDAPOp *op, PASBookView *view) -{ - if (op->view == view) - op->view = NULL; -} - -static void -view_destroy(gpointer data, GObject *where_object_was) -{ - PASBook *book = (PASBook *)data; - PASBackendLDAP *bl; - EIterator *iter; - - bl = PAS_BACKEND_LDAP(pas_book_get_backend(book)); - - iter = e_list_get_iterator (bl->priv->book_views); - - while (e_iterator_is_valid (iter)) { - PASBackendLDAPBookView *view = (PASBackendLDAPBookView*)e_iterator_get (iter); - - if (view->book_view == (PASBookView*)where_object_was) { - GNOME_Evolution_Addressbook_Book corba_book; - CORBA_Environment ev; - - /* if we have an active search, interrupt it */ - if (view->search_op) { - ldap_op_finished (view->search_op); - } - /* and remove us as the view for any other - operations that might be using us to spew - status messages to the gui */ - g_hash_table_foreach (bl->priv->id_to_op, (GHFunc)remove_view, view->book_view); - - /* free up the view structure */ - g_free (view->search); - g_free (view); - - /* and remove it from our list */ - e_iterator_delete (iter); - - /* unref the book now */ - corba_book = bonobo_object_corba_objref(BONOBO_OBJECT(book)); - - CORBA_exception_init(&ev); - - GNOME_Evolution_Addressbook_Book_unref(corba_book, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning("view_destroy: Exception unreffing " - "corba book.\n"); - } - - CORBA_exception_free(&ev); - break; - } - - e_iterator_next (iter); - } - - g_object_unref (iter); - -} -#endif - -static void -book_view_notify_status (PASBookView *view, const char *status) -{ - if (!view) - return; - pas_book_view_notify_status_message (view, status); -} - -static PASBookView* -find_book_view (PASBackendLDAP *bl) -{ -#if 0 - EIterator *iter = e_list_get_iterator (bl->priv->book_views); - PASBookView *rv = NULL; - - if (e_iterator_is_valid (iter)) { - /* just always use the first book view */ - PASBackendLDAPBookView *v = (PASBackendLDAPBookView*)e_iterator_get(iter); - if (v) - rv = v->book_view; - } - - g_object_unref (iter); - - return rv; -#endif -} - -static void -add_to_supported_fields (PASBackendLDAP *bl, char **attrs, GHashTable *attr_hash) -{ - int i; - for (i = 0; attrs[i]; i ++) { - char *query_prop = g_hash_table_lookup (attr_hash, g_strdup (attrs[i])); - - if (query_prop) { - bl->priv->supported_fields = g_list_append (bl->priv->supported_fields, g_strdup (query_prop)); - - /* handle the list attributes here */ - if (!strcmp (query_prop, "email")) { - bl->priv->supported_fields = g_list_append (bl->priv->supported_fields, g_strdup ("email_2")); - bl->priv->supported_fields = g_list_append (bl->priv->supported_fields, g_strdup ("email_3")); - } - else if (!strcmp (query_prop, "business_phone")) { - bl->priv->supported_fields = g_list_append (bl->priv->supported_fields, g_strdup ("business_phone_2")); - } - else if (!strcmp (query_prop, "home_phone")) { - bl->priv->supported_fields = g_list_append (bl->priv->supported_fields, g_strdup ("home_phone_2")); - } - } - } -} - -static void -add_oc_attributes_to_supported_fields (PASBackendLDAP *bl, LDAPObjectClass *oc) -{ - int i; - GHashTable *attr_hash = g_hash_table_new (g_str_hash, g_str_equal); - - for (i = 0; i < num_prop_infos; i ++) - g_hash_table_insert (attr_hash, prop_info[i].ldap_attr, (char*)e_contact_field_name (prop_info[i].field_id)); - - if (oc->oc_at_oids_must) - add_to_supported_fields (bl, oc->oc_at_oids_must, attr_hash); - - if (oc->oc_at_oids_may) - add_to_supported_fields (bl, oc->oc_at_oids_may, attr_hash); - - g_hash_table_destroy (attr_hash); -} - -static void -check_schema_support (PASBackendLDAP *bl) -{ - char *attrs[2]; - LDAPMessage *resp; - LDAP *ldap = bl->priv->ldap; - struct timeval timeout; - - if (!bl->priv->schema_dn) - return; - - bl->priv->evolutionPersonChecked = TRUE; - - attrs[0] = "objectClasses"; - attrs[1] = NULL; - - timeout.tv_sec = 30; - timeout.tv_usec = 0; - - if (ldap_search_ext_s (ldap, bl->priv->schema_dn, LDAP_SCOPE_BASE, - "(objectClass=subschema)", attrs, 0, - NULL, NULL, &timeout, LDAP_NO_LIMIT, &resp) == LDAP_SUCCESS) { - char **values; - - values = ldap_get_values (ldap, resp, "objectClasses"); - - if (values) { - int i; - for (i = 0; values[i]; i ++) { - int j; - int code; - const char *err; - LDAPObjectClass *oc = ldap_str2objectclass (values[i], &code, &err, 0); - - if (!oc) - continue; - - for (j = 0; oc->oc_names[j]; j++) - if (!g_ascii_strcasecmp (oc->oc_names[j], EVOLUTIONPERSON)) { - g_print ("support found on ldap server for objectclass evolutionPerson\n"); - bl->priv->evolutionPersonSupported = TRUE; - - add_oc_attributes_to_supported_fields (bl, oc); - } - else if (!g_ascii_strcasecmp (oc->oc_names[j], CALENTRY)) { - g_print ("support found on ldap server for objectclass calEntry\n"); - bl->priv->calEntrySupported = TRUE; - add_oc_attributes_to_supported_fields (bl, oc); - } - else if (!g_ascii_strcasecmp (oc->oc_names[j], INETORGPERSON) - || !g_ascii_strcasecmp (oc->oc_names[j], ORGANIZATIONALPERSON) - || !g_ascii_strcasecmp (oc->oc_names[j], PERSON)) { - add_oc_attributes_to_supported_fields (bl, oc); - } - - ldap_objectclass_free (oc); - } - - ldap_value_free (values); - } - else { - /* the reason for this is so that if the user - ends up authenticating to the ldap server, - we will requery for the subschema values. - This makes it a bit more robust in the face - of draconian acl's that keep subschema - reads from working until the user is - authed. */ - if (!pas_backend_is_writable (PAS_BACKEND (bl))) { - g_warning ("subschema read returned nothing before successful auth"); - bl->priv->evolutionPersonChecked = FALSE; - } - else { - g_warning ("subschema read returned nothing after successful auth"); - } - } - - ldap_msgfree (resp); - } -} - -static void -get_ldap_library_info () -{ - LDAPAPIInfo info; - LDAP *ldap; - - if (LDAP_SUCCESS != ldap_create (&ldap)) { - g_warning ("couldn't create LDAP* for getting at the client lib api info"); - return; - } - - info.ldapai_info_version = LDAP_API_INFO_VERSION; - - if (LDAP_OPT_SUCCESS != ldap_get_option (ldap, LDAP_OPT_API_INFO, &info)) { - g_warning ("couldn't get ldap api info"); - } - else { - int i; - g_message ("libldap vendor/version: %s %2d.%02d.%02d", - info.ldapai_vendor_name, - info.ldapai_vendor_version / 10000, - (info.ldapai_vendor_version % 10000) / 1000, - info.ldapai_vendor_version % 1000); - - g_message ("extensions present:"); - /* yuck. we have to free these? */ - for (i = 0; info.ldapai_extensions[i]; i++) { - char *extension = info.ldapai_extensions[i]; - g_message (extension); - ldap_memfree (extension); - } - ldap_memfree (info.ldapai_extensions); - ldap_memfree (info.ldapai_vendor_name); - } - - ldap_unbind_ext_s (ldap, NULL, NULL); -} - -static int -query_ldap_root_dse (PASBackendLDAP *bl) -{ -#define MAX_DSE_ATTRS 20 - LDAP *ldap = bl->priv->ldap; - LDAPMessage *resp; - int ldap_error; - char *attrs[MAX_DSE_ATTRS], **values; - int i = 0; - struct timeval timeout; - - attrs[i++] = "supportedControl"; - attrs[i++] = "supportedExtension"; - attrs[i++] = "supportedFeatures"; - attrs[i++] = "supportedSASLMechanisms"; - attrs[i++] = "supportedLDAPVersion"; - attrs[i++] = "subschemaSubentry"; /* OpenLDAP's dn for schema information */ - attrs[i++] = "schemaNamingContext"; /* Active directory's dn for schema information */ - attrs[i] = NULL; - - timeout.tv_sec = 30; - timeout.tv_usec = 0; - - ldap_error = ldap_search_ext_s (ldap, - LDAP_ROOT_DSE, LDAP_SCOPE_BASE, - "(objectclass=*)", - attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, &resp); - if (ldap_error != LDAP_SUCCESS) { - g_warning ("could not perform query on Root DSE (ldap_error 0x%02x)", ldap_error); - return ldap_error; - } - - values = ldap_get_values (ldap, resp, "supportedControl"); - if (values) { - for (i = 0; values[i]; i++) - g_message ("supported server control: %s", values[i]); - ldap_value_free (values); - } - - values = ldap_get_values (ldap, resp, "supportedExtension"); - if (values) { - for (i = 0; values[i]; i++) { - g_message ("supported server extension: %s", values[i]); - if (!strcmp (values[i], LDAP_EXOP_START_TLS)) { - g_message ("server reports LDAP_EXOP_START_TLS"); - } - } - ldap_value_free (values); - } - - values = ldap_get_values (ldap, resp, "supportedSASLMechanisms"); - if (values) { - char *auth_method; - if (bl->priv->supported_auth_methods) { - g_list_foreach (bl->priv->supported_auth_methods, (GFunc)g_free, NULL); - g_list_free (bl->priv->supported_auth_methods); - } - bl->priv->supported_auth_methods = NULL; - - auth_method = g_strdup_printf ("ldap/simple-binddn|%s", _("Using Distinguished Name (DN)")); - bl->priv->supported_auth_methods = g_list_append (bl->priv->supported_auth_methods, auth_method); - - auth_method = g_strdup_printf ("ldap/simple-email|%s", _("Using Email Address")); - bl->priv->supported_fields = g_list_append (bl->priv->supported_auth_methods, auth_method); - - for (i = 0; values[i]; i++) { - auth_method = g_strdup_printf ("sasl/%s|%s", values[i], values[i]); - bl->priv->supported_fields = g_list_append (bl->priv->supported_auth_methods, auth_method); - g_message ("supported SASL mechanism: %s", values[i]); - } - ldap_value_free (values); - } - - - values = ldap_get_values (ldap, resp, "subschemaSubentry"); - if (!values || !values[0]) { - if (values) ldap_value_free (values); - values = ldap_get_values (ldap, resp, "schemaNamingContext"); - } - if (values && values[0]) { - g_free (bl->priv->schema_dn); - bl->priv->schema_dn = g_strdup (values[0]); - } - else { - g_warning ("could not determine location of schema information on LDAP server"); - } - if (values) - ldap_value_free (values); - - ldap_msgfree (resp); - - return LDAP_SUCCESS; -} - -static GNOME_Evolution_Addressbook_CallStatus -pas_backend_ldap_connect (PASBackendLDAP *bl) -{ - PASBackendLDAPPrivate *blpriv = bl->priv; - - /* close connection first if it's open first */ - if (blpriv->ldap) - ldap_unbind_ext (blpriv->ldap, NULL, NULL); - - blpriv->ldap = ldap_init (blpriv->ldap_host, blpriv->ldap_port); -#if defined (DEBUG) && defined (LDAP_OPT_DEBUG_LEVEL) - { - int debug_level = 4; - ldap_set_option (blpriv->ldap, LDAP_OPT_DEBUG_LEVEL, &debug_level); - } -#endif - - if (NULL != blpriv->ldap) { - int ldap_error; - - if (bl->priv->use_tls != PAS_BACKEND_LDAP_TLS_NO) { - int protocol_version = LDAP_VERSION3; - ldap_error = ldap_set_option (blpriv->ldap, LDAP_OPT_PROTOCOL_VERSION, &protocol_version); - if (LDAP_OPT_SUCCESS != ldap_error) { - g_warning ("failed to set protocol version to LDAPv3"); - bl->priv->ldap_v3 = FALSE; - } - else - bl->priv->ldap_v3 = TRUE; - - if (!bl->priv->ldap_v3 && bl->priv->use_tls == PAS_BACKEND_LDAP_TLS_ALWAYS) { - g_message ("TLS not available (fatal version), v3 protocol could not be established (ldap_error 0x%02x)", ldap_error); - ldap_unbind (blpriv->ldap); - blpriv->ldap = NULL; - return GNOME_Evolution_Addressbook_TLSNotAvailable; - } - - if (bl->priv->ldap_port == LDAPS_PORT && bl->priv->use_tls == PAS_BACKEND_LDAP_TLS_ALWAYS) { - int tls_level = LDAP_OPT_X_TLS_HARD; - ldap_set_option (blpriv->ldap, LDAP_OPT_X_TLS, &tls_level); - } - else if (bl->priv->use_tls) { - ldap_error = ldap_start_tls_s (blpriv->ldap, NULL, NULL); - if (LDAP_SUCCESS != ldap_error) { - if (bl->priv->use_tls == PAS_BACKEND_LDAP_TLS_ALWAYS) { - g_message ("TLS not available (fatal version), (ldap_error 0x%02x)", ldap_error); - ldap_unbind (blpriv->ldap); - blpriv->ldap = NULL; - return GNOME_Evolution_Addressbook_TLSNotAvailable; - } - else { - g_message ("TLS not available (ldap_error 0x%02x)", ldap_error); - } - } - else - g_message ("TLS active"); - } - } - - /* bind anonymously initially, we'll actually - authenticate the user properly later (in - authenticate_user) if they've selected - authentication */ - ldap_error = ldap_simple_bind_s (blpriv->ldap, NULL, NULL); - if (ldap_error == LDAP_SERVER_DOWN) { - /* we only want this to be fatal if the server is down. */ - g_warning ("failed to bind anonymously while connecting (ldap_error 0x%02x)", ldap_error); - return GNOME_Evolution_Addressbook_RepositoryOffline; - } - - ldap_error = query_ldap_root_dse (bl); - /* query_ldap_root_dse will cause the actual - connect(), so any tcpip problems will show up - here */ - - /* we can't just check for LDAP_SUCCESS here since in - older servers (namely openldap1.x servers), there's - not a root DSE at all, so the query will fail with - LDAP_NO_SUCH_OBJECT. */ - if (ldap_error == LDAP_SUCCESS || LDAP_NAME_ERROR (ldap_error)) { - blpriv->connected = TRUE; - - /* check to see if evolutionPerson is supported, if we can (me - might not be able to if we can't authenticate. if we - can't, try again in auth_user.) */ - if (!bl->priv->evolutionPersonChecked) - check_schema_support (bl); - - pas_backend_set_is_loaded (PAS_BACKEND (bl), TRUE); - return GNOME_Evolution_Addressbook_Success; - } - else - g_warning ("Failed to perform root dse query anonymously, (ldap_error 0x%02x)", ldap_error); - } - - g_warning ("pas_backend_ldap_connect failed for " - "'ldap://%s:%d/%s'\n", - blpriv->ldap_host, - blpriv->ldap_port, - blpriv->ldap_rootdn ? blpriv->ldap_rootdn : ""); - blpriv->connected = FALSE; - return GNOME_Evolution_Addressbook_RepositoryOffline; -} - -static gboolean -pas_backend_ldap_reconnect (PASBackendLDAP *bl, PASBookView *book_view, int ldap_status) -{ - /* we need to reconnect if we were previously connected */ - if (bl->priv->connected && ldap_status == LDAP_SERVER_DOWN) { - GNOME_Evolution_Addressbook_CallStatus status; - int ldap_error = LDAP_SUCCESS; - - book_view_notify_status (book_view, _("Reconnecting to LDAP server...")); - - status = pas_backend_ldap_connect (bl); - - if (status != GNOME_Evolution_Addressbook_Success) { - book_view_notify_status (book_view, ""); - return FALSE; - } - - if (bl->priv->auth_dn) - ldap_error = ldap_simple_bind_s(bl->priv->ldap, - bl->priv->auth_dn, - bl->priv->auth_passwd); - book_view_notify_status (book_view, ""); - return (ldap_error == LDAP_SUCCESS); - } - else { - return FALSE; - } -} - -static void -ldap_op_add (LDAPOp *op, PASBackend *backend, - PASBook *book, PASBookView *view, - int id, - LDAPOpHandler handler, LDAPOpDtor dtor) -{ - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - - op->backend = backend; - op->book = book; - op->view = view; - op->id = id; - op->handler = handler; - op->dtor = dtor; - - if (g_hash_table_lookup (bl->priv->id_to_op, &op->id)) { - g_warning ("conflicting ldap msgid's"); - } - - g_hash_table_insert (bl->priv->id_to_op, - &op->id, op); - - bl->priv->active_ops ++; - - if (bl->priv->poll_timeout == -1) - bl->priv->poll_timeout = g_timeout_add (LDAP_POLL_INTERVAL, - (GSourceFunc) poll_ldap, - bl); -} - -static void -ldap_op_finished (LDAPOp *op) -{ - PASBackend *backend = op->backend; - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - - g_hash_table_remove (bl->priv->id_to_op, &op->id); - - /* should handle errors here */ - ldap_abandon (bl->priv->ldap, op->id); - - op->dtor (op); - - bl->priv->active_ops--; - - if (bl->priv->active_ops == 0) { - if (bl->priv->poll_timeout != -1) - g_source_remove (bl->priv->poll_timeout); - bl->priv->poll_timeout = -1; - } -} - -static void -ldap_op_change_id (LDAPOp *op, int msg_id) -{ - PASBackend *backend = op->backend; - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - - g_hash_table_remove (bl->priv->id_to_op, &op->id); - - op->id = msg_id; - - g_hash_table_insert (bl->priv->id_to_op, - &op->id, op); -} - -static int -ldap_error_to_response (int ldap_error) -{ - if (ldap_error == LDAP_SUCCESS) - return GNOME_Evolution_Addressbook_Success; - else if (LDAP_NAME_ERROR (ldap_error)) - return GNOME_Evolution_Addressbook_ContactNotFound; - else if (ldap_error == LDAP_INSUFFICIENT_ACCESS) - return GNOME_Evolution_Addressbook_PermissionDenied; - else if (ldap_error == LDAP_SERVER_DOWN) - return GNOME_Evolution_Addressbook_RepositoryOffline; - else if (ldap_error == LDAP_ALREADY_EXISTS) - return GNOME_Evolution_Addressbook_ContactIdAlreadyExists; - else - return GNOME_Evolution_Addressbook_OtherError; -} - - -static char * -create_dn_from_contact (EContact *contact, const char *root_dn) -{ - char *cn, *cn_part = NULL; - char *dn; - - cn = e_contact_get (contact, E_CONTACT_FULL_NAME); - if (cn) { - if (strchr (cn, ',')) { - /* need to escape commas */ - char *new_cn = g_malloc0 (strlen (cn) * 3 + 1); - int i, j; - - for (i = 0, j = 0; i < strlen (cn); i ++) { - if (cn[i] == ',') { - sprintf (new_cn + j, "%%%02X", cn[i]); - j += 3; - } - else { - new_cn[j++] = cn[i]; - } - } - cn_part = g_strdup_printf ("cn=%s", new_cn); - g_free (new_cn); - } - else { - cn_part = g_strdup_printf ("cn=%s", cn); - } - } - else { - cn_part = g_strdup (""); - } - - dn = g_strdup_printf ("%s%s%s", cn_part, - (root_dn && strlen(root_dn)) ? "," : "", - (root_dn && strlen(root_dn)) ? root_dn: ""); - - g_free (cn_part); - - g_print ("generated dn: %s\n", dn); - - return dn; -} - -static void -free_mods (GPtrArray *mods) -{ - int i = 0; - LDAPMod *mod; - - while ((mod = g_ptr_array_index (mods, i++))) { - int j; - g_free (mod->mod_type); - - if (mod->mod_op & LDAP_MOD_BVALUES) { - for (j = 0; mod->mod_bvalues[j]; j++) { - g_free (mod->mod_bvalues[j]->bv_val); - g_free (mod->mod_bvalues[j]); - } - } - else { - for (j = 0; mod->mod_values[j]; j++) - g_free (mod->mod_values[j]); - } - g_free (mod); - } - - g_ptr_array_free (mods, TRUE); -} - -static GPtrArray* -build_mods_from_contacts (PASBackendLDAP *bl, EContact *current, EContact *new, gboolean *new_dn_needed) -{ - gboolean adding = (current == NULL); - GPtrArray *result = g_ptr_array_new(); - int i; - - if (new_dn_needed) - *new_dn_needed = FALSE; - - /* we walk down the list of properties we can deal with (that - big table at the top of the file) */ - - for (i = 0; i < num_prop_infos; i ++) { - gboolean include; - gboolean new_prop_present = FALSE; - gboolean current_prop_present = FALSE; - struct berval** new_prop_bers = NULL; - char *new_prop = NULL; - char *current_prop = NULL; - - /* XXX if it's an evolutionPerson prop and the ldap - server doesn't support that objectclass, skip it. */ - if (prop_info[i].prop_type & PROP_EVOLVE && !bl->priv->evolutionPersonSupported) - continue; - - /* get the value for the new contact, and compare it to - the value in the current contact to see if we should - update it -- if adding is TRUE, short circuit the - check. */ - if (prop_info[i].prop_type & PROP_TYPE_STRING) { - new_prop = e_contact_get (new, prop_info[i].field_id); - new_prop_present = (new_prop != NULL); - } - else { - new_prop_bers = prop_info[i].ber_func (new); - new_prop_present = (new_prop_bers != NULL); - } - - /* need to set INCLUDE to true if the field needs to - show up in the ldap modify request */ - if (adding) { - /* if we're creating a new contact, include it if the - field is there at all */ - if (prop_info[i].prop_type & PROP_TYPE_STRING) - include = (new_prop_present && *new_prop); /* empty strings cause problems */ - else - include = new_prop_present; - } - else { - /* if we're modifying an existing contact, - include it if the current field value is - different than the new one, if it didn't - exist previously, or if it's been - removed. */ - if (prop_info[i].prop_type & PROP_TYPE_STRING) { - current_prop = e_contact_get (current, prop_info[i].field_id); - current_prop_present = (current_prop != NULL); - - if (new_prop && current_prop) - include = *new_prop && strcmp (new_prop, current_prop); - else - include = (!!new_prop != !!current_prop); - } - else { - int j; - struct berval **current_prop_bers = prop_info[i].ber_func (current); - - current_prop_present = (current_prop_bers != NULL); - - /* free up the current_prop_bers */ - if (current_prop_bers) { - for (j = 0; current_prop_bers[j]; j++) { - g_free (current_prop_bers[j]->bv_val); - g_free (current_prop_bers[j]); - } - g_free (current_prop_bers); - } - - include = !prop_info[i].compare_func (new, current); - } - } - - if (include) { - LDAPMod *mod = g_new (LDAPMod, 1); - - /* the included attribute has changed - we - need to update the dn if it's one of the - attributes we compute the dn from. */ - if (new_dn_needed) - *new_dn_needed |= prop_info[i].prop_type & PROP_DN; - - if (adding) { - mod->mod_op = LDAP_MOD_ADD; - } - else { - if (!new_prop_present) - mod->mod_op = LDAP_MOD_DELETE; - else if (!current_prop_present) - mod->mod_op = LDAP_MOD_ADD; - else - mod->mod_op = LDAP_MOD_REPLACE; - } - - mod->mod_type = g_strdup (prop_info[i].ldap_attr); - - if (prop_info[i].prop_type & PROP_TYPE_STRING) { - mod->mod_values = g_new (char*, 2); - mod->mod_values[0] = new_prop; - mod->mod_values[1] = NULL; - } - else { /* PROP_TYPE_COMPLEX */ - mod->mod_op |= LDAP_MOD_BVALUES; - mod->mod_bvalues = new_prop_bers; - } - - g_ptr_array_add (result, mod); - } - - } - - /* NULL terminate the list of modifications */ - g_ptr_array_add (result, NULL); - - return result; -} - -static void -add_objectclass_mod (PASBackendLDAP *bl, GPtrArray *mod_array, GList *existing_objectclasses) -{ -#define FIND_INSERT(oc) \ - if (!g_list_find_custom (existing_objectclasses, (oc), (GCompareFunc)g_ascii_strcasecmp)) \ - g_ptr_array_add (objectclasses, g_strdup ((oc))) -#define INSERT(oc) \ - g_ptr_array_add (objectclasses, g_strdup ((oc))) - - LDAPMod *objectclass_mod; - GPtrArray *objectclasses = g_ptr_array_new(); - - if (existing_objectclasses) { - objectclass_mod = g_new (LDAPMod, 1); - objectclass_mod->mod_op = LDAP_MOD_ADD; - objectclass_mod->mod_type = g_strdup ("objectClass"); - - /* yes, this is a linear search for each of our - objectclasses, but really, how many objectclasses - are there going to be in any sane ldap entry? */ - FIND_INSERT (TOP); - FIND_INSERT (PERSON); - FIND_INSERT (ORGANIZATIONALPERSON); - FIND_INSERT (INETORGPERSON); - if (bl->priv->calEntrySupported) - FIND_INSERT (CALENTRY); - if (bl->priv->evolutionPersonSupported) - FIND_INSERT (EVOLUTIONPERSON); - - if (objectclasses->len) { - g_ptr_array_add (objectclasses, NULL); - objectclass_mod->mod_values = (char**)objectclasses->pdata; - g_ptr_array_add (mod_array, objectclass_mod); - g_ptr_array_free (objectclasses, FALSE); - } - else { - g_ptr_array_free (objectclasses, TRUE); - g_free (objectclass_mod->mod_type); - g_free (objectclass_mod); - } - - } - else { - objectclass_mod = g_new (LDAPMod, 1); - objectclass_mod->mod_op = LDAP_MOD_ADD; - objectclass_mod->mod_type = g_strdup ("objectClass"); - - INSERT(TOP); - INSERT(PERSON); - INSERT(ORGANIZATIONALPERSON); - INSERT(INETORGPERSON); - if (bl->priv->calEntrySupported) - INSERT(CALENTRY); - if (bl->priv->evolutionPersonSupported) - INSERT(EVOLUTIONPERSON); - g_ptr_array_add (objectclasses, NULL); - objectclass_mod->mod_values = (char**)objectclasses->pdata; - g_ptr_array_add (mod_array, objectclass_mod); - g_ptr_array_free (objectclasses, FALSE); - } -} - -typedef struct { - LDAPOp op; - char *dn; - EContact *new_contact; -} LDAPCreateOp; - -static void -create_contact_handler (LDAPOp *op, LDAPMessage *res) -{ - LDAPCreateOp *create_op = (LDAPCreateOp*)op; - PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend); - LDAP *ldap = bl->priv->ldap; - EContact *contact; - int ldap_error; - int response; - - if (LDAP_RES_ADD != ldap_msgtype (res)) { - g_warning ("incorrect msg type %d passed to create_contact_handler", ldap_msgtype (res)); - pas_book_respond_create (op->book, - GNOME_Evolution_Addressbook_OtherError, - NULL); - ldap_op_finished (op); - return; - } - - ldap_parse_result (ldap, res, &ldap_error, - NULL, NULL, NULL, NULL, 0); - - /* and lastly respond */ - response = ldap_error_to_response (ldap_error); - pas_book_respond_create (op->book, - response, - create_op->new_contact); - - ldap_op_finished (op); -} - -static void -create_contact_dtor (LDAPOp *op) -{ - LDAPCreateOp *create_op = (LDAPCreateOp*)op; - - g_free (create_op->dn); - g_object_unref (create_op->new_contact); - g_free (create_op); -} - -static void -pas_backend_ldap_process_create_contact (PASBackend *backend, - PASBook *book, - const char *vcard) -{ - LDAPCreateOp *create_op = g_new (LDAPCreateOp, 1); - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - PASBookView *book_view; - int create_contact_msgid; - int response; - int err; - GPtrArray *mod_array; - LDAPMod **ldap_mods; - LDAP *ldap; - - book_view = find_book_view (bl); - - printf ("vcard = %s\n", vcard); - - create_op->new_contact = e_contact_new_from_vcard (vcard); - - create_op->dn = create_dn_from_contact (create_op->new_contact, bl->priv->ldap_rootdn); - e_contact_set (create_op->new_contact, E_CONTACT_UID, create_op->dn); - - ldap = bl->priv->ldap; - - /* build our mods */ - mod_array = build_mods_from_contacts (bl, NULL, create_op->new_contact, NULL); - -#if 0 - if (!mod_array) { - /* there's an illegal field in there. report - UnsupportedAttribute back */ - pas_book_respond_create (book, - GNOME_Evolution_Addressbook_BookListener_UnsupportedField, - NULL); - - g_free (create_op->dn); - g_object_unref (create_op->new_contact); - g_free (create_op); - return; - } -#endif - - /* remove the NULL at the end */ - g_ptr_array_remove (mod_array, NULL); - - /* add our objectclass(es) */ - add_objectclass_mod (bl, mod_array, NULL); - - /* then put the NULL back */ - g_ptr_array_add (mod_array, NULL); - -#ifdef LDAP_DEBUG_ADD - { - int i; - printf ("Sending the following to the server as ADD\n"); - - for (i = 0; g_ptr_array_index(mod_array, i); i ++) { - LDAPMod *mod = g_ptr_array_index(mod_array, i); - if (mod->mod_op & LDAP_MOD_DELETE) - printf ("del "); - else if (mod->mod_op & LDAP_MOD_REPLACE) - printf ("rep "); - else - printf ("add "); - if (mod->mod_op & LDAP_MOD_BVALUES) - printf ("ber "); - else - printf (" "); - - printf (" %s:\n", mod->mod_type); - - if (mod->mod_op & LDAP_MOD_BVALUES) { - int j; - for (j = 0; mod->mod_bvalues[j] && mod->mod_bvalues[j]->bv_val; j++) - printf ("\t\t'%s'\n", mod->mod_bvalues[j]->bv_val); - } - else { - int j; - - for (j = 0; mod->mod_values[j]; j++) - printf ("\t\t'%s'\n", mod->mod_values[j]); - } - } - } -#endif - - ldap_mods = (LDAPMod**)mod_array->pdata; - - do { - book_view_notify_status (book_view, _("Adding contact to LDAP server...")); - - err = ldap_add_ext (ldap, create_op->dn, ldap_mods, - NULL, NULL, &create_contact_msgid); - - } while (pas_backend_ldap_reconnect (bl, book_view, err)); - - /* and clean up */ - free_mods (mod_array); - - if (LDAP_SUCCESS != err) { - response = ldap_error_to_response (err); - pas_book_respond_create (create_op->op.book, - response, - NULL); - create_contact_dtor ((LDAPOp*)create_op); - return; - } - else { - g_print ("ldap_add_ext returned %d\n", err); - ldap_op_add ((LDAPOp*)create_op, backend, book, - book_view, create_contact_msgid, - create_contact_handler, create_contact_dtor); - } -} - - -typedef struct { - LDAPOp op; - char *id; -} LDAPRemoveOp; - -static void -remove_contact_handler (LDAPOp *op, LDAPMessage *res) -{ - LDAPRemoveOp *remove_op = (LDAPRemoveOp*)op; - PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend); - int ldap_error; - GList *ids = NULL; - - if (LDAP_RES_DELETE != ldap_msgtype (res)) { - g_warning ("incorrect msg type %d passed to remove_contact_handler", ldap_msgtype (res)); - pas_book_respond_remove_contacts (op->book, - GNOME_Evolution_Addressbook_OtherError, - NULL); - ldap_op_finished (op); - return; - } - - ldap_parse_result (bl->priv->ldap, res, &ldap_error, - NULL, NULL, NULL, NULL, 0); - - ids = g_list_append (ids, remove_op->id); - pas_book_respond_remove_contacts (remove_op->op.book, - ldap_error_to_response (ldap_error), - ids); - g_list_free (ids); -} - -static void -remove_contact_dtor (LDAPOp *op) -{ - LDAPRemoveOp *remove_op = (LDAPRemoveOp*)op; - - g_free (remove_op->id); - g_free (remove_op); -} - -static void -pas_backend_ldap_process_remove_contacts (PASBackend *backend, - PASBook *book, - GList *ids) -{ - LDAPRemoveOp *remove_op = g_new (LDAPRemoveOp, 1); - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - PASBookView *book_view; - int remove_msgid; - int ldap_error; - - book_view = find_book_view (bl); - - /* - ** since we didn't pass "bulk-removes" in our static - ** capabilities, we should only get 1 length lists here, so - ** the id we're deleting is the first and only id in the list. - */ - remove_op->id = g_strdup (ids->data); - - do { - book_view_notify_status (book_view, _("Removing contact from LDAP server...")); - - ldap_error = ldap_delete_ext (bl->priv->ldap, - remove_op->id, - NULL, NULL, &remove_msgid); - } while (pas_backend_ldap_reconnect (bl, book_view, ldap_error)); - - if (ldap_error != LDAP_SUCCESS) { - pas_book_respond_remove_contacts (remove_op->op.book, - ldap_error_to_response (ldap_error), - NULL); - remove_contact_dtor ((LDAPOp*)remove_op); - return; - } - else { - g_print ("ldap_delete_ext returned %d\n", ldap_error); - ldap_op_add ((LDAPOp*)remove_op, backend, book, - book_view, remove_msgid, - remove_contact_handler, remove_contact_dtor); - } -} - - -/* -** MODIFY -** -** The modification request is actually composed of 2 separate -** requests. Since we need to get a list of theexisting objectclasses -** used by the ldap server for the entry, and since the UI only sends -** us the current contact, we need to query the ldap server for the -** existing contact. -** -*/ - -typedef struct { - LDAPOp op; - const char *id; /* the id of the contact we're modifying */ - EContact *current_contact; - EContact *contact; - GList *existing_objectclasses; -} LDAPModifyOp; - -static void -modify_contact_modify_handler (LDAPOp *op, LDAPMessage *res) -{ - LDAPModifyOp *modify_op = (LDAPModifyOp*)op; - PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend); - LDAP *ldap = bl->priv->ldap; - int ldap_error; - - if (LDAP_RES_MODIFY != ldap_msgtype (res)) { - g_warning ("incorrect msg type %d passed to modify_contact_handler", ldap_msgtype (res)); - pas_book_respond_modify (op->book, - GNOME_Evolution_Addressbook_OtherError, - NULL); - ldap_op_finished (op); - return; - } - - ldap_parse_result (ldap, res, &ldap_error, - NULL, NULL, NULL, NULL, 0); - - /* and lastly respond */ - pas_book_respond_modify (op->book, - ldap_error_to_response (ldap_error), - modify_op->contact); - ldap_op_finished (op); -} - -static void -modify_contact_search_handler (LDAPOp *op, LDAPMessage *res) -{ - LDAPModifyOp *modify_op = (LDAPModifyOp*)op; - PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend); - LDAP *ldap = bl->priv->ldap; - int msg_type; - - /* if it's successful, we should get called with a - RES_SEARCH_ENTRY and a RES_SEARCH_RESULT. if it's - unsuccessful, we should only see a RES_SEARCH_RESULT */ - - msg_type = ldap_msgtype (res); - if (msg_type == LDAP_RES_SEARCH_ENTRY) { - LDAPMessage *e = ldap_first_entry(ldap, res); - - if (!e) { - g_warning ("uh, this shouldn't happen"); - pas_book_respond_modify (op->book, - GNOME_Evolution_Addressbook_OtherError, - NULL); - ldap_op_finished (op); - return; - } - - modify_op->current_contact = build_contact_from_entry (ldap, e, - &modify_op->existing_objectclasses); - } - else if (msg_type == LDAP_RES_SEARCH_RESULT) { - int ldap_error; - LDAPMod **ldap_mods; - GPtrArray *mod_array; - gboolean differences; - gboolean need_new_dn; - int modify_contact_msgid; - - /* grab the result code, and set up the actual modify - if it was successful */ - ldap_parse_result (bl->priv->ldap, res, &ldap_error, - NULL, NULL, NULL, NULL, 0); - - if (ldap_error != LDAP_SUCCESS) { - /* more here i'm sure */ - pas_book_respond_modify (op->book, - ldap_error_to_response (ldap_error), - NULL); - ldap_op_finished (op); - return; - } - - /* build our mods */ - mod_array = build_mods_from_contacts (bl, modify_op->current_contact, modify_op->contact, &need_new_dn); - differences = mod_array->len > 0; - - if (differences) { - /* remove the NULL at the end */ - g_ptr_array_remove (mod_array, NULL); - - /* add our objectclass(es), making sure - evolutionPerson is there if it's supported */ - add_objectclass_mod (bl, mod_array, modify_op->existing_objectclasses); - - /* then put the NULL back */ - g_ptr_array_add (mod_array, NULL); - - ldap_mods = (LDAPMod**)mod_array->pdata; - - /* actually perform the ldap modify */ - ldap_error = ldap_modify_ext (ldap, modify_op->id, ldap_mods, - NULL, NULL, &modify_contact_msgid); - - if (ldap_error == LDAP_SUCCESS) { - op->handler = modify_contact_modify_handler; - ldap_op_change_id ((LDAPOp*)modify_op, - modify_contact_msgid); - } - else { - g_warning ("ldap_modify_ext returned %d\n", ldap_error); - pas_book_respond_modify (op->book, - ldap_error_to_response (ldap_error), - NULL); - ldap_op_finished (op); - return; - } - } - - /* and clean up */ - free_mods (mod_array); - } - else { - g_warning ("unhandled result type %d returned", msg_type); - pas_book_respond_modify (op->book, - GNOME_Evolution_Addressbook_OtherError, - NULL); - ldap_op_finished (op); - } -} - -static void -modify_contact_dtor (LDAPOp *op) -{ - LDAPModifyOp *modify_op = (LDAPModifyOp*)op; - - g_list_foreach (modify_op->existing_objectclasses, (GFunc)g_free, NULL); - g_list_free (modify_op->existing_objectclasses); - if (modify_op->current_contact) - g_object_unref (modify_op->current_contact); - if (modify_op->contact) - g_object_unref (modify_op->contact); - g_free (modify_op); -} - -static void -pas_backend_ldap_process_modify_contact (PASBackend *backend, - PASBook *book, - const char *vcard) -{ - LDAPModifyOp *modify_op = g_new0 (LDAPModifyOp, 1); - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - int ldap_error; - LDAP *ldap; - int modify_contact_msgid; - PASBookView *book_view; - - book_view = find_book_view (bl); - - modify_op->contact = e_contact_new_from_vcard (vcard); - modify_op->id = e_contact_get_const (modify_op->contact, E_CONTACT_UID); - - ldap = bl->priv->ldap; - - book_view_notify_status (book_view, _("Modifying contact from LDAP server...")); - - do { - book_view_notify_status (book_view, _("Modifying contact from LDAP server...")); - - ldap_error = ldap_search_ext (ldap, modify_op->id, - LDAP_SCOPE_BASE, - "(objectclass=*)", - NULL, 0, NULL, NULL, - NULL, /* XXX timeout */ - 1, &modify_contact_msgid); - - } while (pas_backend_ldap_reconnect (bl, book_view, ldap_error)); - - if (ldap_error == LDAP_SUCCESS) { - ldap_op_add ((LDAPOp*)modify_op, backend, book, - book_view, modify_contact_msgid, - modify_contact_search_handler, modify_contact_dtor); - } - else { - g_warning ("ldap_search_ext returned %d\n", ldap_error); - pas_book_respond_modify (book, - GNOME_Evolution_Addressbook_OtherError, - NULL); - modify_contact_dtor ((LDAPOp*)modify_op); - } -} - - -typedef struct { - LDAPOp op; -} LDAPGetContactOp; - -static void -get_contact_handler (LDAPOp *op, LDAPMessage *res) -{ - PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend); - int msg_type; - - /* the msg_type will be either SEARCH_ENTRY (if we're - successful) or SEARCH_RESULT (if we're not), so we finish - the op after either */ - msg_type = ldap_msgtype (res); - if (msg_type == LDAP_RES_SEARCH_ENTRY) { - LDAPMessage *e = ldap_first_entry(bl->priv->ldap, res); - EContact *contact; - char *vcard; - - if (!e) { - g_warning ("uh, this shouldn't happen"); - pas_book_respond_get_contact (op->book, - GNOME_Evolution_Addressbook_OtherError, - ""); - ldap_op_finished (op); - return; - } - - contact = build_contact_from_entry (bl->priv->ldap, e, NULL); - vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); - pas_book_respond_get_contact (op->book, - GNOME_Evolution_Addressbook_Success, - vcard); - g_free (vcard); - g_object_unref (contact); - ldap_op_finished (op); - } - else if (msg_type == LDAP_RES_SEARCH_RESULT) { - int ldap_error; - ldap_parse_result (bl->priv->ldap, res, &ldap_error, - NULL, NULL, NULL, NULL, 0); - pas_book_respond_get_contact (op->book, ldap_error_to_response (ldap_error), ""); - ldap_op_finished (op); - } - else { - g_warning ("unhandled result type %d returned", msg_type); - pas_book_respond_get_contact (op->book, GNOME_Evolution_Addressbook_OtherError, - ""); - ldap_op_finished (op); - } - -} - -static void -get_contact_dtor (LDAPOp *op) -{ - LDAPGetContactOp *get_contact_op = (LDAPGetContactOp*)op; - - g_free (get_contact_op); -} - -static void -pas_backend_ldap_process_get_contact (PASBackend *backend, - PASBook *book, - const char *id) -{ - LDAPGetContactOp *get_contact_op = g_new0 (LDAPGetContactOp, 1); - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - LDAP *ldap = bl->priv->ldap; - int get_contact_msgid; - PASBookView *book_view; - int ldap_error; - - book_view = find_book_view (bl); - - do { - ldap_error = ldap_search_ext (ldap, id, - LDAP_SCOPE_BASE, - "(objectclass=*)", - NULL, 0, NULL, NULL, - NULL, /* XXX timeout */ - 1, &get_contact_msgid); - } while (pas_backend_ldap_reconnect (bl, book_view, ldap_error)); - - if (ldap_error == LDAP_SUCCESS) { - ldap_op_add ((LDAPOp*)get_contact_op, backend, book, - book_view, get_contact_msgid, - get_contact_handler, get_contact_dtor); - } - else { - pas_book_respond_get_contact (book, - ldap_error_to_response (ldap_error), - ""); - get_contact_dtor ((LDAPOp*)get_contact_op); - } -} - - - -static EContactField email_ids[3] = { - E_CONTACT_EMAIL_1, - E_CONTACT_EMAIL_2, - E_CONTACT_EMAIL_3 -}; - -/* List property functions */ -static void -email_populate(EContact *contact, char **values) -{ - int i; - for (i = 0; values[i] && i < 3; i ++) - e_contact_set (contact, email_ids[i], values[i]); -} - -struct berval** -email_ber(EContact *contact) -{ - struct berval** result; - const char *emails[3]; - int i, j, num = 0; - - for (i = 0; i < 3; i ++) { - emails[i] = e_contact_get (contact, email_ids[i]); - if (emails[i]) - num++; - } - - if (num == 0) - return NULL; - - result = g_new (struct berval*, num + 1); - - for (i = 0; i < num; i ++) - result[i] = g_new (struct berval, 1); - - j = 0; - for (i = 0; i < 3; i ++) { - if (emails[i]) { - result[j]->bv_val = g_strdup (emails[i]); - result[j++]->bv_len = strlen (emails[i]); - } - } - - result[num] = NULL; - - return result; -} - -static gboolean -email_compare (EContact *contact1, EContact *contact2) -{ - const char *email1, *email2; - int i; - - for (i = 0; i < 3; i ++) { - gboolean equal; - email1 = e_contact_get_const (contact1, email_ids[i]); - email2 = e_contact_get_const (contact2, email_ids[i]); - - if (email1 && email2) - equal = !strcmp (email1, email2); - else - equal = (!!email1 == !!email2); - - if (!equal) - return equal; - } - - return TRUE; -} - -static void -homephone_populate(EContact *contact, char **values) -{ - if (values[0]) { - e_contact_set (contact, E_CONTACT_PHONE_HOME, values[0]); - if (values[1]) - e_contact_set (contact, E_CONTACT_PHONE_HOME_2, values[1]); - } -} - -struct berval** -homephone_ber(EContact *contact) -{ - struct berval** result; - const char *homephones[3]; - int i, j, num; - - num = 0; - if ((homephones[0] = e_contact_get (contact, E_CONTACT_PHONE_HOME))) - num++; - if ((homephones[1] = e_contact_get (contact, E_CONTACT_PHONE_HOME_2))) - num++; - - if (num == 0) - return NULL; - - result = g_new (struct berval*, num + 1); - - for (i = 0; i < num; i ++) - result[i] = g_new (struct berval, 1); - - j = 0; - for (i = 0; i < 2; i ++) { - if (homephones[i]) { - result[j]->bv_val = g_strdup (homephones[i]); - result[j++]->bv_len = strlen (homephones[i]); - } - } - - result[num] = NULL; - - return result; -} - -static gboolean -homephone_compare (EContact *contact1, EContact *contact2) -{ - int phone_ids[2] = { E_CONTACT_PHONE_HOME, E_CONTACT_PHONE_HOME_2 }; - const char *phone1, *phone2; - int i; - - for (i = 0; i < 2; i ++) { - gboolean equal; - phone1 = e_contact_get (contact1, phone_ids[i]); - phone2 = e_contact_get (contact2, phone_ids[i]); - - if (phone1 && phone2) - equal = !strcmp (phone1, phone2); - else - equal = (!!phone1 == !!phone2); - - if (!equal) - return equal; - } - - return TRUE; -} - -static void -business_populate(EContact *contact, char **values) -{ - if (values[0]) { - e_contact_set (contact, E_CONTACT_PHONE_BUSINESS, values[0]); - if (values[1]) - e_contact_set (contact, E_CONTACT_PHONE_BUSINESS_2, values[1]); - } -} - -struct berval** -business_ber(EContact *contact) -{ - struct berval** result; - const char *business_phones[3]; - int i, j, num; - - num = 0; - if ((business_phones[0] = e_contact_get (contact, E_CONTACT_PHONE_BUSINESS))) - num++; - if ((business_phones[1] = e_contact_get (contact, E_CONTACT_PHONE_BUSINESS_2))) - num++; - - if (num == 0) - return NULL; - - result = g_new (struct berval*, num + 1); - - for (i = 0; i < num; i ++) - result[i] = g_new (struct berval, 1); - - j = 0; - for (i = 0; i < 2; i ++) { - if (business_phones[i]) { - result[j]->bv_val = g_strdup (business_phones[i]); - result[j++]->bv_len = strlen (business_phones[i]); - } - } - - result[num] = NULL; - - return result; -} - -static gboolean -business_compare (EContact *contact1, EContact *contact2) -{ - int phone_ids[2] = { E_CONTACT_PHONE_BUSINESS, E_CONTACT_PHONE_BUSINESS_2 }; - const char *phone1, *phone2; - int i; - - for (i = 0; i < 2; i ++) { - gboolean equal; - phone1 = e_contact_get (contact1, phone_ids[i]); - phone2 = e_contact_get (contact2, phone_ids[i]); - - if (phone1 && phone2) - equal = !strcmp (phone1, phone2); - else - equal = (!!phone1 == !!phone2); - - if (!equal) - return equal; - } - - return TRUE; -} - -static void -anniversary_populate (EContact *contact, char **values) -{ - if (values[0]) { - EContactDate *dt = e_contact_date_from_string (values[0]); - e_contact_set (contact, E_CONTACT_ANNIVERSARY, &dt); - } -} - -struct berval** -anniversary_ber (EContact *contact) -{ - EContactDate *dt; - struct berval** result = NULL; - - dt = e_contact_get (contact, E_CONTACT_ANNIVERSARY); - - if (dt) { - char *anniversary; - - anniversary = e_contact_date_to_string (dt); - - result = g_new (struct berval*, 2); - result[0] = g_new (struct berval, 1); - result[0]->bv_val = anniversary; - result[0]->bv_len = strlen (anniversary); - - result[1] = NULL; - - e_contact_date_free (dt); - } - - return result; -} - -static gboolean -anniversary_compare (EContact *contact1, EContact *contact2) -{ - EContactDate *dt; - char *date1 = NULL, *date2 = NULL; - gboolean equal; - - dt = e_contact_get (contact1, E_CONTACT_ANNIVERSARY); - if (dt) { - date1 = e_contact_date_to_string (dt); - e_contact_date_free (dt); - } - - dt = e_contact_get (contact2, E_CONTACT_ANNIVERSARY); - if (dt) { - date2 = e_contact_date_to_string (dt); - e_contact_date_free (dt); - } - - if (date1 && date2) - equal = !strcmp (date1, date2); - else - equal = (!!date1 == !!date2); - - g_free (date1); - g_free (date2); - - return equal; -} - -static void -birthday_populate (EContact *contact, char **values) -{ - if (values[0]) { - EContactDate *dt = e_contact_date_from_string (values[0]); - e_contact_set (contact, E_CONTACT_BIRTH_DATE, dt); - e_contact_date_free (dt); - } -} - -struct berval** -birthday_ber (EContact *contact) -{ - EContactDate *dt; - struct berval** result = NULL; - - dt = e_contact_get (contact, E_CONTACT_BIRTH_DATE); - if (dt) { - char *birthday; - - birthday = e_contact_date_to_string (dt); - - result = g_new (struct berval*, 2); - result[0] = g_new (struct berval, 1); - result[0]->bv_val = birthday; - result[0]->bv_len = strlen (birthday); - - result[1] = NULL; - - e_contact_date_free (dt); - } - - return result; -} - -static gboolean -birthday_compare (EContact *contact1, EContact *contact2) -{ - EContactDate *dt; - char *date1 = NULL, *date2 = NULL; - gboolean equal; - - dt = e_contact_get (contact1, E_CONTACT_BIRTH_DATE); - if (dt) { - date1 = e_contact_date_to_string (dt); - e_contact_date_free (dt); - } - - dt = e_contact_get (contact2, E_CONTACT_BIRTH_DATE); - if (dt) { - date2 = e_contact_date_to_string (dt); - e_contact_date_free (dt); - } - - if (date1 && date2) - equal = !strcmp (date1, date2); - else - equal = (!!date1 == !!date2); - - g_free (date1); - g_free (date2); - - return equal; -} - -static void -category_populate (EContact *contact, char **values) -{ -#if notyet - int i; - EContact *ecard; - EList *categories; - - g_object_get (card, - "card", &ecard, - NULL); - - categories = e_list_new((EListCopyFunc) g_strdup, - (EListFreeFunc) g_free, - NULL); - - for (i = 0; values[i]; i++) - e_list_append (categories, values[i]); - - g_object_set (ecard, - "category_list", categories, - NULL); - - g_object_unref (categories); - - e_card_simple_sync_card (card); - g_object_unref (ecard); -#endif -} - -struct berval** -category_ber (EContact *contact) -{ -#if notyet - struct berval** result = NULL; - EList *categories; - EIterator *iterator; - EContact *ecard; - int i; - - g_object_get (card, - "card", &ecard, - NULL); - - g_object_get (ecard, - "category_list", &categories, - NULL); - - if (e_list_length (categories) != 0) { - result = g_new0 (struct berval*, e_list_length (categories) + 1); - - for (iterator = e_list_get_iterator(categories), i = 0; e_iterator_is_valid (iterator); - e_iterator_next (iterator), i++) { - const char *category = e_iterator_get (iterator); - - result[i] = g_new (struct berval, 1); - result[i]->bv_val = g_strdup (category); - result[i]->bv_len = strlen (category); - } - - g_object_unref (iterator); - } - - g_object_unref (categories); - g_object_unref (ecard); - return result; -#endif -} - -static gboolean -category_compare (EContact *contact1, EContact *contact2) -{ -#if notyet - char *categories1, *categories2; - gboolean equal; - - categories1 = e_card_simple_get (ecard1, E_CONTACT_CATEGORIES); - categories2 = e_card_simple_get (ecard2, E_CONTACT_CATEGORIES); - - equal = !strcmp (categories1, categories2); - - g_free (categories1); - g_free (categories2); - - return equal; -#endif -} - -static void -photo_populate (EContact *contact, struct berval **ber_values) -{ - if (ber_values && ber_values[0]) { - EContactPhoto photo; - photo.data = ber_values[0]->bv_val; - photo.length = ber_values[0]->bv_len; - - e_contact_set (contact, E_CONTACT_PHOTO, &photo); - } -} - -typedef struct { - GList *list; - PASBackendLDAP *bl; -} PASBackendLDAPSExpData; - -#define IS_RFC2254_CHAR(c) ((c) == '*' || (c) =='\\' || (c) == '(' || (c) == ')' || (c) == '\0') -static char * -rfc2254_escape(char *str) -{ - int i; - int len = strlen(str); - int newlen = 0; - - for (i = 0; i < len; i ++) { - if (IS_RFC2254_CHAR(str[i])) - newlen += 3; - else - newlen ++; - } - - if (len == newlen) { - return g_strdup (str); - } - else { - char *newstr = g_malloc0 (newlen + 1); - int j = 0; - for (i = 0; i < len; i ++) { - if (IS_RFC2254_CHAR(str[i])) { - sprintf (newstr + j, "\\%02x", str[i]); - j+= 3; - } - else { - newstr[j++] = str[i]; - } - } - return newstr; - } -} - -static ESExpResult * -func_and(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendLDAPSExpData *ldap_data = data; - ESExpResult *r; - char ** strings; - - if (argc > 0) { - int i; - - strings = g_new0(char*, argc+3); - strings[0] = g_strdup ("(&"); - strings[argc+3 - 2] = g_strdup (")"); - - for (i = 0; i < argc; i ++) { - GList *list_head = ldap_data->list; - if (!list_head) - break; - strings[argc - i] = list_head->data; - ldap_data->list = g_list_remove_link(list_head, list_head); - g_list_free_1(list_head); - } - - ldap_data->list = g_list_prepend(ldap_data->list, g_strjoinv(" ", strings)); - - for (i = 0 ; i < argc + 2; i ++) - g_free (strings[i]); - - g_free (strings); - } - - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_or(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendLDAPSExpData *ldap_data = data; - ESExpResult *r; - char ** strings; - - if (argc > 0) { - int i; - - strings = g_new0(char*, argc+3); - strings[0] = g_strdup ("(|"); - strings[argc+3 - 2] = g_strdup (")"); - - for (i = 0; i < argc; i ++) { - GList *list_head = ldap_data->list; - if (!list_head) - break; - strings[argc - i] = list_head->data; - ldap_data->list = g_list_remove_link(list_head, list_head); - g_list_free_1(list_head); - } - - ldap_data->list = g_list_prepend(ldap_data->list, g_strjoinv(" ", strings)); - - for (i = 0 ; i < argc + 2; i ++) - g_free (strings[i]); - - g_free (strings); - } - - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_not(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendLDAPSExpData *ldap_data = data; - ESExpResult *r; - - /* just replace the head of the list with the NOT of it. */ - if (argc > 0) { - char *term = ldap_data->list->data; - ldap_data->list->data = g_strdup_printf("(!%s)", term); - g_free (term); - } - - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendLDAPSExpData *ldap_data = data; - ESExpResult *r; - - if (argc == 2 - && argv[0]->type == ESEXP_RES_STRING - && argv[1]->type == ESEXP_RES_STRING) { - char *propname = argv[0]->value.string; - char *str = rfc2254_escape(argv[1]->value.string); - gboolean one_star = FALSE; - - if (strlen(str) == 0) - one_star = TRUE; - - if (!strcmp (propname, "x-evolution-any-field")) { - int i; - int query_length; - char *big_query; - char *match_str; - - match_str = g_strdup_printf("=*%s%s)", - str, one_star ? "" : "*"); - - query_length = 3; /* strlen ("(|") + strlen (")") */ - - for (i = 0; i < num_prop_infos; i ++) { - query_length += 1 /* strlen ("(") */ + strlen(prop_info[i].ldap_attr) + strlen (match_str); - } - - big_query = g_malloc0(query_length + 1); - strcat (big_query, "(|"); - for (i = 0; i < num_prop_infos; i ++) { - strcat (big_query, "("); - strcat (big_query, prop_info[i].ldap_attr); - strcat (big_query, match_str); - } - strcat (big_query, ")"); - - ldap_data->list = g_list_prepend(ldap_data->list, big_query); - - g_free (match_str); - } - else { - char *ldap_attr = query_prop_to_ldap(propname); - - if (ldap_attr) - ldap_data->list = g_list_prepend(ldap_data->list, - g_strdup_printf("(%s=*%s%s)", - ldap_attr, - str, - one_star ? "" : "*")); - } - - g_free (str); - } - - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_is(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendLDAPSExpData *ldap_data = data; - ESExpResult *r; - - if (argc == 2 - && argv[0]->type == ESEXP_RES_STRING - && argv[1]->type == ESEXP_RES_STRING) { - char *propname = argv[0]->value.string; - char *str = rfc2254_escape(argv[1]->value.string); - char *ldap_attr = query_prop_to_ldap(propname); - - if (ldap_attr) - ldap_data->list = g_list_prepend(ldap_data->list, - g_strdup_printf("(%s=%s)", - ldap_attr, str)); - else { - g_warning ("unknown query property\n"); - /* we want something that'll always be false */ - ldap_data->list = g_list_prepend(ldap_data->list, - g_strdup("objectClass=MyBarnIsBiggerThanYourBarn")); - } - - g_free (str); - } - - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_beginswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendLDAPSExpData *ldap_data = data; - ESExpResult *r; - - if (argc == 2 - && argv[0]->type == ESEXP_RES_STRING - && argv[1]->type == ESEXP_RES_STRING) { - char *propname = argv[0]->value.string; - char *str = rfc2254_escape(argv[1]->value.string); - char *ldap_attr = query_prop_to_ldap(propname); - - /* insert hack for fileAs queries, since we need to do - the right thing if the server supports them or not, - and for entries that have no fileAs attribute. */ - if (ldap_attr) { - if (!strcmp (propname, "full_name")) { - ldap_data->list = g_list_prepend(ldap_data->list, - g_strdup_printf( - "(|(cn=%s*)(sn=%s*))", - str, str)); - } - else if (!strcmp (ldap_attr, "fileAs")) { - if (ldap_data->bl->priv->evolutionPersonSupported) - ldap_data->list = g_list_prepend(ldap_data->list, - g_strdup_printf("(|(fileAs=%s*)(&(!(fileAs=*))(sn=%s*)))", - str, str)); - else - ldap_data->list = g_list_prepend(ldap_data->list, - g_strdup_printf("(sn=%s*)", str)); - } - else { - ldap_data->list = g_list_prepend(ldap_data->list, - g_strdup_printf("(%s=%s*)", - ldap_attr, - str)); - } - } - - g_free (str); - } - - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_endswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendLDAPSExpData *ldap_data = data; - ESExpResult *r; - - if (argc == 2 - && argv[0]->type == ESEXP_RES_STRING - && argv[1]->type == ESEXP_RES_STRING) { - char *propname = argv[0]->value.string; - char *str = rfc2254_escape(argv[1]->value.string); - char *ldap_attr = query_prop_to_ldap(propname); - - if (ldap_attr) - ldap_data->list = g_list_prepend(ldap_data->list, - g_strdup_printf("(%s=*%s)", - ldap_attr, - str)); - g_free (str); - } - - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -static ESExpResult * -func_exists(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendLDAPSExpData *ldap_data = data; - ESExpResult *r; - - if (argc == 1 - && argv[0]->type == ESEXP_RES_STRING) { - char *propname = argv[0]->value.string; - - if (!strcmp (propname, "x-evolution-any-field")) { - int i; - int query_length; - char *big_query; - char *match_str; - - match_str = g_strdup("=*)"); - - query_length = 3; /* strlen ("(|") + strlen (")") */ - - for (i = 0; i < num_prop_infos; i ++) { - query_length += 1 /* strlen ("(") */ + strlen(prop_info[i].ldap_attr) + strlen (match_str); - } - - big_query = g_malloc0(query_length + 1); - strcat (big_query, "(|"); - for (i = 0; i < num_prop_infos; i ++) { - strcat (big_query, "("); - strcat (big_query, prop_info[i].ldap_attr); - strcat (big_query, match_str); - } - strcat (big_query, ")"); - - ldap_data->list = g_list_prepend(ldap_data->list, big_query); - - g_free (match_str); - } - else { - char *ldap_attr = query_prop_to_ldap(propname); - - if (ldap_attr) - ldap_data->list = g_list_prepend(ldap_data->list, - g_strdup_printf("(%s=*)", ldap_attr)); - } - } - - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = FALSE; - - return r; -} - -/* 'builtin' functions */ -static struct { - char *name; - ESExpFunc *func; - int type; /* set to 1 if a function can perform shortcut evaluation, or - doesn't execute everything, 0 otherwise */ -} symbols[] = { - { "and", func_and, 0 }, - { "or", func_or, 0 }, - { "not", func_not, 0 }, - { "contains", func_contains, 0 }, - { "is", func_is, 0 }, - { "beginswith", func_beginswith, 0 }, - { "endswith", func_endswith, 0 }, - { "exists", func_exists, 0 }, -}; - -static gchar * -pas_backend_ldap_build_query (PASBackendLDAP *bl, const char *query) -{ - ESExp *sexp; - ESExpResult *r; - gchar *retval; - PASBackendLDAPSExpData data; - int i; - - data.list = NULL; - data.bl = bl; - - sexp = e_sexp_new(); - - for(i=0;inext) { - g_warning ("conversion to ldap query string failed"); - retval = NULL; - g_list_foreach (data.list, (GFunc)g_free, NULL); - } - else { - retval = data.list->data; - } - } - else { - g_warning ("conversion to ldap query string failed"); - retval = NULL; - } - - g_list_free (data.list); - return retval; -} - -static gchar * -query_prop_to_ldap(gchar *query_prop) -{ - int i; - - for (i = 0; i < num_prop_infos; i ++) - if (!strcmp (query_prop, e_contact_field_name (prop_info[i].field_id))) - return prop_info[i].ldap_attr; - - return NULL; -} - - -typedef struct { - LDAPOp op; - PASBookView *view; - - /* used by search_handler to only send the status messages once */ - gboolean notified_receiving_results; -} LDAPSearchOp; - -static EContact * -build_contact_from_entry (LDAP *ldap, LDAPMessage *e, GList **existing_objectclasses) -{ - EContact *contact = e_contact_new (); - char *dn; - char *attr; - BerElement *ber = NULL; - - dn = ldap_get_dn(ldap, e); - e_contact_set (contact, E_CONTACT_UID, dn); - ldap_memfree (dn); - - for (attr = ldap_first_attribute (ldap, e, &ber); attr; - attr = ldap_next_attribute (ldap, e, ber)) { - int i; - struct prop_info *info = NULL; - char **values; - - 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])); - - ldap_value_free (values); - } - else { - for (i = 0; i < num_prop_infos; i ++) - if (!g_ascii_strcasecmp (attr, prop_info[i].ldap_attr)) { - info = &prop_info[i]; - break; - } - - printf ("attr = %s, ", attr); - printf ("info = %p\n", info); - - if (info) { - if (info->prop_type & PROP_WRITE_ONLY) - continue; - - if (info->prop_type & PROP_TYPE_BINARY) { - struct berval **ber_values = ldap_get_values_len (ldap, e, attr); - - if (ber_values) { - info->binary_populate_contact_func (contact, ber_values); - - ldap_value_free_len (ber_values); - } - } - else { - values = ldap_get_values (ldap, e, attr); - - if (values) { - if (info->prop_type & PROP_TYPE_STRING) { - printf ("value = %s\n", values[0]); - /* if it's a normal property just set the string */ - if (values[0]) - e_contact_set (contact, info->field_id, values[0]); - } - else if (info->prop_type & PROP_TYPE_COMPLEX) { - /* if it's a list call the contact-populate function, - which calls g_object_set to set the property */ - info->populate_contact_func(contact, - values); - } - - ldap_value_free (values); - } - } - } - } - - ldap_memfree (attr); - } - - if (ber) - ber_free (ber, 0); - - return contact; -} - -static gboolean -poll_ldap (PASBackendLDAP *bl) -{ - LDAP *ldap = bl->priv->ldap; - int rc; - LDAPMessage *res; - struct timeval timeout; - - if (!bl->priv->active_ops) { - g_warning ("poll_ldap being called for backend with no active operations"); - return FALSE; - } - - timeout.tv_sec = 0; - timeout.tv_usec = LDAP_RESULT_TIMEOUT_MILLIS * 1000; - - rc = ldap_result (ldap, LDAP_RES_ANY, 0, &timeout, &res); - if (rc != 0) {/* rc == 0 means timeout exceeded */ - if (rc == -1) { - PASBookView *book_view = find_book_view (bl); - g_warning ("ldap_result returned -1, restarting ops"); - - pas_backend_ldap_reconnect (bl, book_view, LDAP_SERVER_DOWN); -#if 0 - if (bl->priv->connected) - restart_ops (bl); -#endif - } - else { - int msgid = ldap_msgid (res); - LDAPOp *op; - - op = g_hash_table_lookup (bl->priv->id_to_op, &msgid); - - if (op) - op->handler (op, res); - else - g_warning ("unknown operation, msgid = %d", msgid); - - ldap_msgfree(res); - } - } - - return TRUE; -} - -static void -ldap_search_handler (LDAPOp *op, LDAPMessage *res) -{ - LDAPSearchOp *search_op = (LDAPSearchOp*)op; - PASBookView *view = search_op->view; - PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend); - LDAP *ldap = bl->priv->ldap; - LDAPMessage *e; - int msg_type; - - bonobo_object_dup_ref(bonobo_object_corba_objref(BONOBO_OBJECT(view)), NULL); - - if (!search_op->notified_receiving_results) { - search_op->notified_receiving_results = TRUE; - book_view_notify_status (op->view, _("Receiving LDAP search results...")); - } - - msg_type = ldap_msgtype (res); - if (msg_type == LDAP_RES_SEARCH_ENTRY) { - e = ldap_first_entry(ldap, res); - - while (NULL != e) { - EContact *contact = build_contact_from_entry (ldap, e, NULL); - - pas_book_view_notify_update (view, contact); - - g_object_unref (contact); - - e = ldap_next_entry(ldap, e); - } - } - else if (msg_type == LDAP_RES_SEARCH_RESULT) { - int ldap_error; - - ldap_parse_result (ldap, res, &ldap_error, - NULL, NULL, NULL, NULL, 0); - - g_warning ("search returned %d\n", ldap_error); - - if (ldap_error == LDAP_TIMELIMIT_EXCEEDED) - pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_SearchTimeLimitExceeded); - else if (ldap_error == LDAP_SIZELIMIT_EXCEEDED) - pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_SearchSizeLimitExceeded); - else if (ldap_error == LDAP_SUCCESS) - pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_Success); - else - pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_OtherError); - - ldap_op_finished (op); - } - else { - g_warning ("unhandled search result type %d returned", msg_type); - pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_OtherError); - ldap_op_finished (op); - } - - - bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view)), NULL); -} - -static void -ldap_search_dtor (LDAPOp *op) -{ - LDAPSearchOp *search_op = (LDAPSearchOp*) op; - -#if notyet - /* unhook us from our PASBackendLDAPBookView */ - if (search_op->view) - search_op->view->search_op = NULL; -#endif - - g_free (search_op); -} - -static void -pas_backend_ldap_search (PASBackendLDAP *bl, - PASBook *book, - PASBookView *view) -{ - char *ldap_query; - - ldap_query = pas_backend_ldap_build_query (bl, pas_book_view_get_card_query (view)); - - if (ldap_query != NULL) { - LDAP *ldap = bl->priv->ldap; - int ldap_err; - int search_msgid; - - printf ("searching server using filter: %s\n", ldap_query); - - do { - book_view_notify_status (view, _("Searching...")); - - ldap_err = ldap_search_ext (ldap, bl->priv->ldap_rootdn, - bl->priv->ldap_scope, - ldap_query, - NULL, 0, - NULL, /* XXX */ - NULL, /* XXX */ - NULL, /* XXX timeout */ - 0 /* XXX we need this back in view->limit*/, &search_msgid); - } while (pas_backend_ldap_reconnect (bl, view, ldap_err)); - - g_free (ldap_query); - - if (ldap_err != LDAP_SUCCESS) { - book_view_notify_status (view, ldap_err2string(ldap_err)); - return; - } - else if (search_msgid == -1) { - book_view_notify_status (view, - _("Error performing search")); - return; - } - else { - LDAPSearchOp *op = g_new0 (LDAPSearchOp, 1); - - op->view = view; - -#if notyet - view->search_op = (LDAPOp*)op; -#endif - - ldap_op_add ((LDAPOp*)op, PAS_BACKEND(bl), book, view, - search_msgid, - ldap_search_handler, ldap_search_dtor); - - } - return; - } - else { - pas_book_view_notify_complete (view, - GNOME_Evolution_Addressbook_InvalidQuery); - return; - } - -} - -static void -pas_backend_ldap_process_start_book_view (PASBackend *backend, - PASBookView *view) -{ - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - - pas_backend_ldap_search (bl, NULL /* XXX ugh */, view); -} - -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) -{ - /* FIXME: implement */ -} - -#define LDAP_SIMPLE_PREFIX "ldap/simple-" -#define SASL_PREFIX "sasl/" - -static void -pas_backend_ldap_process_authenticate_user (PASBackend *backend, - PASBook *book, - const char *user, - const char *passwd, - const char *auth_method) -{ - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - int ldap_error; - char *dn = NULL; - - if (!strncasecmp (auth_method, LDAP_SIMPLE_PREFIX, strlen (LDAP_SIMPLE_PREFIX))) { - - if (!strcmp (auth_method, "ldap/simple-email")) { - LDAPMessage *res, *e; - char *query = g_strdup_printf ("(mail=%s)", user); - - ldap_error = ldap_search_s (bl->priv->ldap, - bl->priv->ldap_rootdn, - bl->priv->ldap_scope, - query, - NULL, 0, &res); - g_free (query); - - if (ldap_error == LDAP_SUCCESS) { - char *entry_dn; - - e = ldap_first_entry (bl->priv->ldap, res); - - entry_dn = ldap_get_dn (bl->priv->ldap, e); - dn = g_strdup(entry_dn); - - ldap_memfree (entry_dn); - ldap_msgfree (res); - } - else { - pas_book_respond_authenticate_user (book, - GNOME_Evolution_Addressbook_PermissionDenied); - return; - } - } - else if (!strcmp (auth_method, "ldap/simple-binddn")) { - dn = g_strdup (user); - } - - /* now authenticate against the DN we were either supplied or queried for */ - printf ("simple auth as %s\n", dn); - ldap_error = ldap_simple_bind_s(bl->priv->ldap, - dn, - passwd); - - pas_book_respond_authenticate_user (book, - ldap_error_to_response (ldap_error)); - } -#ifdef ENABLE_SASL_BINDS - else if (!strncasecmp (auth_method, SASL_PREFIX, strlen (SASL_PREFIX))) { - g_print ("sasl bind (mech = %s) as %s", auth_method + strlen (SASL_PREFIX), user); - ldap_error = ldap_sasl_bind_s (bl->priv->ldap, - NULL, - auth_method + strlen (SASL_PREFIX), - passwd, - NULL, - NULL, - NULL); - - if (ldap_error == LDAP_NOT_SUPPORTED) - pas_book_respond_authenticate_user (book, - GNOME_Evolution_Addressbook_UnsupportedAuthenticationMethod); - else - pas_book_respond_authenticate_user (book, - ldap_error_to_response (ldap_error)); - } -#endif - else { - pas_book_respond_authenticate_user (book, - GNOME_Evolution_Addressbook_UnsupportedAuthenticationMethod); - return; - } - - if (ldap_error == LDAP_SUCCESS) { - bl->priv->auth_dn = dn; - bl->priv->auth_passwd = g_strdup (passwd); - - pas_backend_set_is_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); - } - - pas_book_report_writable (book, TRUE); - } - -} - -static void -pas_backend_ldap_process_get_supported_fields (PASBackend *backend, - PASBook *book) - -{ - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - - pas_book_respond_get_supported_fields (book, - GNOME_Evolution_Addressbook_Success, - bl->priv->supported_fields); -} - -static void -pas_backend_ldap_process_get_supported_auth_methods (PASBackend *backend, - PASBook *book) - -{ - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - - pas_book_respond_get_supported_auth_methods (book, - GNOME_Evolution_Addressbook_Success, - bl->priv->supported_auth_methods); -} - -static GNOME_Evolution_Addressbook_CallStatus -pas_backend_ldap_load_uri (PASBackend *backend, - const char *uri, - gboolean only_if_exists) -{ - PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend); - LDAPURLDesc *lud; - int ldap_error; - char **attributes; - int i; - int limit = 100; - int timeout = 60; /* 1 minute */ - - g_assert (bl->priv->connected == FALSE); - - attributes = g_strsplit (uri, ";", 0); - - if (attributes[0] == NULL) - return FALSE; - - for (i = 1; attributes[i]; i++) { - char *equals; - char *value; - int key_length; - equals = strchr (attributes[i], '='); - if (equals) { - key_length = equals - attributes[i]; - value = equals + 1; - } else { - key_length = strlen (attributes[i]); - value = NULL; - } - - if (key_length == strlen("limit") && !strncmp (attributes[i], "limit", key_length)) { - if (value) - limit = atoi(value); - } - else if (key_length == strlen("ssl") && !strncmp (attributes[i], "ssl", key_length)) { - if (value) { - if (!strncmp (value, "always", 6)) { - bl->priv->use_tls = PAS_BACKEND_LDAP_TLS_ALWAYS; - } - else if (!strncmp (value, "whenever_possible", 3)) { - bl->priv->use_tls = PAS_BACKEND_LDAP_TLS_WHEN_POSSIBLE; - } - else if (strncmp (value, "never", 5)) { - g_warning ("unhandled value for use_tls, not using it"); - } - } - else { - bl->priv->use_tls = PAS_BACKEND_LDAP_TLS_WHEN_POSSIBLE; - } - } - else if (key_length == strlen("timeout") && !strncmp (attributes[i], "timeout", key_length)) { - if (value) - timeout = atoi (value); - } - } - - ldap_error = ldap_url_parse ((char*)attributes[0], &lud); - g_strfreev (attributes); - - if (ldap_error == LDAP_SUCCESS) { - g_free(bl->priv->uri); - bl->priv->uri = g_strdup (uri); - bl->priv->ldap_host = g_strdup(lud->lud_host); - bl->priv->ldap_port = lud->lud_port; - /* if a port wasn't specified, default to LDAP_PORT */ - if (bl->priv->ldap_port == 0) - bl->priv->ldap_port = LDAP_PORT; - bl->priv->ldap_rootdn = g_strdup(lud->lud_dn); - bl->priv->ldap_limit = limit; - bl->priv->ldap_timeout = timeout; - bl->priv->ldap_scope = lud->lud_scope; - - ldap_free_urldesc(lud); - - return pas_backend_ldap_connect (bl); - } else - return GNOME_Evolution_Addressbook_OtherError; -} - -static char* -pas_backend_ldap_get_static_capabilities (PASBackend *backend) -{ - return g_strdup("net"); -} - -static gboolean -pas_backend_ldap_construct (PASBackendLDAP *backend) -{ - g_assert (backend != NULL); - g_assert (PAS_IS_BACKEND_LDAP (backend)); - - if (! pas_backend_construct (PAS_BACKEND (backend))) - return FALSE; - - return TRUE; -} - -/** - * pas_backend_ldap_new: - */ -PASBackend * -pas_backend_ldap_new (void) -{ - PASBackendLDAP *backend; - - backend = g_object_new (PAS_TYPE_BACKEND_LDAP, NULL); - - if (! pas_backend_ldap_construct (backend)) { - g_object_unref (backend); - - return NULL; - } - - return PAS_BACKEND (backend); -} - -static gboolean -call_dtor (int msgid, LDAPOp *op, gpointer data) -{ - ldap_abandon (PAS_BACKEND_LDAP(op->backend)->priv->ldap, op->id); - - op->dtor (op); - - return TRUE; -} - -static void -pas_backend_ldap_dispose (GObject *object) -{ - PASBackendLDAP *bl; - - bl = PAS_BACKEND_LDAP (object); - - if (bl->priv) { - g_hash_table_foreach_remove (bl->priv->id_to_op, (GHRFunc)call_dtor, NULL); - g_hash_table_destroy (bl->priv->id_to_op); - - if (bl->priv->poll_timeout != -1) { - printf ("removing timeout\n"); - g_source_remove (bl->priv->poll_timeout); - } - - if (bl->priv->supported_fields) { - g_list_foreach (bl->priv->supported_fields, (GFunc)g_free, NULL); - g_list_free (bl->priv->supported_fields); - } - - if (bl->priv->supported_auth_methods) { - g_list_foreach (bl->priv->supported_auth_methods, (GFunc)g_free, NULL); - g_list_free (bl->priv->supported_auth_methods); - } - - g_free (bl->priv->uri); - - g_free (bl->priv); - bl->priv = NULL; - } - - if (G_OBJECT_CLASS (pas_backend_ldap_parent_class)->dispose) - G_OBJECT_CLASS (pas_backend_ldap_parent_class)->dispose (object); -} - -static void -pas_backend_ldap_class_init (PASBackendLDAPClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - PASBackendClass *parent_class; - - /* get client side information (extensions present in the library) */ - get_ldap_library_info (); - - pas_backend_ldap_parent_class = g_type_class_peek_parent (klass); - - parent_class = PAS_BACKEND_CLASS (klass); - - /* Set the virtual methods. */ - parent_class->load_uri = pas_backend_ldap_load_uri; - parent_class->get_static_capabilities = pas_backend_ldap_get_static_capabilities; - - parent_class->create_contact = pas_backend_ldap_process_create_contact; - parent_class->remove_contacts = pas_backend_ldap_process_remove_contacts; - 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; - parent_class->get_supported_auth_methods = pas_backend_ldap_process_get_supported_auth_methods; - - object_class->dispose = pas_backend_ldap_dispose; -} - -static void -pas_backend_ldap_init (PASBackendLDAP *backend) -{ - PASBackendLDAPPrivate *priv; - - priv = g_new0 (PASBackendLDAPPrivate, 1); - - priv->supported_fields = NULL; - priv->supported_auth_methods = NULL; - priv->ldap_limit = 100; - priv->id_to_op = g_hash_table_new (g_int_hash, g_int_equal); - priv->poll_timeout = -1; - - backend->priv = priv; -} - -/** - * pas_backend_ldap_get_type: - */ -GType -pas_backend_ldap_get_type (void) -{ - static GType type = 0; - - if (! type) { - GTypeInfo info = { - sizeof (PASBackendLDAPClass), - NULL, /* base_class_init */ - NULL, /* base_class_finalize */ - (GClassInitFunc) pas_backend_ldap_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PASBackendLDAP), - 0, /* n_preallocs */ - (GInstanceInitFunc) pas_backend_ldap_init - }; - - type = g_type_register_static (PAS_TYPE_BACKEND, "PASBackendLDAP", &info, 0); - } - - return type; -} diff --git a/addressbook/backend/pas/pas-backend-ldap.h b/addressbook/backend/pas/pas-backend-ldap.h deleted file mode 100644 index ca04ee6a21..0000000000 --- a/addressbook/backend/pas/pas-backend-ldap.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2000, Ximian, Inc. - */ - -#ifndef __PAS_BACKEND_LDAP_H__ -#define __PAS_BACKEND_LDAP_H__ - -#include "pas-backend.h" - -#define PAS_TYPE_BACKEND_LDAP (pas_backend_ldap_get_type ()) -#define PAS_BACKEND_LDAP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_LDAP, PASBackendLDAP)) -#define PAS_BACKEND_LDAP_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_BACKEND_TYPE, PASBackendLDAPClass)) -#define PAS_IS_BACKEND_LDAP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BACKEND_LDAP)) -#define PAS_IS_BACKEND_LDAP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BACKEND_LDAP)) -#define PAS_BACKEND_LDAP_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BACKEND_LDAP, PASBackendLDAPClass)) - -typedef struct _PASBackendLDAPPrivate PASBackendLDAPPrivate; - -typedef struct { - PASBackend parent_object; - PASBackendLDAPPrivate *priv; -} PASBackendLDAP; - -typedef struct { - PASBackendClass parent_class; -} PASBackendLDAPClass; - -PASBackend *pas_backend_ldap_new (void); -GType pas_backend_ldap_get_type (void); - -#endif /* ! __PAS_BACKEND_LDAP_H__ */ - diff --git a/addressbook/backend/pas/pas-backend-summary.c b/addressbook/backend/pas/pas-backend-summary.c deleted file mode 100644 index 268a0c7062..0000000000 --- a/addressbook/backend/pas/pas-backend-summary.c +++ /dev/null @@ -1,1078 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * pas-backend-summary.c - * Copyright 2000, 2001, Ximian, Inc. - * - * Authors: - * Chris Toshok - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#include "config.h" - -#include -#include -#include -#include -#include - -#include - -#include - -#include "ebook/e-contact.h" -#include "pas-backend-summary.h" -#include "e-util/e-sexp.h" - -static GObjectClass *parent_class; - -struct _PASBackendSummaryPrivate { - char *summary_path; - FILE *fp; - guint32 file_version; - time_t mtime; - gboolean upgraded; - gboolean dirty; - int flush_timeout_millis; - int flush_timeout; - GPtrArray *items; - GHashTable *id_to_item; - guint32 num_items; /* used only for loading */ -#ifdef SUMMARY_STATS - int size; -#endif -}; - -typedef struct { - char *id; - char *nickname; - char *full_name; - char *given_name; - char *surname; - char *file_as; - char *email_1; - char *email_2; - char *email_3; - gboolean wants_html; - gboolean wants_html_set; - gboolean list; - gboolean list_show_addresses; -} PASBackendSummaryItem; - -typedef struct { - /* these lengths do *not* including the terminating \0, as - it's not stored on disk. */ - guint16 id_len; - guint16 nickname_len; - guint16 full_name_len; /* version 3.0 field */ - guint16 given_name_len; - guint16 surname_len; - guint16 file_as_len; - guint16 email_1_len; - guint16 email_2_len; - guint16 email_3_len; - guint8 wants_html; - guint8 wants_html_set; - guint8 list; - guint8 list_show_addresses; -} PASBackendSummaryDiskItem; - -typedef struct { - guint32 file_version; - guint32 num_items; - guint32 summary_mtime; /* version 2.0 field */ -} PASBackendSummaryHeader; - -#define PAS_SUMMARY_MAGIC "PAS-SUMMARY" -#define PAS_SUMMARY_MAGIC_LEN 11 - -#define PAS_SUMMARY_FILE_VERSION_1_0 1000 -#define PAS_SUMMARY_FILE_VERSION_2_0 2000 -#define PAS_SUMMARY_FILE_VERSION_3_0 3000 -#define PAS_SUMMARY_FILE_VERSION_4_0 4000 - -#define PAS_SUMMARY_FILE_VERSION PAS_SUMMARY_FILE_VERSION_4_0 - -static void -free_summary_item (PASBackendSummaryItem *item) -{ - g_free (item->id); - g_free (item->nickname); - g_free (item->full_name); - g_free (item->given_name); - g_free (item->surname); - g_free (item->file_as); - g_free (item->email_1); - g_free (item->email_2); - g_free (item->email_3); - g_free (item); -} - -static void -clear_items (PASBackendSummary *summary) -{ - int i; - int num = summary->priv->items->len; - for (i = 0; i < num; i++) { - PASBackendSummaryItem *item = g_ptr_array_remove_index_fast (summary->priv->items, 0); - g_hash_table_remove (summary->priv->id_to_item, item->id); - free_summary_item (item); - } -} - -PASBackendSummary* -pas_backend_summary_new (const char *summary_path, int flush_timeout_millis) -{ - PASBackendSummary *summary = g_object_new (PAS_TYPE_BACKEND_SUMMARY, NULL); - - summary->priv->summary_path = g_strdup (summary_path); - summary->priv->flush_timeout_millis = flush_timeout_millis; - summary->priv->file_version = PAS_SUMMARY_FILE_VERSION_4_0; - - return summary; -} - -static void -pas_backend_summary_dispose (GObject *object) -{ - PASBackendSummary *summary = PAS_BACKEND_SUMMARY (object); - - if (summary->priv) { - if (summary->priv->dirty) - g_warning ("Destroying dirty summary"); - - if (summary->priv->flush_timeout) { - g_source_remove (summary->priv->flush_timeout); - summary->priv->flush_timeout = 0; - } - - if (summary->priv->fp) - fclose (summary->priv->fp); - - g_free (summary->priv->summary_path); - clear_items (summary); - g_ptr_array_free (summary->priv->items, TRUE); - - g_hash_table_destroy (summary->priv->id_to_item); - - g_free (summary->priv); - summary->priv = NULL; - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -pas_backend_summary_class_init (PASBackendSummaryClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - /* Set the virtual methods. */ - - object_class->dispose = pas_backend_summary_dispose; -} - -static void -pas_backend_summary_init (PASBackendSummary *summary) -{ - PASBackendSummaryPrivate *priv; - - priv = g_new(PASBackendSummaryPrivate, 1); - - summary->priv = priv; - - priv->summary_path = NULL; - priv->fp = NULL; - priv->dirty = FALSE; - priv->upgraded = FALSE; - priv->items = g_ptr_array_new(); - priv->id_to_item = g_hash_table_new (g_str_hash, g_str_equal); - priv->flush_timeout_millis = 0; - priv->flush_timeout = 0; -#ifdef SUMMARY_STATS - priv->size = 0; -#endif -} - -/** - * pas_backend_summary_get_type: - */ -GType -pas_backend_summary_get_type (void) -{ - static GType type = 0; - - if (! type) { - GTypeInfo info = { - sizeof (PASBackendSummaryClass), - NULL, /* base_class_init */ - NULL, /* base_class_finalize */ - (GClassInitFunc) pas_backend_summary_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PASBackendSummary), - 0, /* n_preallocs */ - (GInstanceInitFunc) pas_backend_summary_init - }; - - type = g_type_register_static (G_TYPE_OBJECT, "PASBackendSummary", &info, 0); - } - - return type; -} - - -static gboolean -pas_backend_summary_check_magic (PASBackendSummary *summary, FILE *fp) -{ - char buf [PAS_SUMMARY_MAGIC_LEN + 1]; - int rv; - - memset (buf, 0, sizeof (buf)); - - rv = fread (buf, PAS_SUMMARY_MAGIC_LEN, 1, fp); - if (rv != 1) - return FALSE; - if (strcmp (buf, PAS_SUMMARY_MAGIC)) - return FALSE; - - return TRUE; -} - -static gboolean -pas_backend_summary_load_header (PASBackendSummary *summary, FILE *fp, - PASBackendSummaryHeader *header) -{ - int rv; - - rv = fread (&header->file_version, sizeof (header->file_version), 1, fp); - if (rv != 1) - return FALSE; - - header->file_version = ntohl (header->file_version); - - if (header->file_version < PAS_SUMMARY_FILE_VERSION) { - return FALSE; /* this will cause the entire summary to be rebuilt */ - } - - rv = fread (&header->num_items, sizeof (header->num_items), 1, fp); - if (rv != 1) - return FALSE; - - header->num_items = ntohl (header->num_items); - - rv = fread (&header->summary_mtime, sizeof (header->summary_mtime), 1, fp); - if (rv != 1) - return FALSE; - header->summary_mtime = ntohl (header->summary_mtime); - - return TRUE; -} - -static char * -read_string (FILE *fp, int len) -{ - char *buf; - int rv; - - buf = g_new0 (char, len + 1); - - rv = fread (buf, len, 1, fp); - if (rv != 1) { - g_free (buf); - return NULL; - } - - return buf; -} - -static gboolean -pas_backend_summary_load_item (PASBackendSummary *summary, - PASBackendSummaryItem **new_item) -{ - PASBackendSummaryItem *item; - char *buf; - FILE *fp = summary->priv->fp; - - if (summary->priv->file_version >= PAS_SUMMARY_FILE_VERSION_4_0) { - PASBackendSummaryDiskItem disk_item; - int rv = fread (&disk_item, sizeof (disk_item), 1, fp); - if (rv != 1) - return FALSE; - - disk_item.id_len = ntohs (disk_item.id_len); - disk_item.nickname_len = ntohs (disk_item.nickname_len); - disk_item.full_name_len = ntohs (disk_item.full_name_len); - disk_item.given_name_len = ntohs (disk_item.given_name_len); - disk_item.surname_len = ntohs (disk_item.surname_len); - disk_item.file_as_len = ntohs (disk_item.file_as_len); - disk_item.email_1_len = ntohs (disk_item.email_1_len); - disk_item.email_2_len = ntohs (disk_item.email_2_len); - disk_item.email_3_len = ntohs (disk_item.email_3_len); - - item = g_new0 (PASBackendSummaryItem, 1); - - item->wants_html = disk_item.wants_html; - item->wants_html_set = disk_item.wants_html_set; - item->list = disk_item.list; - item->list_show_addresses = disk_item.list_show_addresses; - - if (disk_item.id_len) { - buf = read_string (fp, disk_item.id_len); - if (!buf) { - free_summary_item (item); - return FALSE; - } - item->id = buf; - } - - if (disk_item.nickname_len) { - buf = read_string (fp, disk_item.nickname_len); - if (!buf) { - free_summary_item (item); - return FALSE; - } - item->nickname = buf; - } - - if (disk_item.full_name_len) { - buf = read_string (fp, disk_item.full_name_len); - if (!buf) { - free_summary_item (item); - return FALSE; - } - item->full_name = buf; - } - - if (disk_item.given_name_len) { - buf = read_string (fp, disk_item.given_name_len); - if (!buf) { - free_summary_item (item); - return FALSE; - } - item->given_name = buf; - } - - if (disk_item.surname_len) { - buf = read_string (fp, disk_item.surname_len); - if (!buf) { - free_summary_item (item); - return FALSE; - } - item->surname = buf; - } - - if (disk_item.file_as_len) { - buf = read_string (fp, disk_item.file_as_len); - if (!buf) { - free_summary_item (item); - return FALSE; - } - item->file_as = buf; - } - - if (disk_item.email_1_len) { - buf = read_string (fp, disk_item.email_1_len); - if (!buf) { - free_summary_item (item); - return FALSE; - } - item->email_1 = buf; - } - - if (disk_item.email_2_len) { - buf = read_string (fp, disk_item.email_2_len); - if (!buf) { - free_summary_item (item); - return FALSE; - } - item->email_2 = buf; - } - - if (disk_item.email_3_len) { - buf = read_string (fp, disk_item.email_3_len); - if (!buf) { - free_summary_item (item); - return FALSE; - } - item->email_3 = buf; - } - - /* the only field that has to be there is the id */ - if (!item->id) { - free_summary_item (item); - return FALSE; - } - } - else { - /* unhandled file version */ - return FALSE; - } - - *new_item = item; - return TRUE; -} - -/* opens the file and loads the header */ -static gboolean -pas_backend_summary_open (PASBackendSummary *summary) -{ - FILE *fp; - PASBackendSummaryHeader header; - struct stat sb; - - if (summary->priv->fp) - return TRUE; - - if (stat (summary->priv->summary_path, &sb) == -1) { - /* if there's no summary present, look for the .new - file and rename it if it's there, and attempt to - load that */ - char *new_filename = g_strconcat (summary->priv->summary_path, ".new", NULL); - if (stat (new_filename, &sb) == -1) { - g_warning ("no summary present"); - g_free (new_filename); - return FALSE; - } - else { - rename (new_filename, summary->priv->summary_path); - g_free (new_filename); - } - } - - fp = fopen (summary->priv->summary_path, "r"); - if (!fp) { - g_warning ("failed to open summary file"); - return FALSE; - } - - if (!pas_backend_summary_check_magic (summary, fp)) { - g_warning ("file is not a valid summary file"); - fclose (fp); - return FALSE; - } - - if (!pas_backend_summary_load_header (summary, fp, &header)) { - g_warning ("failed to read summary header"); - fclose (fp); - return FALSE; - } - - summary->priv->num_items = header.num_items; - summary->priv->file_version = header.file_version; - summary->priv->mtime = header.summary_mtime; - summary->priv->fp = fp; - - return TRUE; -} - -gboolean -pas_backend_summary_load (PASBackendSummary *summary) -{ - PASBackendSummaryItem *new_item; - int i; - - if (!pas_backend_summary_open (summary)) - return FALSE; - - for (i = 0; i < summary->priv->num_items; i ++) { - if (!pas_backend_summary_load_item (summary, &new_item)) { - g_warning ("error while reading summary item"); - clear_items (summary); - fclose (summary->priv->fp); - summary->priv->fp = NULL; - summary->priv->dirty = FALSE; - return FALSE; - } - - g_ptr_array_add (summary->priv->items, new_item); - g_hash_table_insert (summary->priv->id_to_item, new_item->id, new_item); - } - - if (summary->priv->upgraded) { - pas_backend_summary_save (summary); - } - summary->priv->dirty = FALSE; - - return TRUE; -} - -static gboolean -pas_backend_summary_save_magic (FILE *fp) -{ - int rv; - rv = fwrite (PAS_SUMMARY_MAGIC, PAS_SUMMARY_MAGIC_LEN, 1, fp); - if (rv != 1) - return FALSE; - - return TRUE; -} - -static gboolean -pas_backend_summary_save_header (PASBackendSummary *summary, FILE *fp) -{ - PASBackendSummaryHeader header; - int rv; - - header.file_version = htonl (PAS_SUMMARY_FILE_VERSION); - header.num_items = htonl (summary->priv->items->len); - header.summary_mtime = htonl (time (NULL)); - - rv = fwrite (&header, sizeof (header), 1, fp); - if (rv != 1) - return FALSE; - - return TRUE; -} - -static gboolean -save_string (const char *str, FILE *fp) -{ - int rv; - - if (!str || !*str) - return TRUE; - - rv = fwrite (str, strlen (str), 1, fp); - return (rv == 1); -} - -static gboolean -pas_backend_summary_save_item (PASBackendSummary *summary, FILE *fp, PASBackendSummaryItem *item) -{ - PASBackendSummaryDiskItem disk_item; - int len; - int rv; - - len = item->id ? strlen (item->id) : 0; - disk_item.id_len = htons (len); - - len = item->nickname ? strlen (item->nickname) : 0; - disk_item.nickname_len = htons (len); - - len = item->given_name ? strlen (item->given_name) : 0; - disk_item.given_name_len = htons (len); - - len = item->full_name ? strlen (item->full_name) : 0; - disk_item.full_name_len = htons (len); - - len = item->surname ? strlen (item->surname) : 0; - disk_item.surname_len = htons (len); - - len = item->file_as ? strlen (item->file_as) : 0; - disk_item.file_as_len = htons (len); - - len = item->email_1 ? strlen (item->email_1) : 0; - disk_item.email_1_len = htons (len); - - len = item->email_2 ? strlen (item->email_2) : 0; - disk_item.email_2_len = htons (len); - - len = item->email_3 ? strlen (item->email_3) : 0; - disk_item.email_3_len = htons (len); - - disk_item.wants_html = item->wants_html; - disk_item.wants_html_set = item->wants_html_set; - disk_item.list = item->list; - disk_item.list_show_addresses = item->list_show_addresses; - - rv = fwrite (&disk_item, sizeof(disk_item), 1, fp); - if (rv != 1) - return FALSE; - - if (!save_string (item->id, fp)) - return FALSE; - if (!save_string (item->nickname, fp)) - return FALSE; - if (!save_string (item->full_name, fp)) - return FALSE; - if (!save_string (item->given_name, fp)) - return FALSE; - if (!save_string (item->surname, fp)) - return FALSE; - if (!save_string (item->file_as, fp)) - return FALSE; - if (!save_string (item->email_1, fp)) - return FALSE; - if (!save_string (item->email_2, fp)) - return FALSE; - if (!save_string (item->email_3, fp)) - return FALSE; - - return TRUE; -} - -gboolean -pas_backend_summary_save (PASBackendSummary *summary) -{ - struct stat sb; - FILE *fp = NULL; - char *new_filename = NULL; - int i; - - if (!summary->priv->dirty) - return TRUE; - - new_filename = g_strconcat (summary->priv->summary_path, ".new", NULL); - - fp = fopen (new_filename, "w"); - if (!fp) { - g_warning ("could not create new summary file"); - goto lose; - } - - if (!pas_backend_summary_save_magic (fp)) { - g_warning ("could not write magic to new summary file"); - goto lose; - } - - if (!pas_backend_summary_save_header (summary, fp)) { - g_warning ("could not write header to new summary file"); - goto lose; - } - - for (i = 0; i < summary->priv->items->len; i ++) { - PASBackendSummaryItem *item = g_ptr_array_index (summary->priv->items, i); - if (!pas_backend_summary_save_item (summary, fp, item)) { - g_warning ("failed to write an item to new summary file, errno = %d", errno); - goto lose; - } - } - - fclose (fp); - - /* if we have a queued flush, clear it (since we just flushed) */ - if (summary->priv->flush_timeout) { - g_source_remove (summary->priv->flush_timeout); - summary->priv->flush_timeout = 0; - } - - /* unlink the old summary and rename the new one */ - unlink (summary->priv->summary_path); - rename (new_filename, summary->priv->summary_path); - - g_free (new_filename); - - /* lastly, update the in memory mtime to that of the file */ - if (stat (summary->priv->summary_path, &sb) == -1) { - g_warning ("error stat'ing saved summary"); - } - else { - summary->priv->mtime = sb.st_mtime; - } - - return TRUE; - - lose: - if (fp) - fclose (fp); - if (new_filename) - unlink (new_filename); - g_free (new_filename); - return FALSE; -} - -void -pas_backend_summary_add_contact (PASBackendSummary *summary, EContact *contact) -{ - PASBackendSummaryItem *new_item; - - new_item = g_new0 (PASBackendSummaryItem, 1); - - new_item->id = e_contact_get (contact, E_CONTACT_UID); - new_item->nickname = e_contact_get (contact, E_CONTACT_NICKNAME); - new_item->full_name = e_contact_get (contact, E_CONTACT_FULL_NAME); - new_item->given_name = e_contact_get (contact, E_CONTACT_GIVEN_NAME); - new_item->surname = e_contact_get (contact, E_CONTACT_FAMILY_NAME); - new_item->file_as = e_contact_get (contact, E_CONTACT_FILE_AS); - new_item->email_1 = e_contact_get (contact, E_CONTACT_EMAIL_1); - new_item->email_2 = e_contact_get (contact, E_CONTACT_EMAIL_2); - new_item->email_3 = e_contact_get (contact, E_CONTACT_EMAIL_3); - new_item->list = GPOINTER_TO_INT (e_contact_get (contact, E_CONTACT_IS_LIST)); - new_item->list_show_addresses = GPOINTER_TO_INT (e_contact_get (contact, E_CONTACT_LIST_SHOW_ADDRESSES)); - new_item->wants_html = GPOINTER_TO_INT (e_contact_get (contact, E_CONTACT_WANTS_HTML)); - - g_ptr_array_add (summary->priv->items, new_item); - g_hash_table_insert (summary->priv->id_to_item, new_item->id, new_item); - -#ifdef SUMMARY_STATS - summary->priv->size += sizeof (PASBackendSummaryItem); - summary->priv->size += new_item->id ? strlen (new_item->id) : 0; - summary->priv->size += new_item->nickname ? strlen (new_item->nickname) : 0; - summary->priv->size += new_item->full_name ? strlen (new_item->full_name) : 0; - summary->priv->size += new_item->given_name ? strlen (new_item->given_name) : 0; - summary->priv->size += new_item->surname ? strlen (new_item->surname) : 0; - summary->priv->size += new_item->file_as ? strlen (new_item->file_as) : 0; - summary->priv->size += new_item->email_1 ? strlen (new_item->email_1) : 0; - summary->priv->size += new_item->email_2 ? strlen (new_item->email_2) : 0; - summary->priv->size += new_item->email_3 ? strlen (new_item->email_3) : 0; -#endif - pas_backend_summary_touch (summary); -} - -void -pas_backend_summary_remove_contact (PASBackendSummary *summary, const char *id) -{ - PASBackendSummaryItem *item = g_hash_table_lookup (summary->priv->id_to_item, id); - - if (item) { - g_ptr_array_remove (summary->priv->items, item); - g_hash_table_remove (summary->priv->id_to_item, id); - free_summary_item (item); - pas_backend_summary_touch (summary); - return; - } - - g_warning ("pas_backend_summary_remove_contact: unable to locate id `%s'", id); -} - -static gboolean -summary_flush_func (gpointer data) -{ - PASBackendSummary *summary = PAS_BACKEND_SUMMARY (data); - - if (!summary->priv->dirty) { - summary->priv->flush_timeout = 0; - return FALSE; - } - - if (!pas_backend_summary_save (summary)) { - /* this isn't fatal, as we can just either 1) flush - out with the next change, or 2) regen the summary - when we next load the uri */ - g_warning ("failed to flush summary file to disk"); - return TRUE; /* try again after the next timeout */ - } - - g_warning ("flushed summary to disk"); - - /* we only want this to execute once, so return FALSE and set - summary->flush_timeout to 0 */ - summary->priv->flush_timeout = 0; - return FALSE; -} - -void -pas_backend_summary_touch (PASBackendSummary *summary) -{ - summary->priv->dirty = TRUE; - if (!summary->priv->flush_timeout - && summary->priv->flush_timeout_millis) - summary->priv->flush_timeout = g_timeout_add (summary->priv->flush_timeout_millis, - summary_flush_func, summary); -} - -gboolean -pas_backend_summary_is_up_to_date (PASBackendSummary *summary, time_t t) -{ - if (!pas_backend_summary_open (summary)) - return FALSE; - else - return summary->priv->mtime >= t; -} - - -/* we only want to do summary queries if the query is over the set fields in the summary */ - -static ESExpResult * -func_check(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - ESExpResult *r; - int truth = FALSE; - - if (argc == 2 - && argv[0]->type == ESEXP_RES_STRING - && argv[1]->type == ESEXP_RES_STRING) { - char *query_name = argv[0]->value.string; - - if (!strcmp (query_name, "nickname") || - !strcmp (query_name, "full_name") || - !strcmp (query_name, "file_as") || - !strcmp (query_name, "email")) { - truth = TRUE; - } - } - - r = e_sexp_result_new(f, ESEXP_RES_BOOL); - r->value.bool = truth; - - return r; -} - -/* 'builtin' functions */ -static struct { - char *name; - ESExpFunc *func; - int type; /* set to 1 if a function can perform shortcut evaluation, or - doesn't execute everything, 0 otherwise */ -} check_symbols[] = { - { "contains", func_check, 0 }, - { "is", func_check, 0 }, - { "beginswith", func_check, 0 }, - { "endswith", func_check, 0 }, -}; - -gboolean -pas_backend_summary_is_summary_query (PASBackendSummary *summary, const char *query) -{ - ESExp *sexp; - ESExpResult *r; - gboolean retval; - int i; - int esexp_error; - - sexp = e_sexp_new(); - - for(i=0;itype == ESEXP_RES_BOOL && r->value.bool); - - e_sexp_result_free(sexp, r); - - e_sexp_unref (sexp); - - return retval; -} - - - -/* the actual query mechanics */ -static ESExpResult * -do_compare (PASBackendSummary *summary, struct _ESExp *f, int argc, - struct _ESExpResult **argv, - char *(*compare)(const char*, const char*)) -{ - GPtrArray *result = g_ptr_array_new (); - ESExpResult *r; - int i; - - if (argc == 2 - && argv[0]->type == ESEXP_RES_STRING - && argv[1]->type == ESEXP_RES_STRING) { - - for (i = 0; i < summary->priv->items->len; i ++) { - PASBackendSummaryItem *item = g_ptr_array_index (summary->priv->items, i); - if (!strcmp (argv[0]->value.string, "full_name")) { - char *given = item->given_name; - char *surname = item->surname; - if ((given && compare (given, argv[1]->value.string)) - || (surname && compare (surname, argv[1]->value.string))) - g_ptr_array_add (result, item->id); - } - else if (!strcmp (argv[0]->value.string, "email")) { - char *email_1 = item->email_1; - char *email_2 = item->email_2; - char *email_3 = item->email_3; - if ((email_1 && compare (email_1, argv[1]->value.string)) - || (email_2 && compare (email_2, argv[1]->value.string)) - || (email_3 && compare (email_3, argv[1]->value.string))) - g_ptr_array_add (result, item->id); - } - else if (!strcmp (argv[0]->value.string, "file_as")) { - char *file_as = item->file_as; - if (file_as && compare (file_as, argv[1]->value.string)) - g_ptr_array_add (result, item->id); - } - else if (!strcmp (argv[0]->value.string, "nickname")) { - char *nickname = item->nickname; - if (nickname && compare (nickname, argv[1]->value.string)) - g_ptr_array_add (result, item->id); - } - } - } - - r = e_sexp_result_new(f, ESEXP_RES_ARRAY_PTR); - r->value.ptrarray = result; - - return r; -} - -static ESExpResult * -func_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendSummary *summary = data; - - return do_compare (summary, f, argc, argv, (char *(*)(const char*, const char*)) e_utf8_strstrcase); -} - -static char * -is_helper (const char *s1, const char *s2) -{ - if (!strcasecmp(s1, s2)) - return (char*)s1; - else - return NULL; -} - -static ESExpResult * -func_is(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendSummary *summary = data; - - return do_compare (summary, f, argc, argv, is_helper); -} - -static char * -endswith_helper (const char *s1, const char *s2) -{ - char *p; - if ((p = (char*)e_utf8_strstrcase(s1, s2)) - && (strlen(p) == strlen(s2))) - return p; - else - return NULL; -} - -static ESExpResult * -func_endswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendSummary *summary = data; - - return do_compare (summary, f, argc, argv, endswith_helper); -} - -static char * -beginswith_helper (const char *s1, const char *s2) -{ - char *p; - if ((p = (char*)e_utf8_strstrcase(s1, s2)) - && (p == s1)) - return p; - else - return NULL; -} - -static ESExpResult * -func_beginswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) -{ - PASBackendSummary *summary = data; - - return do_compare (summary, f, argc, argv, beginswith_helper); -} - -/* 'builtin' functions */ -static struct { - char *name; - ESExpFunc *func; - int type; /* set to 1 if a function can perform shortcut evaluation, or - doesn't execute everything, 0 otherwise */ -} symbols[] = { - { "contains", func_contains, 0 }, - { "is", func_is, 0 }, - { "beginswith", func_beginswith, 0 }, - { "endswith", func_endswith, 0 }, -}; - -GPtrArray* -pas_backend_summary_search (PASBackendSummary *summary, const char *query) -{ - ESExp *sexp; - ESExpResult *r; - GPtrArray *retval = g_ptr_array_new(); - int i; - int esexp_error; - - sexp = e_sexp_new(); - - for(i=0;itype == ESEXP_RES_ARRAY_PTR && r->value.ptrarray) { - GPtrArray *ptrarray = r->value.ptrarray; - int i; - - for (i = 0; i < ptrarray->len; i ++) - g_ptr_array_add (retval, g_ptr_array_index (ptrarray, i)); - } - - e_sexp_result_free(sexp, r); - - e_sexp_unref (sexp); - - return retval; -} - -char* -pas_backend_summary_get_summary_vcard(PASBackendSummary *summary, const char *id) -{ - PASBackendSummaryItem *item = g_hash_table_lookup (summary->priv->id_to_item, id); - - if (item) { - EContact *contact = e_contact_new (); - char *vcard; - - e_contact_set (contact, E_CONTACT_UID, item->id); - e_contact_set (contact, E_CONTACT_FILE_AS, item->file_as); - e_contact_set (contact, E_CONTACT_GIVEN_NAME, item->given_name); - e_contact_set (contact, E_CONTACT_FAMILY_NAME, item->surname); - e_contact_set (contact, E_CONTACT_NICKNAME, item->nickname); - e_contact_set (contact, E_CONTACT_FULL_NAME, item->full_name); - e_contact_set (contact, E_CONTACT_EMAIL_1, item->email_1); - e_contact_set (contact, E_CONTACT_EMAIL_2, item->email_2); - e_contact_set (contact, E_CONTACT_EMAIL_3, item->email_3); - - e_contact_set (contact, E_CONTACT_IS_LIST, GINT_TO_POINTER (item->list)); - e_contact_set (contact, E_CONTACT_LIST_SHOW_ADDRESSES, GINT_TO_POINTER (item->list_show_addresses)); - e_contact_set (contact, E_CONTACT_WANTS_HTML, GINT_TO_POINTER (item->wants_html)); - - vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); - - g_object_unref (contact); - - return vcard; - } - else { - g_warning ("in unable to locate card `%s' in summary", id); - return NULL; - } -} - diff --git a/addressbook/backend/pas/pas-backend-summary.h b/addressbook/backend/pas/pas-backend-summary.h deleted file mode 100644 index bb07e0fb27..0000000000 --- a/addressbook/backend/pas/pas-backend-summary.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * pas-backend-summary.h - * Copyright 2000, 2001, Ximian, Inc. - * - * Authors: - * Chris Toshok - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifndef __PAS_BACKEND_SUMMARY_H__ -#define __PAS_BACKEND_SUMMARY_H__ - -#include -#include -#include -#include - -#define PAS_TYPE_BACKEND_SUMMARY (pas_backend_summary_get_type ()) -#define PAS_BACKEND_SUMMARY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_SUMMARY, PASBackendSummary)) -#define PAS_BACKEND_SUMMARY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_BACKEND_TYPE, PASBackendSummaryClass)) -#define PAS_IS_BACKEND_SUMMARY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BACKEND_SUMMARY)) -#define PAS_IS_BACKEND_SUMMARY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BACKEND_SUMMARY)) -#define PAS_BACKEND_SUMMARY_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BACKEND_SUMMARY, PASBackendSummaryClass)) - -typedef struct _PASBackendSummaryPrivate PASBackendSummaryPrivate; - -struct _PASBackendSummary{ - GObject parent_object; - PASBackendSummaryPrivate *priv; -}; - -struct _PASBackendSummaryClass{ - GObjectClass parent_class; -}; - -PASBackendSummary* pas_backend_summary_new (const char *summary_path, - int flush_timeout_millis); -GType pas_backend_summary_get_type (void); - -/* returns FALSE if the load fails for any reason (including that the - summary is out of date), TRUE if it succeeds */ -gboolean pas_backend_summary_load (PASBackendSummary *summary); -/* returns FALSE if the save fails, TRUE if it succeeds (or isn't required due to no changes) */ -gboolean pas_backend_summary_save (PASBackendSummary *summary); - -void pas_backend_summary_add_contact (PASBackendSummary *summary, EContact *contact); -void pas_backend_summary_remove_contact (PASBackendSummary *summary, const char *id); - -void pas_backend_summary_touch (PASBackendSummary *summary); - -/* returns TRUE if the summary's mtime is >= @t. */ -gboolean pas_backend_summary_is_up_to_date (PASBackendSummary *summary, time_t t); - -gboolean pas_backend_summary_is_summary_query (PASBackendSummary *summary, const char *query); -GPtrArray* pas_backend_summary_search (PASBackendSummary *summary, const char *query); -char* pas_backend_summary_get_summary_vcard (PASBackendSummary *summary, const char *id); - -#endif /* __PAS_BACKEND_SUMMARY_H__ */ diff --git a/addressbook/backend/pas/pas-backend-sync.c b/addressbook/backend/pas/pas-backend-sync.c deleted file mode 100644 index 45063eddc6..0000000000 --- a/addressbook/backend/pas/pas-backend-sync.c +++ /dev/null @@ -1,395 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author: - * Chris Toshok (toshok@ximian.com) - * - * Copyright (C) 2003, Ximian, Inc. - */ - -#include -#include "pas-backend-sync.h" -#include "pas-marshal.h" - -struct _PASBackendSyncPrivate { - int mumble; -}; - -static GObjectClass *parent_class; - -gboolean -pas_backend_sync_construct (PASBackendSync *backend) -{ - return TRUE; -} - -PASBackendSyncStatus -pas_backend_sync_create_contact (PASBackendSync *backend, - PASBook *book, - const char *vcard, - EContact **contact) -{ - g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (vcard, GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (contact, GNOME_Evolution_Addressbook_OtherError); - - g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->create_contact_sync); - - return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->create_contact_sync) (backend, book, vcard, contact); -} - -PASBackendSyncStatus -pas_backend_sync_remove (PASBackendSync *backend, - PASBook *book) -{ - g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError); - - g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->remove_sync); - - return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->remove_sync) (backend, book); -} - -PASBackendSyncStatus -pas_backend_sync_remove_contacts (PASBackendSync *backend, - PASBook *book, - GList *id_list, - GList **removed_ids) -{ - g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (id_list, GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (removed_ids, GNOME_Evolution_Addressbook_OtherError); - - g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->remove_contacts_sync); - - return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->remove_contacts_sync) (backend, book, id_list, removed_ids); -} - -PASBackendSyncStatus -pas_backend_sync_modify_contact (PASBackendSync *backend, - PASBook *book, - const char *vcard, - EContact **contact) -{ - g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (vcard, GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (contact, GNOME_Evolution_Addressbook_OtherError); - - g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->modify_contact_sync); - - return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->modify_contact_sync) (backend, book, vcard, contact); -} - -PASBackendSyncStatus -pas_backend_sync_get_contact (PASBackendSync *backend, - PASBook *book, - const char *id, - char **vcard) -{ - g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (id, GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (vcard, GNOME_Evolution_Addressbook_OtherError); - - g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->get_contact_sync); - - return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->get_contact_sync) (backend, book, id, vcard); -} - -PASBackendSyncStatus -pas_backend_sync_get_contact_list (PASBackendSync *backend, - PASBook *book, - const char *query, - GList **contacts) -{ - g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (query, GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (contacts, GNOME_Evolution_Addressbook_OtherError); - - g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->get_contact_list_sync); - - return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->get_contact_list_sync) (backend, book, query, contacts); -} - -PASBackendSyncStatus -pas_backend_sync_get_changes (PASBackendSync *backend, - PASBook *book, - const char *change_id, - GList **changes) -{ - g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (change_id, GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (changes, GNOME_Evolution_Addressbook_OtherError); - - g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->get_changes_sync); - - return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->get_changes_sync) (backend, book, change_id, changes); -} - -PASBackendSyncStatus -pas_backend_sync_authenticate_user (PASBackendSync *backend, - PASBook *book, - const char *user, - const char *passwd, - const char *auth_method) -{ - g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (user && passwd && auth_method, GNOME_Evolution_Addressbook_OtherError); - - g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->authenticate_user_sync); - - return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->authenticate_user_sync) (backend, book, user, passwd, auth_method); -} - -PASBackendSyncStatus -pas_backend_sync_get_supported_fields (PASBackendSync *backend, - PASBook *book, - GList **fields) -{ - g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (fields, GNOME_Evolution_Addressbook_OtherError); - - g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->get_supported_fields_sync); - - return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->get_supported_fields_sync) (backend, book, fields); -} - -PASBackendSyncStatus -pas_backend_sync_get_supported_auth_methods (PASBackendSync *backend, - PASBook *book, - GList **methods) -{ - g_return_val_if_fail (backend && PAS_IS_BACKEND_SYNC (backend), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (methods, GNOME_Evolution_Addressbook_OtherError); - - g_assert (PAS_BACKEND_SYNC_GET_CLASS (backend)->get_supported_auth_methods_sync); - - return (* PAS_BACKEND_SYNC_GET_CLASS (backend)->get_supported_auth_methods_sync) (backend, book, methods); -} - -static void -_pas_backend_remove (PASBackend *backend, - PASBook *book) -{ - PASBackendSyncStatus status; - - status = pas_backend_sync_remove (PAS_BACKEND_SYNC (backend), book); - - pas_book_respond_remove (book, status); -} - -static void -_pas_backend_create_contact (PASBackend *backend, - PASBook *book, - const char *vcard) -{ - PASBackendSyncStatus status; - EContact *contact; - - status = pas_backend_sync_create_contact (PAS_BACKEND_SYNC (backend), book, vcard, &contact); - - pas_book_respond_create (book, status, contact); - - g_object_unref (contact); -} - -static void -_pas_backend_remove_contacts (PASBackend *backend, - PASBook *book, - GList *id_list) -{ - PASBackendSyncStatus status; - GList *ids = NULL; - - status = pas_backend_sync_remove_contacts (PAS_BACKEND_SYNC (backend), book, id_list, &ids); - - pas_book_respond_remove_contacts (book, status, ids); - - g_list_free (ids); -} - -static void -_pas_backend_modify_contact (PASBackend *backend, - PASBook *book, - const char *vcard) -{ - PASBackendSyncStatus status; - EContact *contact; - - status = pas_backend_sync_modify_contact (PAS_BACKEND_SYNC (backend), book, vcard, &contact); - - pas_book_respond_modify (book, status, contact); - - g_object_unref (contact); -} - -static void -_pas_backend_get_contact (PASBackend *backend, - PASBook *book, - const char *id) -{ - PASBackendSyncStatus status; - char *vcard; - - status = pas_backend_sync_get_contact (PAS_BACKEND_SYNC (backend), book, id, &vcard); - - pas_book_respond_get_contact (book, status, vcard); - - g_free (vcard); -} - -static void -_pas_backend_get_contact_list (PASBackend *backend, - PASBook *book, - const char *query) -{ - PASBackendSyncStatus status; - GList *cards = NULL; - - status = pas_backend_sync_get_contact_list (PAS_BACKEND_SYNC (backend), book, query, &cards); - - pas_book_respond_get_contact_list (book, status, cards); -} - -static void -_pas_backend_get_changes (PASBackend *backend, - PASBook *book, - const char *change_id) -{ - PASBackendSyncStatus status; - GList *changes = NULL; - - status = pas_backend_sync_get_changes (PAS_BACKEND_SYNC (backend), book, change_id, &changes); - - pas_book_respond_get_changes (book, status, changes); - - /* XXX free view? */ -} - -static void -_pas_backend_authenticate_user (PASBackend *backend, - PASBook *book, - const char *user, - const char *passwd, - const char *auth_method) -{ - PASBackendSyncStatus status; - - status = pas_backend_sync_authenticate_user (PAS_BACKEND_SYNC (backend), book, user, passwd, auth_method); - - pas_book_respond_authenticate_user (book, status); -} - -static void -_pas_backend_get_supported_fields (PASBackend *backend, - PASBook *book) -{ - PASBackendSyncStatus status; - GList *fields = NULL; - - status = pas_backend_sync_get_supported_fields (PAS_BACKEND_SYNC (backend), book, &fields); - - pas_book_respond_get_supported_fields (book, status, fields); - - g_list_foreach (fields, (GFunc)g_free, NULL); - g_list_free (fields); -} - -static void -_pas_backend_get_supported_auth_methods (PASBackend *backend, - PASBook *book) -{ - PASBackendSyncStatus status; - GList *methods = NULL; - - status = pas_backend_sync_get_supported_auth_methods (PAS_BACKEND_SYNC (backend), book, &methods); - - pas_book_respond_get_supported_auth_methods (book, status, methods); - - g_list_foreach (methods, (GFunc)g_free, NULL); - g_list_free (methods); -} - -static void -pas_backend_sync_init (PASBackendSync *backend) -{ - PASBackendSyncPrivate *priv; - - priv = g_new0 (PASBackendSyncPrivate, 1); - - backend->priv = priv; -} - -static void -pas_backend_sync_dispose (GObject *object) -{ - PASBackendSync *backend; - - backend = PAS_BACKEND_SYNC (object); - - if (backend->priv) { - g_free (backend->priv); - - backend->priv = NULL; - } - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -pas_backend_sync_class_init (PASBackendSyncClass *klass) -{ - GObjectClass *object_class; - PASBackendClass *backend_class = PAS_BACKEND_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class = (GObjectClass *) klass; - - backend_class->remove = _pas_backend_remove; - backend_class->create_contact = _pas_backend_create_contact; - backend_class->remove_contacts = _pas_backend_remove_contacts; - backend_class->modify_contact = _pas_backend_modify_contact; - backend_class->get_contact = _pas_backend_get_contact; - backend_class->get_contact_list = _pas_backend_get_contact_list; - backend_class->get_changes = _pas_backend_get_changes; - backend_class->authenticate_user = _pas_backend_authenticate_user; - backend_class->get_supported_fields = _pas_backend_get_supported_fields; - backend_class->get_supported_auth_methods = _pas_backend_get_supported_auth_methods; - - object_class->dispose = pas_backend_sync_dispose; -} - -/** - * pas_backend_get_type: - */ -GType -pas_backend_sync_get_type (void) -{ - static GType type = 0; - - if (! type) { - GTypeInfo info = { - sizeof (PASBackendSyncClass), - NULL, /* base_class_init */ - NULL, /* base_class_finalize */ - (GClassInitFunc) pas_backend_sync_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PASBackendSync), - 0, /* n_preallocs */ - (GInstanceInitFunc) pas_backend_sync_init - }; - - type = g_type_register_static (PAS_TYPE_BACKEND, "PASBackendSync", &info, 0); - } - - return type; -} diff --git a/addressbook/backend/pas/pas-backend-sync.h b/addressbook/backend/pas/pas-backend-sync.h deleted file mode 100644 index 2e176d9f5d..0000000000 --- a/addressbook/backend/pas/pas-backend-sync.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - */ - -#ifndef __PAS_BACKEND_SYNC_H__ -#define __PAS_BACKEND_SYNC_H__ - -#include -#include -#include -#include - -#define PAS_TYPE_BACKEND_SYNC (pas_backend_sync_get_type ()) -#define PAS_BACKEND_SYNC(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_SYNC, PASBackendSync)) -#define PAS_BACKEND_SYNC_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_TYPE_BACKEND_SYNC, PASBackendSyncClass)) -#define PAS_IS_BACKEND_SYNC(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BACKEND_SYNC)) -#define PAS_IS_BACKEND_SYNC_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BACKEND_SYNC)) -#define PAS_BACKEND_SYNC_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((k), PAS_TYPE_BACKEND_SYNC, PASBackendSyncClass)) - -typedef struct _PASBackendSyncPrivate PASBackendSyncPrivate; - -typedef GNOME_Evolution_Addressbook_CallStatus PASBackendSyncStatus; - -struct _PASBackendSync { - PASBackend parent_object; - PASBackendSyncPrivate *priv; -}; - -struct _PASBackendSyncClass { - PASBackendClass parent_class; - - /* Virtual methods */ - PASBackendSyncStatus (*remove_sync) (PASBackendSync *backend, PASBook *book); - PASBackendSyncStatus (*create_contact_sync) (PASBackendSync *backend, PASBook *book, - const char *vcard, EContact **contact); - PASBackendSyncStatus (*remove_contacts_sync) (PASBackendSync *backend, PASBook *book, - GList *id_list, GList **removed_ids); - PASBackendSyncStatus (*modify_contact_sync) (PASBackendSync *backend, PASBook *book, - const char *vcard, EContact **contact); - PASBackendSyncStatus (*get_contact_sync) (PASBackendSync *backend, PASBook *book, - const char *id, char **vcard); - PASBackendSyncStatus (*get_contact_list_sync) (PASBackendSync *backend, PASBook *book, - const char *query, GList **contacts); - PASBackendSyncStatus (*get_changes_sync) (PASBackendSync *backend, PASBook *book, - const char *change_id, GList **changes); - PASBackendSyncStatus (*authenticate_user_sync) (PASBackendSync *backend, PASBook *book, - const char *user, - const char *passwd, - const char *auth_method); - PASBackendSyncStatus (*get_supported_fields_sync) (PASBackendSync *backend, PASBook *book, - GList **fields); - PASBackendSyncStatus (*get_supported_auth_methods_sync) (PASBackendSync *backend, PASBook *book, - GList **methods); - - /* Padding for future expansion */ - void (*_pas_reserved0) (void); - void (*_pas_reserved1) (void); - void (*_pas_reserved2) (void); - void (*_pas_reserved3) (void); - void (*_pas_reserved4) (void); - -}; - -typedef PASBackendSync * (*PASBackendSyncFactoryFn) (void); - -gboolean pas_backend_sync_construct (PASBackendSync *backend); - -GType pas_backend_sync_get_type (void); - -PASBackendSyncStatus pas_backend_sync_remove (PASBackendSync *backend, PASBook *book); -PASBackendSyncStatus pas_backend_sync_create_contact (PASBackendSync *backend, PASBook *book, const char *vcard, EContact **contact); -PASBackendSyncStatus pas_backend_sync_remove_contacts (PASBackendSync *backend, PASBook *book, GList *id_list, GList **removed_ids); -PASBackendSyncStatus pas_backend_sync_modify_contact (PASBackendSync *backend, PASBook *book, const char *vcard, EContact **contact); -PASBackendSyncStatus pas_backend_sync_get_contact (PASBackendSync *backend, PASBook *book, const char *id, char **vcard); -PASBackendSyncStatus pas_backend_sync_get_contact_list (PASBackendSync *backend, PASBook *book, const char *query, GList **contacts); -PASBackendSyncStatus pas_backend_sync_get_changes (PASBackendSync *backend, PASBook *book, const char *change_id, GList **changes); -PASBackendSyncStatus pas_backend_sync_authenticate_user (PASBackendSync *backend, PASBook *book, const char *user, const char *passwd, const char *auth_method); -PASBackendSyncStatus pas_backend_sync_get_supported_fields (PASBackendSync *backend, PASBook *book, GList **fields); -PASBackendSyncStatus pas_backend_sync_get_supported_auth_methods (PASBackendSync *backend, PASBook *book, GList **methods); - -#endif /* ! __PAS_BACKEND_SYNC_H__ */ diff --git a/addressbook/backend/pas/pas-backend-vcf.c b/addressbook/backend/pas/pas-backend-vcf.c deleted file mode 100644 index e82fe04f56..0000000000 --- a/addressbook/backend/pas/pas-backend-vcf.c +++ /dev/null @@ -1,675 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author: - * Chris Toshok (toshok@ximian.com) - * - * Copyright (C) 2003, Ximian, Inc. - */ - -#include "config.h" -#include "pas-backend-vcf.h" -#include "pas-backend-card-sexp.h" -#include "pas-book.h" -#include "pas-book-view.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#define PAS_ID_PREFIX "pas-id-" -#define FILE_FLUSH_TIMEOUT 5000 - -static PASBackendSyncClass *pas_backend_vcf_parent_class; -typedef struct _PASBackendVCFBookView PASBackendVCFBookView; -typedef struct _PASBackendVCFSearchContext PASBackendVCFSearchContext; - -struct _PASBackendVCFPrivate { - char *uri; - char *filename; - GMutex *mutex; - GHashTable *contacts; - gboolean dirty; - int flush_timeout_tag; -}; - -static char * -pas_backend_vcf_create_unique_id () -{ - /* use a 32 counter and the 32 bit timestamp to make an id. - it's doubtful 2^32 id's will be created in a second, so we - should be okay. */ - static guint c = 0; - return g_strdup_printf (PAS_ID_PREFIX "%08lX%08X", time(NULL), c++); -} - -typedef struct { - PASBackendVCF *bvcf; - PASBook *book; - PASBookView *view; -} VCFBackendSearchClosure; - -static void -free_search_closure (VCFBackendSearchClosure *closure) -{ - g_free (closure); -} - -static void -foreach_search_compare (char *id, char *vcard_string, VCFBackendSearchClosure *closure) -{ - EContact *contact; - - contact = e_contact_new_from_vcard (vcard_string); - pas_book_view_notify_update (closure->view, contact); - g_object_unref (contact); -} - -static gboolean -pas_backend_vcf_search_timeout (gpointer data) -{ - VCFBackendSearchClosure *closure = data; - - g_hash_table_foreach (closure->bvcf->priv->contacts, - (GHFunc)foreach_search_compare, - closure); - - pas_book_view_notify_complete (closure->view, GNOME_Evolution_Addressbook_Success); - - free_search_closure (closure); - - return FALSE; -} - - -static void -pas_backend_vcf_search (PASBackendVCF *bvcf, - PASBookView *book_view) -{ - const char *query = pas_book_view_get_card_query (book_view); - VCFBackendSearchClosure *closure = g_new0 (VCFBackendSearchClosure, 1); - - 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...")); - - closure->view = book_view; - closure->bvcf = bvcf; - - g_idle_add (pas_backend_vcf_search_timeout, closure); -} - -static void -insert_contact (PASBackendVCF *vcf, char *vcard) -{ - EContact *contact = e_contact_new_from_vcard (vcard); - char *id; - - id = e_contact_get (contact, E_CONTACT_UID); - if (id) - g_hash_table_insert (vcf->priv->contacts, - id, - e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30)); -} - -static void -load_file (PASBackendVCF *vcf, int fd) -{ - FILE *fp; - GString *str; - char buf[1024]; - - fp = fdopen (fd, "r"); - if (!fp) { - g_warning ("failed to open `%s' for reading", vcf->priv->filename); - return; - } - - str = g_string_new (""); - - while (fgets (buf, sizeof (buf), fp)) { - if (!strcmp (buf, "\r\n")) { - /* if the string has accumulated some stuff, create a contact for it and start over */ - if (str->len) { - insert_contact (vcf, str->str); - g_string_assign (str, ""); - } - } - else { - g_string_append (str, buf); - } - } - if (str->len) { - insert_contact (vcf, str->str); - } - - g_string_free (str, TRUE); - - fclose (fp); -} - -static void -foreach_build_list (char *id, char *vcard_string, GList **list) -{ - *list = g_list_append (*list, vcard_string); -} - -static gboolean -save_file (PASBackendVCF *vcf) -{ - GList *vcards = NULL; - GList *l; - char *new_path; - int fd, rv; - - 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 = vcards; l; l = l->next) { - char *vcard_str = l->data; - int len = strlen (vcard_str); - - rv = write (fd, vcard_str, len); - - if (rv < len) { - /* XXX */ - g_warning ("write failed. we need to handle short writes\n"); - close (fd); - unlink (new_path); - return FALSE; - } - - 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); - unlink (new_path); - return FALSE; - } - } - - if (0 > rename (new_path, vcf->priv->filename)) { - g_warning ("Failed to rename %s: %s\n", vcf->priv->filename, strerror(errno)); - unlink (new_path); - return FALSE; - } - - g_list_free (vcards); - g_free (new_path); - - vcf->priv->dirty = FALSE; - - g_mutex_unlock (vcf->priv->mutex); - - return TRUE; -} - -static gboolean -vcf_flush_file (gpointer data) -{ - PASBackendVCF *bvcf = PAS_BACKEND_VCF (data); - - if (!bvcf->priv->dirty) { - bvcf->priv->flush_timeout_tag = 0; - return FALSE; - } - - if (!save_file (bvcf)) { - g_warning ("failed to flush the .vcf file to disk, will try again next timeout"); - return TRUE; - } - - bvcf->priv->flush_timeout_tag = 0; - return FALSE; -} - -static EContact * -do_create(PASBackendVCF *bvcf, - const char *vcard_req, - gboolean dirty_the_file) -{ - char *id; - 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); - e_contact_set(contact, E_CONTACT_UID, id); - vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); - - g_hash_table_insert (bvcf->priv->contacts, id, vcard); - - if (dirty_the_file) { - 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); - - return contact; -} - -static PASBackendSyncStatus -pas_backend_vcf_process_create_contact (PASBackendSync *backend, - PASBook *book, - const char *vcard, - EContact **contact) -{ - PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend); - - *contact = do_create(bvcf, vcard, TRUE); - if (*contact) { - return GNOME_Evolution_Addressbook_Success; - } - else { - /* XXX need a different call status for this case, i - think */ - return GNOME_Evolution_Addressbook_ContactNotFound; - } -} - -static PASBackendSyncStatus -pas_backend_vcf_process_remove_contacts (PASBackendSync *backend, - PASBook *book, - GList *id_list, - GList **ids) -{ - /* 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 (!success) { - g_mutex_unlock (bvcf->priv->mutex); - return GNOME_Evolution_Addressbook_ContactNotFound; - } - else { - 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); - - *ids = g_list_append (*ids, id); - - return GNOME_Evolution_Addressbook_Success; - } -} - -static PASBackendSyncStatus -pas_backend_vcf_process_modify_contact (PASBackendSync *backend, - PASBook *book, - const char *vcard, - EContact **contact) -{ - 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); - - 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); - - return GNOME_Evolution_Addressbook_Success; - } -} - -static PASBackendSyncStatus -pas_backend_vcf_process_get_contact (PASBackendSync *backend, - PASBook *book, - const char *id, - char **vcard) -{ - PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend); - char *v; - - v = g_hash_table_lookup (bvcf->priv->contacts, id); - - if (v) { - *vcard = g_strdup (v); - return GNOME_Evolution_Addressbook_Success; - } else { - *vcard = g_strdup (""); - return GNOME_Evolution_Addressbook_ContactNotFound; - } -} - - -typedef struct { - PASBackendVCF *bvcf; - gboolean search_needed; - PASBackendCardSExp *card_sexp; - GList *list; -} GetContactListClosure; - -static void -foreach_get_contact_compare (char *id, char *vcard_string, GetContactListClosure *closure) -{ - if ((!closure->search_needed) || pas_backend_card_sexp_match_vcard (closure->card_sexp, vcard_string)) { - closure->list = g_list_append (closure->list, g_strdup (vcard_string)); - } -} - -static PASBackendSyncStatus -pas_backend_vcf_process_get_contact_list (PASBackendSync *backend, - PASBook *book, - const char *query, - GList **contacts) -{ - PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend); - const char *search = query; - GetContactListClosure closure; - - closure.bvcf = bvcf; - closure.search_needed = strcmp (search, "(contains \"x-evolution-any-field\" \"\")"); - closure.card_sexp = pas_backend_card_sexp_new (search); - closure.list = NULL; - - g_hash_table_foreach (bvcf->priv->contacts, (GHFunc)foreach_get_contact_compare, &closure); - - g_object_unref (closure.card_sexp); - - *contacts = closure.list; - return GNOME_Evolution_Addressbook_Success; -} - -static void -pas_backend_vcf_start_book_view (PASBackend *backend, - PASBookView *book_view) -{ - 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) -{ - g_assert (strncasecmp (uri, "vcf://", 6) == 0); - - return g_strdup (uri + 6); -} - -static PASBackendSyncStatus -pas_backend_vcf_process_authenticate_user (PASBackendSync *backend, - PASBook *book, - const char *user, - const char *passwd, - const char *auth_method) -{ - return GNOME_Evolution_Addressbook_Success; -} - -static PASBackendSyncStatus -pas_backend_vcf_process_get_supported_fields (PASBackendSync *backend, - PASBook *book, - GList **fields_out) -{ - GList *fields = NULL; - int i; - - /* XXX we need a way to say "we support everything", since the - vcf backend does */ - for (i = 0; i < E_CONTACT_FIELD_LAST; i ++) - fields = g_list_append (fields, (char*)e_contact_field_name (i)); - - *fields_out = fields; - return GNOME_Evolution_Addressbook_Success; -} - -#include "ximian-vcard.h" - -static GNOME_Evolution_Addressbook_CallStatus -pas_backend_vcf_load_uri (PASBackend *backend, - const char *uri, - gboolean only_if_exists) -{ - PASBackendVCF *bvcf = PAS_BACKEND_VCF (backend); - char *dirname; - gboolean writable = FALSE; - int fd; - - g_free(bvcf->priv->uri); - bvcf->priv->uri = g_strdup (uri); - - dirname = pas_backend_vcf_extract_path_from_uri (uri); - bvcf->priv->filename = g_build_filename (dirname, "addressbook.vcf", NULL); - - 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); - - if (fd != -1) { - writable = TRUE; - } else { - fd = open (bvcf->priv->filename, O_RDONLY); - - if (fd == -1) { - fd = open (bvcf->priv->filename, O_CREAT, 0666); - - if (fd != -1 && !only_if_exists) { - EContact *contact; - - contact = do_create(bvcf, XIMIAN_VCARD, FALSE); - save_file (bvcf); - - /* XXX check errors here */ - g_object_unref (contact); - - writable = TRUE; - } - } - } - - if (fd == -1) { - g_warning ("Failed to open addressbook at uri `%s'", uri); - g_warning ("error == %s", strerror(errno)); - return GNOME_Evolution_Addressbook_OtherError; - } - - load_file (bvcf, fd); - - pas_backend_set_is_loaded (backend, TRUE); - pas_backend_set_is_writable (backend, writable); - - return GNOME_Evolution_Addressbook_Success; -} - -static char * -pas_backend_vcf_get_static_capabilities (PASBackend *backend) -{ - return g_strdup("local,do-initial-query"); -} - -static GNOME_Evolution_Addressbook_CallStatus -pas_backend_vcf_cancel_operation (PASBackend *backend, PASBook *book) -{ - return GNOME_Evolution_Addressbook_CouldNotCancel; -} - -static gboolean -pas_backend_vcf_construct (PASBackendVCF *backend) -{ - g_assert (backend != NULL); - g_assert (PAS_IS_BACKEND_VCF (backend)); - - if (! pas_backend_construct (PAS_BACKEND (backend))) - return FALSE; - - return TRUE; -} - -/** - * pas_backend_vcf_new: - */ -PASBackend * -pas_backend_vcf_new (void) -{ - PASBackendVCF *backend; - - backend = g_object_new (PAS_TYPE_BACKEND_VCF, NULL); - - if (! pas_backend_vcf_construct (backend)) { - g_object_unref (backend); - - return NULL; - } - - return PAS_BACKEND (backend); -} - -static void -pas_backend_vcf_dispose (GObject *object) -{ - PASBackendVCF *bvcf; - - bvcf = PAS_BACKEND_VCF (object); - - if (bvcf->priv) { - - 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; - } - - G_OBJECT_CLASS (pas_backend_vcf_parent_class)->dispose (object); -} - -static void -pas_backend_vcf_class_init (PASBackendVCFClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - PASBackendSyncClass *sync_class; - PASBackendClass *backend_class; - - pas_backend_vcf_parent_class = g_type_class_peek_parent (klass); - - sync_class = PAS_BACKEND_SYNC_CLASS (klass); - backend_class = PAS_BACKEND_CLASS (klass); - - /* Set the virtual methods. */ - 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; - sync_class->remove_contacts_sync = pas_backend_vcf_process_remove_contacts; - sync_class->modify_contact_sync = pas_backend_vcf_process_modify_contact; - sync_class->get_contact_sync = pas_backend_vcf_process_get_contact; - sync_class->get_contact_list_sync = pas_backend_vcf_process_get_contact_list; - sync_class->authenticate_user_sync = pas_backend_vcf_process_authenticate_user; - sync_class->get_supported_fields_sync = pas_backend_vcf_process_get_supported_fields; - - object_class->dispose = pas_backend_vcf_dispose; -} - -static void -pas_backend_vcf_init (PASBackendVCF *backend) -{ - PASBackendVCFPrivate *priv; - - priv = g_new0 (PASBackendVCFPrivate, 1); - priv->uri = NULL; - priv->mutex = g_mutex_new(); - - backend->priv = priv; -} - -/** - * pas_backend_vcf_get_type: - */ -GType -pas_backend_vcf_get_type (void) -{ - static GType type = 0; - - if (! type) { - GTypeInfo info = { - sizeof (PASBackendVCFClass), - NULL, /* base_class_init */ - NULL, /* base_class_finalize */ - (GClassInitFunc) pas_backend_vcf_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PASBackendVCF), - 0, /* n_preallocs */ - (GInstanceInitFunc) pas_backend_vcf_init - }; - - type = g_type_register_static (PAS_TYPE_BACKEND_SYNC, "PASBackendVCF", &info, 0); - } - - return type; -} diff --git a/addressbook/backend/pas/pas-backend-vcf.h b/addressbook/backend/pas/pas-backend-vcf.h deleted file mode 100644 index 81c872dcf1..0000000000 --- a/addressbook/backend/pas/pas-backend-vcf.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author: - * Chris Toshok (toshok@ximian.com) - * Copyright (C) 2003, Ximian, Inc. - */ - -#ifndef __PAS_BACKEND_VCF_H__ -#define __PAS_BACKEND_VCF_H__ - -#include "pas-backend-sync.h" - -#define PAS_TYPE_BACKEND_VCF (pas_backend_vcf_get_type ()) -#define PAS_BACKEND_VCF(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND_VCF, PASBackendVCF)) -#define PAS_BACKEND_VCF_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_BACKEND_TYPE, PASBackendVCFClass)) -#define PAS_IS_BACKEND_VCF(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BACKEND_VCF)) -#define PAS_IS_BACKEND_VCF_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BACKEND_VCF)) -#define PAS_BACKEND_VCF_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BACKEND_VCF, PASBackendVCFClass)) - -typedef struct _PASBackendVCFPrivate PASBackendVCFPrivate; - -typedef struct { - PASBackendSync parent_object; - PASBackendVCFPrivate *priv; -} PASBackendVCF; - -typedef struct { - PASBackendSyncClass parent_class; -} PASBackendVCFClass; - -PASBackend *pas_backend_vcf_new (void); -GType pas_backend_vcf_get_type (void); - -#endif /* ! __PAS_BACKEND_VCF_H__ */ - diff --git a/addressbook/backend/pas/pas-backend.c b/addressbook/backend/pas/pas-backend.c deleted file mode 100644 index a447d64851..0000000000 --- a/addressbook/backend/pas/pas-backend.c +++ /dev/null @@ -1,671 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#include -#include -#include "pas-book-view.h" -#include "pas-backend.h" -#include "pas-marshal.h" - -struct _PASBackendPrivate { - GMutex *open_mutex; - - GMutex *clients_mutex; - GList *clients; - - char *uri; - gboolean loaded, writable, removed; - - GMutex *views_mutex; - EList *views; -}; - -/* Signal IDs */ -enum { - LAST_CLIENT_GONE, - LAST_SIGNAL -}; - -static guint pas_backend_signals[LAST_SIGNAL]; - -static GObjectClass *parent_class; - -gboolean -pas_backend_construct (PASBackend *backend) -{ - return TRUE; -} - -GNOME_Evolution_Addressbook_CallStatus -pas_backend_load_uri (PASBackend *backend, - const char *uri, - gboolean only_if_exists) -{ - GNOME_Evolution_Addressbook_CallStatus status; - - g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), FALSE); - g_return_val_if_fail (uri, FALSE); - g_return_val_if_fail (backend->priv->loaded == FALSE, FALSE); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->load_uri); - - status = (* PAS_BACKEND_GET_CLASS (backend)->load_uri) (backend, uri, only_if_exists); - - if (status == GNOME_Evolution_Addressbook_Success) - backend->priv->uri = g_strdup (uri); - - return status; -} - -/** - * pas_backend_get_uri: - * @backend: An addressbook backend. - * - * Queries the URI that an addressbook backend is serving. - * - * Return value: URI for the backend. - **/ -const char * -pas_backend_get_uri (PASBackend *backend) -{ - g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), NULL); - - return backend->priv->uri; -} - -void -pas_backend_open (PASBackend *backend, - PASBook *book, - gboolean only_if_exists) -{ - g_return_if_fail (backend && PAS_IS_BACKEND (backend)); - g_return_if_fail (book && PAS_IS_BOOK (book)); - - g_mutex_lock (backend->priv->open_mutex); - - if (backend->priv->loaded) { - pas_book_respond_open ( - book, GNOME_Evolution_Addressbook_Success); - - pas_book_report_writable (book, backend->priv->writable); - } else { - GNOME_Evolution_Addressbook_CallStatus status = - pas_backend_load_uri (backend, pas_book_get_uri (book), only_if_exists); - - pas_book_respond_open (book, status); - - if (status == GNOME_Evolution_Addressbook_Success) - pas_book_report_writable (book, backend->priv->writable); - } - - g_mutex_unlock (backend->priv->open_mutex); -} - -void -pas_backend_remove (PASBackend *backend, - PASBook *book) -{ - g_return_if_fail (backend && PAS_IS_BACKEND (backend)); - g_return_if_fail (book && PAS_IS_BOOK (book)); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->remove); - - (* PAS_BACKEND_GET_CLASS (backend)->remove) (backend, book); -} - -void -pas_backend_create_contact (PASBackend *backend, - PASBook *book, - const char *vcard) -{ - g_return_if_fail (backend && PAS_IS_BACKEND (backend)); - g_return_if_fail (book && PAS_IS_BOOK (book)); - g_return_if_fail (vcard); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->create_contact); - - (* PAS_BACKEND_GET_CLASS (backend)->create_contact) (backend, book, vcard); -} - -void -pas_backend_remove_contacts (PASBackend *backend, - PASBook *book, - GList *id_list) -{ - g_return_if_fail (backend && PAS_IS_BACKEND (backend)); - g_return_if_fail (book && PAS_IS_BOOK (book)); - g_return_if_fail (id_list); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->remove_contacts); - - (* PAS_BACKEND_GET_CLASS (backend)->remove_contacts) (backend, book, id_list); -} - -void -pas_backend_modify_contact (PASBackend *backend, - PASBook *book, - const char *vcard) -{ - g_return_if_fail (backend && PAS_IS_BACKEND (backend)); - g_return_if_fail (book && PAS_IS_BOOK (book)); - g_return_if_fail (vcard); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->modify_contact); - - (* PAS_BACKEND_GET_CLASS (backend)->modify_contact) (backend, book, vcard); -} - -void -pas_backend_get_contact (PASBackend *backend, - PASBook *book, - const char *id) -{ - g_return_if_fail (backend && PAS_IS_BACKEND (backend)); - g_return_if_fail (book && PAS_IS_BOOK (book)); - g_return_if_fail (id); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->get_contact); - - (* PAS_BACKEND_GET_CLASS (backend)->get_contact) (backend, book, id); -} - -void -pas_backend_get_contact_list (PASBackend *backend, - PASBook *book, - const char *query) -{ - g_return_if_fail (backend && PAS_IS_BACKEND (backend)); - g_return_if_fail (book && PAS_IS_BOOK (book)); - g_return_if_fail (query); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->get_contact_list); - - (* PAS_BACKEND_GET_CLASS (backend)->get_contact_list) (backend, book, query); -} - -void -pas_backend_start_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)->start_book_view); - - (* PAS_BACKEND_GET_CLASS (backend)->start_book_view) (backend, book_view); -} - -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) -{ - g_return_if_fail (backend && PAS_IS_BACKEND (backend)); - g_return_if_fail (book && PAS_IS_BOOK (book)); - g_return_if_fail (change_id); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->get_changes); - - (* PAS_BACKEND_GET_CLASS (backend)->get_changes) (backend, book, change_id); -} - -void -pas_backend_authenticate_user (PASBackend *backend, - PASBook *book, - const char *user, - const char *passwd, - const char *auth_method) -{ - g_return_if_fail (backend && PAS_IS_BACKEND (backend)); - g_return_if_fail (book && PAS_IS_BOOK (book)); - g_return_if_fail (user && passwd && auth_method); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->authenticate_user); - - (* PAS_BACKEND_GET_CLASS (backend)->authenticate_user) (backend, book, user, passwd, auth_method); -} - -void -pas_backend_get_supported_fields (PASBackend *backend, - PASBook *book) - -{ - g_return_if_fail (backend && PAS_IS_BACKEND (backend)); - g_return_if_fail (book && PAS_IS_BOOK (book)); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->get_supported_fields); - - (* PAS_BACKEND_GET_CLASS (backend)->get_supported_fields) (backend, book); -} - -void -pas_backend_get_supported_auth_methods (PASBackend *backend, - PASBook *book) -{ - g_return_if_fail (backend && PAS_IS_BACKEND (backend)); - g_return_if_fail (book && PAS_IS_BOOK (book)); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->get_supported_auth_methods); - - (* PAS_BACKEND_GET_CLASS (backend)->get_supported_auth_methods) (backend, book); -} - -GNOME_Evolution_Addressbook_CallStatus -pas_backend_cancel_operation (PASBackend *backend, - PASBook *book) -{ - g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), GNOME_Evolution_Addressbook_OtherError); - g_return_val_if_fail (book && PAS_IS_BOOK (book), GNOME_Evolution_Addressbook_OtherError); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->cancel_operation); - - return (* PAS_BACKEND_GET_CLASS (backend)->cancel_operation) (backend, book); -} - -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 -listener_died_cb (gpointer cnx, gpointer user_data) -{ - PASBook *book = PAS_BOOK (user_data); - - pas_backend_remove_client (pas_book_get_backend (book), book); -} - -static void -last_client_gone (PASBackend *backend) -{ - g_signal_emit (backend, pas_backend_signals[LAST_CLIENT_GONE], 0); -} - -EList* -pas_backend_get_book_views (PASBackend *backend) -{ - g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), FALSE); - - return g_object_ref (backend->priv->views); -} - -void -pas_backend_add_book_view (PASBackend *backend, - PASBookView *view) -{ - g_mutex_lock (backend->priv->views_mutex); - - e_list_append (backend->priv->views, view); - - 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. - * @book: the corba object representing the client connection. - * - * Adds a client to an addressbook backend. - * - * Return value: TRUE on success, FALSE on failure to add the client. - */ -gboolean -pas_backend_add_client (PASBackend *backend, - PASBook *book) -{ - g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), FALSE); - g_return_val_if_fail (book && PAS_IS_BOOK (book), FALSE); - - bonobo_object_set_immortal (BONOBO_OBJECT (book), TRUE); - - g_object_weak_ref (G_OBJECT (book), book_destroy_cb, backend); - - ORBit_small_listen_for_broken (pas_book_get_listener (book), G_CALLBACK (listener_died_cb), book); - - g_mutex_lock (backend->priv->clients_mutex); - backend->priv->clients = g_list_prepend (backend->priv->clients, book); - g_mutex_unlock (backend->priv->clients_mutex); - - return TRUE; -} - -void -pas_backend_remove_client (PASBackend *backend, - PASBook *book) -{ - /* XXX this needs a bit more thinking wrt the mutex - we - should be holding it when we check to see if clients is - NULL */ - - g_return_if_fail (backend && PAS_IS_BACKEND (backend)); - g_return_if_fail (book && PAS_IS_BOOK (book)); - - /* Disconnect */ - g_mutex_lock (backend->priv->clients_mutex); - backend->priv->clients = g_list_remove (backend->priv->clients, book); - g_mutex_unlock (backend->priv->clients_mutex); - - /* 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); -} - -char * -pas_backend_get_static_capabilities (PASBackend *backend) -{ - g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), NULL); - - g_assert (PAS_BACKEND_GET_CLASS (backend)->get_static_capabilities); - - return PAS_BACKEND_GET_CLASS (backend)->get_static_capabilities (backend); -} - -gboolean -pas_backend_is_loaded (PASBackend *backend) -{ - g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), FALSE); - - return backend->priv->loaded; -} - -void -pas_backend_set_is_loaded (PASBackend *backend, gboolean is_loaded) -{ - g_return_if_fail (backend && PAS_IS_BACKEND (backend)); - - backend->priv->loaded = is_loaded; -} - -gboolean -pas_backend_is_writable (PASBackend *backend) -{ - g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), FALSE); - - return backend->priv->writable; -} - -void -pas_backend_set_is_writable (PASBackend *backend, gboolean is_writable) -{ - g_return_if_fail (backend && PAS_IS_BACKEND (backend)); - - backend->priv->writable = is_writable; -} - -gboolean -pas_backend_is_removed (PASBackend *backend) -{ - g_return_val_if_fail (backend && PAS_IS_BACKEND (backend), FALSE); - - return backend->priv->removed; -} - -void -pas_backend_set_is_removed (PASBackend *backend, gboolean is_removed) -{ - g_return_if_fail (backend && PAS_IS_BACKEND (backend)); - - backend->priv->removed = is_removed; -} - - - -GNOME_Evolution_Addressbook_BookChangeItem* -pas_backend_change_add_new (const char *vcard) -{ - GNOME_Evolution_Addressbook_BookChangeItem* new_change = GNOME_Evolution_Addressbook_BookChangeItem__alloc(); - - new_change->changeType= GNOME_Evolution_Addressbook_ContactAdded; - new_change->vcard = CORBA_string_dup (vcard); - - return new_change; -} - -GNOME_Evolution_Addressbook_BookChangeItem* -pas_backend_change_modify_new (const char *vcard) -{ - GNOME_Evolution_Addressbook_BookChangeItem* new_change = GNOME_Evolution_Addressbook_BookChangeItem__alloc(); - - new_change->changeType= GNOME_Evolution_Addressbook_ContactModified; - new_change->vcard = CORBA_string_dup (vcard); - - return new_change; -} - -GNOME_Evolution_Addressbook_BookChangeItem* -pas_backend_change_delete_new (const char *vcard) -{ - GNOME_Evolution_Addressbook_BookChangeItem* new_change = GNOME_Evolution_Addressbook_BookChangeItem__alloc(); - - new_change->changeType= GNOME_Evolution_Addressbook_ContactDeleted; - new_change->vcard = CORBA_string_dup (vcard); - - return new_change; -} - - - -static void -pas_backend_foreach_view (PASBackend *backend, - void (*callback) (PASBookView *, gpointer), - gpointer user_data) -{ - EList *views; - PASBookView *view; - EIterator *iter; - - views = pas_backend_get_book_views (backend); - iter = e_list_get_iterator (views); - - while (e_iterator_is_valid (iter)) { - view = (PASBookView*)e_iterator_get (iter); - - bonobo_object_ref (view); - callback (view, user_data); - bonobo_object_unref (view); - - e_iterator_next (iter); - } - - g_object_unref (iter); - g_object_unref (views); -} - - -static void -view_notify_update (PASBookView *view, gpointer contact) -{ - pas_book_view_notify_update (view, contact); -} - -/** - * pas_backend_notify_update: - * @backend: an addressbook backend - * @contact: a new or modified contact - * - * Notifies all of @backend's book views about the new or modified - * contacts @contact. - * - * pas_book_respond_create() and pas_book_respond_modify() call this - * function for you. You only need to call this from your backend if - * contacts are created or modified by another (non-PAS-using) client. - **/ -void -pas_backend_notify_update (PASBackend *backend, EContact *contact) -{ - pas_backend_foreach_view (backend, view_notify_update, contact); -} - - -static void -view_notify_remove (PASBookView *view, gpointer id) -{ - pas_book_view_notify_remove (view, id); -} - -/** - * pas_backend_notify_remove: - * @backend: an addressbook backend - * @id: a contact id - * - * Notifies all of @backend's book views that the contact with UID - * @id has been removed. - * - * pas_book_respond_remove_contacts() calls this function for you. You - * only need to call this from your backend if contacts are removed by - * another (non-PAS-using) client. - **/ -void -pas_backend_notify_remove (PASBackend *backend, const char *id) -{ - pas_backend_foreach_view (backend, view_notify_remove, (gpointer)id); -} - - -static void -view_notify_complete (PASBookView *view, gpointer unused) -{ - pas_book_view_notify_complete (view, GNOME_Evolution_Addressbook_Success); -} - -/** - * pas_backend_notify_complete: - * @backend: an addressbook backend - * - * Notifies all of @backend's book views that the current set of - * notifications is complete; use this after a series of - * pas_backend_notify_update() and pas_backend_notify_remove() calls. - **/ -void -pas_backend_notify_complete (PASBackend *backend) -{ - pas_backend_foreach_view (backend, view_notify_complete, NULL); -} - - - -static void -pas_backend_init (PASBackend *backend) -{ - PASBackendPrivate *priv; - - priv = g_new0 (PASBackendPrivate, 1); - priv->uri = NULL; - priv->clients = NULL; - priv->views = e_list_new((EListCopyFunc) g_object_ref, (EListFreeFunc) g_object_unref, NULL); - priv->open_mutex = g_mutex_new (); - priv->clients_mutex = g_mutex_new (); - priv->views_mutex = g_mutex_new (); - - 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); - - if (backend->priv->uri) - g_free (backend->priv->uri); - - if (backend->priv->views) { - g_object_unref (backend->priv->views); - backend->priv->views = NULL; - } - - g_mutex_free (backend->priv->open_mutex); - g_mutex_free (backend->priv->clients_mutex); - g_mutex_free (backend->priv->views_mutex); - - g_free (backend->priv); - backend->priv = NULL; - } - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -pas_backend_class_init (PASBackendClass *klass) -{ - GObjectClass *object_class; - - parent_class = g_type_class_peek_parent (klass); - - object_class = (GObjectClass *) klass; - - object_class->dispose = pas_backend_dispose; - - pas_backend_signals[LAST_CLIENT_GONE] = - g_signal_new ("last_client_gone", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (PASBackendClass, last_client_gone), - NULL, NULL, - pas_marshal_NONE__NONE, - G_TYPE_NONE, 0); -} - -/** - * pas_backend_get_type: - */ -GType -pas_backend_get_type (void) -{ - static GType type = 0; - - if (! type) { - GTypeInfo info = { - sizeof (PASBackendClass), - NULL, /* base_class_init */ - NULL, /* base_class_finalize */ - (GClassInitFunc) pas_backend_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (PASBackend), - 0, /* n_preallocs */ - (GInstanceInitFunc) pas_backend_init - }; - - type = g_type_register_static (G_TYPE_OBJECT, "PASBackend", &info, 0); - } - - return type; -} diff --git a/addressbook/backend/pas/pas-backend.h b/addressbook/backend/pas/pas-backend.h deleted file mode 100644 index b71d438441..0000000000 --- a/addressbook/backend/pas/pas-backend.h +++ /dev/null @@ -1,173 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * An abstract class which defines the API to a given backend. - * There will be one PASBackend object for every URI which is loaded. - * - * Two people will call into the PASBackend API: - * - * 1. The PASBookFactory, when it has been asked to load a book. - * It will create a new PASBackend if one is not already running - * for the requested URI. It will call pas_backend_add_client to - * add a new client to an existing PASBackend server. - * - * 2. A PASBook, when a client has requested an operation on the - * GNOME_Evolution_Addressbook_Book interface. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#ifndef __PAS_BACKEND_H__ -#define __PAS_BACKEND_H__ - -#include -#include -#include -#include -#include - -#define PAS_TYPE_BACKEND (pas_backend_get_type ()) -#define PAS_BACKEND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BACKEND, PASBackend)) -#define PAS_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_TYPE_BACKEND, PASBackendClass)) -#define PAS_IS_BACKEND(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BACKEND)) -#define PAS_IS_BACKEND_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BACKEND)) -#define PAS_BACKEND_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((k), PAS_TYPE_BACKEND, PASBackendClass)) - -typedef struct _PASBackendPrivate PASBackendPrivate; - -#include - -struct _PASBackend { - GObject parent_object; - PASBackendPrivate *priv; -}; - -struct _PASBackendClass { - GObjectClass parent_class; - - /* Virtual methods */ - GNOME_Evolution_Addressbook_CallStatus (*load_uri) (PASBackend *backend, const char *uri, gboolean only_if_exists); - void (*remove) (PASBackend *backend, PASBook *book); - char *(*get_static_capabilities) (PASBackend *backend); - - void (*create_contact) (PASBackend *backend, PASBook *book, const char *vcard); - void (*remove_contacts) (PASBackend *backend, PASBook *book, GList *id_list); - void (*modify_contact) (PASBackend *backend, PASBook *book, const char *vcard); - 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); - void (*get_supported_auth_methods) (PASBackend *backend, PASBook *book); - GNOME_Evolution_Addressbook_CallStatus (*cancel_operation) (PASBackend *backend, PASBook *book); - - /* Notification signals */ - void (* last_client_gone) (PASBackend *backend); - - /* Padding for future expansion */ - void (*_pas_reserved0) (void); - void (*_pas_reserved1) (void); - void (*_pas_reserved2) (void); - void (*_pas_reserved3) (void); - void (*_pas_reserved4) (void); -}; - -typedef PASBackend * (*PASBackendFactoryFn) (void); - -gboolean pas_backend_construct (PASBackend *backend); - -GNOME_Evolution_Addressbook_CallStatus - pas_backend_load_uri (PASBackend *backend, - const char *uri, - gboolean only_if_exists); -const char *pas_backend_get_uri (PASBackend *backend); - -gboolean pas_backend_add_client (PASBackend *backend, - PASBook *book); -void pas_backend_remove_client (PASBackend *backend, - PASBook *book); -char *pas_backend_get_static_capabilities (PASBackend *backend); - -gboolean pas_backend_is_loaded (PASBackend *backend); - -gboolean pas_backend_is_writable (PASBackend *backend); - -gboolean pas_backend_is_removed (PASBackend *backend); - -void pas_backend_open (PASBackend *backend, - PASBook *book, - gboolean only_if_exists); -void pas_backend_remove (PASBackend *backend, - PASBook *book); -void pas_backend_create_contact (PASBackend *backend, - PASBook *book, - const char *vcard); -void pas_backend_remove_contacts (PASBackend *backend, - PASBook *book, - GList *id_list); -void pas_backend_modify_contact (PASBackend *backend, - PASBook *book, - const char *vcard); -void pas_backend_get_contact (PASBackend *backend, - PASBook *book, - const char *id); -void pas_backend_get_contact_list (PASBackend *backend, - PASBook *book, - const char *query); -void pas_backend_get_changes (PASBackend *backend, - PASBook *book, - const char *change_id); -void pas_backend_authenticate_user (PASBackend *backend, - PASBook *book, - const char *user, - const char *passwd, - const char *auth_method); -void pas_backend_get_supported_fields (PASBackend *backend, - PASBook *book); -void pas_backend_get_supported_auth_methods (PASBackend *backend, - PASBook *book); -GNOME_Evolution_Addressbook_CallStatus pas_backend_cancel_operation (PASBackend *backend, - PASBook *book); - -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, - EContact *contact); -void pas_backend_notify_remove (PASBackend *backend, - const char *id); -void pas_backend_notify_complete (PASBackend *backend); - - -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); -void pas_backend_set_is_removed (PASBackend *backend, - gboolean is_removed); - -/* useful for implementing _get_changes in backends */ -GNOME_Evolution_Addressbook_BookChangeItem* pas_backend_change_add_new (const char *vcard); -GNOME_Evolution_Addressbook_BookChangeItem* pas_backend_change_modify_new (const char *vcard); -GNOME_Evolution_Addressbook_BookChangeItem* pas_backend_change_delete_new (const char *id); - -#endif /* ! __PAS_BACKEND_H__ */ - diff --git a/addressbook/backend/pas/pas-book-factory.c b/addressbook/backend/pas/pas-book-factory.c deleted file mode 100644 index 34e97aa780..0000000000 --- a/addressbook/backend/pas/pas-book-factory.c +++ /dev/null @@ -1,471 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#include -#include -#include - -#include "addressbook.h" -#include "pas-book-factory.h" -#include "pas-marshal.h" -#include -#include -#include - -#define DEFAULT_PAS_BOOK_FACTORY_OAF_ID "OAFIID:GNOME_Evolution_Wombat_ServerFactory" - -static BonoboObjectClass *pas_book_factory_parent_class; - -typedef struct { - char *uri; - GNOME_Evolution_Addressbook_BookListener listener; -} PASBookFactoryQueuedRequest; - -struct _PASBookFactoryPrivate { - GMutex *map_mutex; - - GHashTable *backends; - GHashTable *active_server_map; - - /* OAFIID of the factory */ - char *iid; - - /* Whether the factory has been registered with OAF yet */ - guint registered : 1; -}; - -/* Signal IDs */ -enum { - LAST_BOOK_GONE, - LAST_SIGNAL -}; - -static guint factory_signals[LAST_SIGNAL]; - -static char * -pas_book_factory_canonicalize_uri (const char *uri) -{ - /* FIXME: What do I do here? */ - - return g_strdup (uri); -} - -static char * -pas_book_factory_extract_proto_from_uri (const char *uri) -{ - char *proto; - char *p; - - p = strchr (uri, ':'); - - if (p == NULL) - return NULL; - - proto = g_malloc0 (p - uri + 1); - - strncpy (proto, uri, p - uri); - - return proto; -} - -/** - * pas_book_factory_register_backend: - * @factory: - * @proto: - * @backend: - */ -void -pas_book_factory_register_backend (PASBookFactory *factory, - const char *proto, - PASBackendFactoryFn backend) -{ - g_return_if_fail (factory != NULL); - g_return_if_fail (PAS_IS_BOOK_FACTORY (factory)); - g_return_if_fail (proto != NULL); - g_return_if_fail (backend != NULL); - - if (g_hash_table_lookup (factory->priv->backends, proto) != NULL) { - g_warning ("pas_book_factory_register_backend: " - "Proto \"%s\" already registered!\n", proto); - } - - g_hash_table_insert (factory->priv->backends, - g_strdup (proto), backend); -} - -/** - * pas_book_factory_get_n_backends: - * @factory: An addressbook factory. - * - * Queries the number of running addressbook backends in an addressbook factory. - * - * Return value: Number of running backends. - **/ -int -pas_book_factory_get_n_backends (PASBookFactory *factory) -{ - int n_backends; - - g_return_val_if_fail (factory != NULL, -1); - g_return_val_if_fail (PAS_IS_BOOK_FACTORY (factory), -1); - - g_mutex_lock (factory->priv->map_mutex); - n_backends = g_hash_table_size (factory->priv->active_server_map); - g_mutex_unlock (factory->priv->map_mutex); - - return n_backends; -} - -static void -dump_active_server_map_entry (gpointer key, gpointer value, gpointer data) -{ - char *uri; - PASBackend *backend; - - uri = key; - backend = PAS_BACKEND (value); - - g_message (" %s: %p", uri, backend); -} - -void -pas_book_factory_dump_active_backends (PASBookFactory *factory) -{ - g_message ("Active PAS backends"); - - g_mutex_lock (factory->priv->map_mutex); - g_hash_table_foreach (factory->priv->active_server_map, - dump_active_server_map_entry, - NULL); - g_mutex_unlock (factory->priv->map_mutex); -} - -/* Callback used when a backend loses its last connected client */ -static void -backend_last_client_gone_cb (PASBackend *backend, gpointer data) -{ - PASBookFactory *factory; - const char *uri; - - factory = PAS_BOOK_FACTORY (data); - - /* Remove the backend from the active server map */ - - uri = pas_backend_get_uri (backend); - if (uri) { - gpointer orig_key; - gboolean result; - char *orig_uri; - - g_mutex_lock (factory->priv->map_mutex); - - result = g_hash_table_lookup_extended (factory->priv->active_server_map, uri, - &orig_key, NULL); - g_assert (result != FALSE); - - orig_uri = orig_key; - - g_hash_table_remove (factory->priv->active_server_map, orig_uri); - g_free (orig_uri); - - g_object_unref (backend); - - g_mutex_unlock (factory->priv->map_mutex); - } - - if (g_hash_table_size (factory->priv->active_server_map) == 0) { - /* Notify upstream if there are no more backends */ - g_signal_emit (G_OBJECT (factory), factory_signals[LAST_BOOK_GONE], 0); - } -} - - - -static PASBackendFactoryFn -pas_book_factory_lookup_backend_factory (PASBookFactory *factory, - const char *uri) -{ - PASBackendFactoryFn backend_fn; - char *proto; - char *canonical_uri; - - g_assert (factory != NULL); - g_assert (PAS_IS_BOOK_FACTORY (factory)); - g_assert (uri != NULL); - - canonical_uri = pas_book_factory_canonicalize_uri (uri); - if (canonical_uri == NULL) - return NULL; - - proto = pas_book_factory_extract_proto_from_uri (canonical_uri); - if (proto == NULL) { - g_free (canonical_uri); - return NULL; - } - - backend_fn = g_hash_table_lookup (factory->priv->backends, proto); - - g_free (proto); - g_free (canonical_uri); - - return backend_fn; -} - -static PASBackend * -pas_book_factory_launch_backend (PASBookFactory *factory, - PASBackendFactoryFn backend_factory, - GNOME_Evolution_Addressbook_BookListener listener, - const char *uri) -{ - PASBackend *backend; - - backend = (* backend_factory) (); - if (!backend) - return NULL; - - g_hash_table_insert (factory->priv->active_server_map, - g_strdup (uri), - backend); - - g_signal_connect (backend, "last_client_gone", - G_CALLBACK (backend_last_client_gone_cb), - factory); - - return backend; -} - -static GNOME_Evolution_Addressbook_Book -impl_GNOME_Evolution_Addressbook_BookFactory_getBook (PortableServer_Servant servant, - const CORBA_char *uri, - const GNOME_Evolution_Addressbook_BookListener listener, - CORBA_Environment *ev) -{ - PASBookFactory *factory = PAS_BOOK_FACTORY (bonobo_object (servant)); - PASBackend *backend; - PASBook *book; - - printf ("impl_GNOME_Evolution_Addressbook_BookFactory_getBook\n"); - - /* Look up the backend and create one if needed */ - g_mutex_lock (factory->priv->map_mutex); - - backend = g_hash_table_lookup (factory->priv->active_server_map, uri); - - if (!backend) { - PASBackendFactoryFn backend_factory; - - backend_factory = pas_book_factory_lookup_backend_factory (factory, uri); - - if (backend_factory == NULL) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Addressbook_BookFactory_ProtocolNotSupported, - NULL); - - g_mutex_unlock (factory->priv->map_mutex); - - return CORBA_OBJECT_NIL; - } - - backend = pas_book_factory_launch_backend (factory, backend_factory, listener, uri); - } - - if (backend) { - GNOME_Evolution_Addressbook_BookListener listener_copy; - - listener_copy = bonobo_object_dup_ref (listener, NULL); - - g_mutex_unlock (factory->priv->map_mutex); - - book = pas_book_new (backend, uri, listener); - - pas_backend_add_client (backend, book); - - return bonobo_object_corba_objref (BONOBO_OBJECT (book)); - } - else { - /* probably need a more descriptive exception here */ - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Addressbook_BookFactory_ProtocolNotSupported, - NULL); - g_mutex_unlock (factory->priv->map_mutex); - - return CORBA_OBJECT_NIL; - } -} - -static void -pas_book_factory_construct (PASBookFactory *factory) -{ - /* nothing to do here.. */ -} - -/** - * pas_book_factory_new: - */ -PASBookFactory * -pas_book_factory_new (void) -{ - PASBookFactory *factory; - - factory = g_object_new (PAS_TYPE_BOOK_FACTORY, - "poa", bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_REQUEST, NULL), - NULL); - - pas_book_factory_construct (factory); - - return factory; -} - -/** - * pas_book_factory_activate: - */ -gboolean -pas_book_factory_activate (PASBookFactory *factory, const char *iid) -{ - PASBookFactoryPrivate *priv; - Bonobo_RegistrationResult result; - char *tmp_iid; - - g_return_val_if_fail (factory != NULL, FALSE); - g_return_val_if_fail (PAS_IS_BOOK_FACTORY (factory), FALSE); - - priv = factory->priv; - - g_return_val_if_fail (!priv->registered, FALSE); - - /* if iid is NULL, use the default factory OAFIID */ - if (iid) - tmp_iid = g_strdup (iid); - else - tmp_iid = g_strdup (DEFAULT_PAS_BOOK_FACTORY_OAF_ID); - - result = bonobo_activation_active_server_register (tmp_iid, bonobo_object_corba_objref (BONOBO_OBJECT (factory))); - - switch (result) { - case Bonobo_ACTIVATION_REG_SUCCESS: - priv->registered = TRUE; - priv->iid = tmp_iid; - return TRUE; - case Bonobo_ACTIVATION_REG_NOT_LISTED: - g_message ("Error registering the PAS factory: not listed"); - break; - case Bonobo_ACTIVATION_REG_ALREADY_ACTIVE: - g_message ("Error registering the PAS factory: already active"); - break; - case Bonobo_ACTIVATION_REG_ERROR: - default: - g_message ("Error registering the PAS factory: generic error"); - break; - } - - g_free (tmp_iid); - return FALSE; -} - -static void -pas_book_factory_init (PASBookFactory *factory) -{ - factory->priv = g_new0 (PASBookFactoryPrivate, 1); - - factory->priv->map_mutex = g_mutex_new(); - factory->priv->active_server_map = g_hash_table_new (g_str_hash, g_str_equal); - factory->priv->backends = g_hash_table_new (g_str_hash, g_str_equal); - factory->priv->registered = FALSE; -} - -static void -free_active_server_map_entry (gpointer key, gpointer value, gpointer data) -{ - char *uri; - PASBackend *backend; - - uri = key; - g_free (uri); - - backend = PAS_BACKEND (value); - g_object_unref (backend); -} - -static void -remove_backends_entry (gpointer key, gpointer value, gpointer data) -{ - char *uri; - - uri = key; - g_free (uri); -} - -static void -pas_book_factory_dispose (GObject *object) -{ - PASBookFactory *factory = PAS_BOOK_FACTORY (object); - - if (factory->priv) { - PASBookFactoryPrivate *priv = factory->priv; - - g_mutex_free (priv->map_mutex); - - g_hash_table_foreach (priv->active_server_map, - free_active_server_map_entry, - NULL); - g_hash_table_destroy (priv->active_server_map); - priv->active_server_map = NULL; - - g_hash_table_foreach (priv->backends, - remove_backends_entry, - NULL); - g_hash_table_destroy (priv->backends); - priv->backends = NULL; - - if (priv->registered) { - bonobo_activation_active_server_unregister (priv->iid, - bonobo_object_corba_objref (BONOBO_OBJECT (factory))); - priv->registered = FALSE; - } - - g_free (priv->iid); - - g_free (priv); - factory->priv = NULL; - } - - if (G_OBJECT_CLASS (pas_book_factory_parent_class)->dispose) - G_OBJECT_CLASS (pas_book_factory_parent_class)->dispose (object); -} - -static void -pas_book_factory_class_init (PASBookFactoryClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - POA_GNOME_Evolution_Addressbook_BookFactory__epv *epv; - - pas_book_factory_parent_class = g_type_class_peek_parent (klass); - - object_class->dispose = pas_book_factory_dispose; - - factory_signals[LAST_BOOK_GONE] = - g_signal_new ("last_book_gone", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (PASBookFactoryClass, last_book_gone), - NULL, NULL, - pas_marshal_NONE__NONE, - G_TYPE_NONE, 0); - - - epv = &klass->epv; - - epv->getBook = impl_GNOME_Evolution_Addressbook_BookFactory_getBook; -} - -BONOBO_TYPE_FUNC_FULL ( - PASBookFactory, - GNOME_Evolution_Addressbook_BookFactory, - BONOBO_TYPE_OBJECT, - pas_book_factory); diff --git a/addressbook/backend/pas/pas-book-factory.h b/addressbook/backend/pas/pas-book-factory.h deleted file mode 100644 index 9d099a6f2c..0000000000 --- a/addressbook/backend/pas/pas-book-factory.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2000, Ximian, Inc. - */ - -#include -#include - -#ifndef __PAS_BOOK_FACTORY_H__ -#define __PAS_BOOK_FACTORY_H__ - -G_BEGIN_DECLS - -#define PAS_TYPE_BOOK_FACTORY (pas_book_factory_get_type ()) -#define PAS_BOOK_FACTORY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BOOK_FACTORY, PASBookFactory)) -#define PAS_BOOK_FACTORY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_TYPE_BOOK_FACTORY, PASBookFactoryClass)) -#define PAS_IS_BOOK_FACTORY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BOOK_FACTORY)) -#define PAS_IS_BOOK_FACTORY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BOOK_FACTORY)) -#define PAS_BOOK_FACTORY_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BOOK_FACTORY, PASBookFactoryClass)) - -typedef struct _PASBookFactoryPrivate PASBookFactoryPrivate; - -typedef struct { - BonoboObject parent_object; - PASBookFactoryPrivate *priv; -} PASBookFactory; - -typedef struct { - BonoboObjectClass parent_class; - - POA_GNOME_Evolution_Addressbook_BookFactory__epv epv; - - /* Notification signals */ - - void (* last_book_gone) (PASBookFactory *factory); -} PASBookFactoryClass; - -PASBookFactory *pas_book_factory_new (void); - -void pas_book_factory_register_backend (PASBookFactory *factory, - const char *proto, - PASBackendFactoryFn backend_factory); - -int pas_book_factory_get_n_backends (PASBookFactory *factory); - -void pas_book_factory_dump_active_backends (PASBookFactory *factory); - -gboolean pas_book_factory_activate (PASBookFactory *factory, const char *iid); - -GType pas_book_factory_get_type (void); - -G_END_DECLS - -#endif /* ! __PAS_BOOK_FACTORY_H__ */ diff --git a/addressbook/backend/pas/pas-book-view.c b/addressbook/backend/pas/pas-book-view.c deleted file mode 100644 index afdfb1dacb..0000000000 --- a/addressbook/backend/pas/pas-book-view.c +++ /dev/null @@ -1,465 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * pas-book-view.c - * - * Copyright 2000, Ximian, Inc. - */ - -#include -#include -#include -#include -#include "pas-backend.h" -#include "pas-backend-card-sexp.h" -#include "pas-book-view.h" - -static BonoboObjectClass *pas_book_view_parent_class; - -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; - int next_threshold; - int threshold_max; - - CORBA_sequence_GNOME_Evolution_Addressbook_VCard changes; - CORBA_sequence_GNOME_Evolution_Addressbook_ContactId removes; - - PASBackend *backend; - char *card_query; - PASBackendCardSExp *card_sexp; - GHashTable *ids; -}; - -static void -send_pending_adds (PASBookView *book_view, gboolean reset) -{ - CORBA_Environment ev; - CORBA_sequence_GNOME_Evolution_Addressbook_VCard *adds; - - adds = &book_view->priv->adds; - if (adds->_length == 0) - return; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookViewListener_notifyContactsAdded ( - book_view->priv->listener, adds, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("send_pending_adds: Exception signaling BookViewListener!\n"); - } - - CORBA_exception_free (&ev); - - CORBA_free (adds->_buffer); - adds->_buffer = NULL; - adds->_maximum = 0; - adds->_length = 0; - - if (reset) - book_view->priv->next_threshold = INITIAL_THRESHOLD; -} - -static void -send_pending_changes (PASBookView *book_view) -{ - CORBA_Environment ev; - CORBA_sequence_GNOME_Evolution_Addressbook_VCard *changes; - - changes = &book_view->priv->changes; - if (changes->_length == 0) - return; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookViewListener_notifyContactsChanged ( - book_view->priv->listener, changes, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("send_pending_changes: Exception signaling BookViewListener!\n"); - } - - CORBA_exception_free (&ev); - - CORBA_free (changes->_buffer); - changes->_buffer = NULL; - changes->_maximum = 0; - changes->_length = 0; -} - -static void -send_pending_removes (PASBookView *book_view) -{ - CORBA_Environment ev; - CORBA_sequence_GNOME_Evolution_Addressbook_VCard *removes; - - removes = &book_view->priv->removes; - if (removes->_length == 0) - return; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookViewListener_notifyContactsRemoved ( - book_view->priv->listener, removes, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("send_pending_removes: Exception signaling BookViewListener!\n"); - } - - CORBA_exception_free (&ev); - - CORBA_free (removes->_buffer); - removes->_buffer = NULL; - removes->_maximum = 0; - removes->_length = 0; -} - -#define MAKE_REALLOC(type) \ -static void \ -CORBA_sequence_ ## type ## _realloc (CORBA_sequence_ ## type *seq, \ - CORBA_unsigned_long new_max) \ -{ \ - type *new_buf; \ - \ - new_buf = CORBA_sequence_ ## type ## _allocbuf (new_max); \ - memcpy (new_buf, seq->_buffer, seq->_maximum * sizeof (type)); \ - CORBA_free (seq->_buffer); \ - seq->_buffer = new_buf; \ - seq->_maximum = new_max; \ -} - -MAKE_REALLOC (GNOME_Evolution_Addressbook_VCard) -MAKE_REALLOC (GNOME_Evolution_Addressbook_ContactId) - -static void -notify_change (PASBookView *book_view, const char *vcard) -{ - CORBA_sequence_GNOME_Evolution_Addressbook_VCard *changes; - - send_pending_adds (book_view, TRUE); - send_pending_removes (book_view); - - changes = &book_view->priv->changes; - - if (changes->_length == changes->_maximum) { - CORBA_sequence_GNOME_Evolution_Addressbook_VCard_realloc ( - changes, 2 * (changes->_maximum + 1)); - } - - changes->_buffer[changes->_length++] = CORBA_string_dup (vcard); -} - -static void -notify_remove (PASBookView *book_view, const char *id) -{ - CORBA_sequence_GNOME_Evolution_Addressbook_ContactId *removes; - - send_pending_adds (book_view, TRUE); - send_pending_changes (book_view); - - removes = &book_view->priv->removes; - - if (removes->_length == removes->_maximum) { - CORBA_sequence_GNOME_Evolution_Addressbook_ContactId_realloc ( - removes, 2 * (removes->_maximum + 1)); - } - - removes->_buffer[removes->_length++] = CORBA_string_dup (id); - g_hash_table_remove (book_view->priv->ids, id); -} - -static void -notify_add (PASBookView *book_view, const char *id, const char *vcard) -{ - CORBA_sequence_GNOME_Evolution_Addressbook_VCard *adds; - PASBookViewPrivate *priv = book_view->priv; - - send_pending_changes (book_view); - send_pending_removes (book_view); - - adds = &priv->adds; - - if (adds->_length == adds->_maximum) { - send_pending_adds (book_view, FALSE); - - adds->_buffer = CORBA_sequence_GNOME_Evolution_Addressbook_VCard_allocbuf (priv->next_threshold); - adds->_maximum = priv->next_threshold; - - if (priv->next_threshold < priv->threshold_max) { - priv->next_threshold = MIN (2 * priv->next_threshold, - priv->threshold_max); - } - } - - adds->_buffer[adds->_length++] = CORBA_string_dup (vcard); - g_hash_table_insert (book_view->priv->ids, g_strdup (id), - GUINT_TO_POINTER (1)); -} - -/** - * pas_book_view_notify_update: - */ -void -pas_book_view_notify_update (PASBookView *book_view, - EContact *contact) -{ - gboolean currently_in_view, want_in_view; - const char *id; - char *vcard; - - g_mutex_lock (book_view->priv->pending_mutex); - - id = e_contact_get_const (contact, E_CONTACT_UID); - - currently_in_view = - g_hash_table_lookup (book_view->priv->ids, id) != NULL; - want_in_view = pas_backend_card_sexp_match_contact ( - book_view->priv->card_sexp, contact); - - if (want_in_view) { - vcard = e_vcard_to_string (E_VCARD (contact), - EVC_FORMAT_VCARD_30); - - if (currently_in_view) - notify_change (book_view, vcard); - else - notify_add (book_view, id, vcard); - - g_free (vcard); - } else { - if (currently_in_view) - pas_book_view_notify_remove (book_view, id); - /* else nothing; we're removing a card that wasn't there */ - } - - g_mutex_unlock (book_view->priv->pending_mutex); -} - -/** - * pas_book_view_notify_remove: - */ -void -pas_book_view_notify_remove (PASBookView *book_view, - const char *id) -{ - g_mutex_lock (book_view->priv->pending_mutex); - notify_remove (book_view, id); - g_mutex_unlock (book_view->priv->pending_mutex); -} - - -void -pas_book_view_notify_complete (PASBookView *book_view, - GNOME_Evolution_Addressbook_CallStatus status) -{ - CORBA_Environment ev; - - g_mutex_lock (book_view->priv->pending_mutex); - - send_pending_adds (book_view, TRUE); - send_pending_changes (book_view); - send_pending_removes (book_view); - - g_mutex_unlock (book_view->priv->pending_mutex); - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookViewListener_notifySequenceComplete ( - book_view->priv->listener, status, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_view_notify_complete: Exception signaling BookViewListener!\n"); - } - - CORBA_exception_free (&ev); -} - -void -pas_book_view_notify_status_message (PASBookView *book_view, - const char *message) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookViewListener_notifyProgress ( - book_view->priv->listener, message, 0, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_view_notify_status_message: Exception signaling BookViewListener!\n"); - } - - CORBA_exception_free (&ev); -} - -static void -pas_book_view_construct (PASBookView *book_view, - PASBackend *backend, - GNOME_Evolution_Addressbook_BookViewListener listener, - const char *card_query, - PASBackendCardSExp *card_sexp) -{ - PASBookViewPrivate *priv; - CORBA_Environment ev; - - g_return_if_fail (book_view != NULL); - g_return_if_fail (listener != CORBA_OBJECT_NIL); - - priv = book_view->priv; - - CORBA_exception_init (&ev); - - priv->listener = CORBA_Object_duplicate (listener, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning("Unable to duplicate listener object in pas-book-view.c\n"); - CORBA_exception_free (&ev); - return; - } - - CORBA_exception_free (&ev); - - priv->backend = backend; - priv->card_query = g_strdup (card_query); - priv->card_sexp = card_sexp; -} - -/** - * pas_book_view_new: - */ -static void -impl_GNOME_Evolution_Addressbook_BookView_start (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - PASBookView *view = PAS_BOOK_VIEW (bonobo_object (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 - */ -const char* -pas_book_view_get_card_query (PASBookView *book_view) -{ - return book_view->priv->card_query; -} - -/** - * pas_book_view_get_card_sexp - */ -PASBackendCardSExp* -pas_book_view_get_card_sexp (PASBookView *book_view) -{ - return book_view->priv->card_sexp; -} - -PASBackend* -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: - */ -PASBookView * -pas_book_view_new (PASBackend *backend, - GNOME_Evolution_Addressbook_BookViewListener listener, - const char *card_query, - PASBackendCardSExp *card_sexp) -{ - PASBookView *book_view; - - book_view = g_object_new (PAS_TYPE_BOOK_VIEW, NULL); - - pas_book_view_construct (book_view, backend, listener, card_query, card_sexp); - - return book_view; -} - -static void -pas_book_view_dispose (GObject *object) -{ - PASBookView *book_view = PAS_BOOK_VIEW (object); - - if (book_view->priv) { - bonobo_object_release_unref (book_view->priv->listener, NULL); - - if (book_view->priv->adds._buffer) - CORBA_free (book_view->priv->adds._buffer); - if (book_view->priv->changes._buffer) - CORBA_free (book_view->priv->changes._buffer); - if (book_view->priv->removes._buffer) - CORBA_free (book_view->priv->removes._buffer); - - g_free (book_view->priv->card_query); - g_object_unref (book_view->priv->card_sexp); - - g_mutex_free (book_view->priv->pending_mutex); - book_view->priv->pending_mutex = NULL; - - g_free (book_view->priv); - book_view->priv = NULL; - } - - if (G_OBJECT_CLASS (pas_book_view_parent_class)->dispose) - G_OBJECT_CLASS (pas_book_view_parent_class)->dispose (object); -} - -static void -pas_book_view_class_init (PASBookViewClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - POA_GNOME_Evolution_Addressbook_BookView__epv *epv; - - pas_book_view_parent_class = g_type_class_peek_parent (klass); - - object_class->dispose = pas_book_view_dispose; - - epv = &klass->epv; - - epv->start = impl_GNOME_Evolution_Addressbook_BookView_start; - epv->stop = impl_GNOME_Evolution_Addressbook_BookView_stop; - -} - -static void -pas_book_view_init (PASBookView *book_view) -{ - book_view->priv = g_new0 (PASBookViewPrivate, 1); - - book_view->priv->pending_mutex = g_mutex_new(); - - book_view->priv->next_threshold = INITIAL_THRESHOLD; - 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); -} - -BONOBO_TYPE_FUNC_FULL ( - PASBookView, - GNOME_Evolution_Addressbook_BookView, - BONOBO_TYPE_OBJECT, - pas_book_view); diff --git a/addressbook/backend/pas/pas-book-view.h b/addressbook/backend/pas/pas-book-view.h deleted file mode 100644 index 3b292d11db..0000000000 --- a/addressbook/backend/pas/pas-book-view.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * A wrapper object which exports the GNOME_Evolution_Addressbook_Book CORBA interface - * and which maintains a request queue. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#ifndef __PAS_BOOK_VIEW_H__ -#define __PAS_BOOK_VIEW_H__ - -#include -#include -#include -#include -#include -#include - -#define PAS_TYPE_BOOK_VIEW (pas_book_view_get_type ()) -#define PAS_BOOK_VIEW(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BOOK_VIEW, PASBookView)) -#define PAS_BOOK_VIEW_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_TYPE_BOOK_VIEW, PASBookViewClass)) -#define PAS_IS_BOOK_VIEW(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BOOK_VIEW)) -#define PAS_IS_BOOK_VIEW_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BOOK_VIEW)) -#define PAS_BOOK_VIEW_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BOOK_VIEW, PASBookView)) - -typedef struct _PASBookViewPrivate PASBookViewPrivate; - -struct _PASBookView { - BonoboObject parent_object; - PASBookViewPrivate *priv; -}; - -struct _PASBookViewClass { - BonoboObjectClass parent_class; - - POA_GNOME_Evolution_Addressbook_BookView__epv epv; -}; - - -PASBookView *pas_book_view_new (PASBackend *backend, - GNOME_Evolution_Addressbook_BookViewListener listener, - const char *card_query, - PASBackendCardSExp *card_sexp); - -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); -void pas_book_view_notify_remove (PASBookView *book_view, - const char *id); -void pas_book_view_notify_complete (PASBookView *book_view, - GNOME_Evolution_Addressbook_CallStatus); -void pas_book_view_notify_status_message (PASBookView *book_view, - const char *message); - -GType pas_book_view_get_type (void); - -#endif /* ! __PAS_BOOK_VIEW_H__ */ diff --git a/addressbook/backend/pas/pas-book.c b/addressbook/backend/pas/pas-book.c deleted file mode 100644 index 346b37ceed..0000000000 --- a/addressbook/backend/pas/pas-book.c +++ /dev/null @@ -1,770 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * pas-book.c - * - * Copyright 2000, Ximian, Inc. - */ - -#include -#include -#include -#include "e-util/e-list.h" -#include "ebook/e-contact.h" -#include "pas-book-view.h" -#include "pas-backend.h" -#include "pas-backend-card-sexp.h" -#include "pas-marshal.h" - -static BonoboObjectClass *pas_book_parent_class; -POA_GNOME_Evolution_Addressbook_Book__vepv pas_book_vepv; - -struct _PASBookPrivate { - PASBackend *backend; - GNOME_Evolution_Addressbook_BookListener listener; - char *uri; -}; - -static void -impl_GNOME_Evolution_Addressbook_Book_open (PortableServer_Servant servant, - const CORBA_boolean only_if_exists, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - printf ("impl_GNOME_Evolution_Addressbook_Book_open\n"); - - pas_backend_open (pas_book_get_backend (book), book, only_if_exists); -} - -static void -impl_GNOME_Evolution_Addressbook_Book_remove (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - printf ("impl_GNOME_Evolution_Addressbook_Book_remove\n"); - - pas_backend_remove (pas_book_get_backend (book), book); -} - -static void -impl_GNOME_Evolution_Addressbook_Book_getContact (PortableServer_Servant servant, - const CORBA_char *id, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - printf ("impl_GNOME_Evolution_Addressbook_Book_getContact\n"); - - pas_backend_get_contact (pas_book_get_backend (book), book, id); -} - -static void -impl_GNOME_Evolution_Addressbook_Book_getContactList (PortableServer_Servant servant, - const CORBA_char *query, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - printf ("impl_GNOME_Evolution_Addressbook_Book_getContactList\n"); - - pas_backend_get_contact_list (pas_book_get_backend (book), book, query); -} - -static void -impl_GNOME_Evolution_Addressbook_Book_authenticateUser (PortableServer_Servant servant, - const char* user, - const char* passwd, - const char* auth_method, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - pas_backend_authenticate_user (pas_book_get_backend (book), book, - user, passwd, auth_method); -} - -static void -impl_GNOME_Evolution_Addressbook_Book_addContact (PortableServer_Servant servant, - const CORBA_char *vcard, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - pas_backend_create_contact (pas_book_get_backend (book), book, vcard); -} - -static void -impl_GNOME_Evolution_Addressbook_Book_removeContacts (PortableServer_Servant servant, - const GNOME_Evolution_Addressbook_ContactIdList *ids, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - int i; - GList *id_list = NULL; - - for (i = 0; i < ids->_length; i ++) - id_list = g_list_append (id_list, ids->_buffer[i]); - - pas_backend_remove_contacts (pas_book_get_backend (book), book, id_list); - - g_list_free (id_list); -} - -static void -impl_GNOME_Evolution_Addressbook_Book_modifyContact (PortableServer_Servant servant, - const CORBA_char *vcard, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - pas_backend_modify_contact (pas_book_get_backend (book), book, vcard); -} - -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, - const GNOME_Evolution_Addressbook_stringlist* requested_fields, - const CORBA_long max_results, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - PASBackend *backend = pas_book_get_backend (book); - PASBackendCardSExp *card_sexp; - PASBookView *view; - - g_warning ("impl_GNOME_Evolution_Addressbook_Book_getBookView (%s)\n", search); - - /* we handle this entirely here, since it doesn't require any - backend involvement now that we have pas_book_view_start to - actually kick off the search. */ - - card_sexp = pas_backend_card_sexp_new (search); - if (!card_sexp) { - pas_book_respond_get_book_view (book, GNOME_Evolution_Addressbook_InvalidQuery, NULL); - return; - } - - view = pas_book_view_new (backend, listener, search, card_sexp); - - if (!view) { - g_object_unref (card_sexp); - pas_book_respond_get_book_view (book, GNOME_Evolution_Addressbook_OtherError, NULL); - 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); - - pas_book_respond_get_book_view (book, GNOME_Evolution_Addressbook_Success, view); - - g_object_unref (view); -} - - -static void -impl_GNOME_Evolution_Addressbook_Book_getChanges (PortableServer_Servant servant, - const CORBA_char *change_id, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - pas_backend_get_changes (pas_book_get_backend (book), book, change_id); -} - -static char * -impl_GNOME_Evolution_Addressbook_Book_getStaticCapabilities (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - char *temp; - char *ret_val; - - temp = pas_backend_get_static_capabilities (book->priv->backend); - ret_val = CORBA_string_dup(temp); - g_free(temp); - return ret_val; -} - -static void -impl_GNOME_Evolution_Addressbook_Book_getSupportedFields (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - pas_backend_get_supported_fields (pas_book_get_backend (book), book); -} - -static void -impl_GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - pas_backend_get_supported_auth_methods (pas_book_get_backend (book), book); -} - -static GNOME_Evolution_Addressbook_CallStatus -impl_GNOME_Evolution_Addressbook_Book_cancelOperation (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - PASBook *book = PAS_BOOK (bonobo_object (servant)); - - return pas_backend_cancel_operation (pas_book_get_backend (book), book); -} - -/** - * pas_book_get_backend: - */ -PASBackend * -pas_book_get_backend (PASBook *book) -{ - g_return_val_if_fail (book && PAS_IS_BOOK (book), NULL); - - return book->priv->backend; -} - -GNOME_Evolution_Addressbook_BookListener -pas_book_get_listener (PASBook *book) -{ - g_return_val_if_fail (book && PAS_IS_BOOK (book), CORBA_OBJECT_NIL); - - return book->priv->listener; -} - -const char* -pas_book_get_uri (PASBook *book) -{ - return book->priv->uri; -} - -/** - * pas_book_respond_open: - */ -void -pas_book_respond_open (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - GNOME_Evolution_Addressbook_BookListener_notifyBookOpened (book->priv->listener, status, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_respond_open: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -/** - * pas_book_respond_remove: - */ -void -pas_book_respond_remove (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - GNOME_Evolution_Addressbook_BookListener_notifyBookRemoved (book->priv->listener, status, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_respond_remove: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -/** - * pas_book_respond_create: - */ -void -pas_book_respond_create (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status, - EContact *contact) -{ - CORBA_Environment ev; - - if (status == GNOME_Evolution_Addressbook_Success) { - pas_backend_notify_update (book->priv->backend, contact); - pas_backend_notify_complete (book->priv->backend); - } - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookListener_notifyContactCreated ( - book->priv->listener, status, - e_contact_get_const (contact, E_CONTACT_UID), &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_respond_create: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -/** - * pas_book_respond_remove_contacts: - */ -void -pas_book_respond_remove_contacts (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status, - GList *ids) -{ - CORBA_Environment ev; - GList *i; - - CORBA_exception_init (&ev); - - if (ids) { - for (i = ids; i; i = i->next) - pas_backend_notify_remove (book->priv->backend, i->data); - pas_backend_notify_complete (book->priv->backend); - } - - GNOME_Evolution_Addressbook_BookListener_notifyContactsRemoved ( - book->priv->listener, status, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_respond_remove: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -/** - * pas_book_respond_modify: - */ -void -pas_book_respond_modify (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status, - EContact *contact) -{ - CORBA_Environment ev; - - if (status == GNOME_Evolution_Addressbook_Success) { - pas_backend_notify_update (book->priv->backend, contact); - pas_backend_notify_complete (book->priv->backend); - } - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookListener_notifyContactModified ( - book->priv->listener, status, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_respond_modify: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -/** - * pas_book_respond_authenticate_user: - */ -void -pas_book_respond_authenticate_user (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookListener_notifyAuthenticationResult ( - book->priv->listener, status, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_respond_authenticate_user: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -void -pas_book_respond_get_supported_fields (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status, - GList *fields) -{ - CORBA_Environment ev; - GNOME_Evolution_Addressbook_stringlist stringlist; - int num_fields; - int i; - GList *iter; - - CORBA_exception_init (&ev); - - num_fields = g_list_length (fields); - - stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_fields); - stringlist._maximum = num_fields; - stringlist._length = num_fields; - - for (i = 0, iter = fields; iter; iter = iter->next, i ++) { - stringlist._buffer[i] = CORBA_string_dup ((char*)iter->data); - } - - printf ("calling GNOME_Evolution_Addressbook_BookListener_notifySupportedFields\n"); - - GNOME_Evolution_Addressbook_BookListener_notifySupportedFields ( - book->priv->listener, status, - &stringlist, - &ev); - - CORBA_exception_free (&ev); - - CORBA_free(stringlist._buffer); -} - -void -pas_book_respond_get_supported_auth_methods (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status, - GList *auth_methods) -{ - CORBA_Environment ev; - GNOME_Evolution_Addressbook_stringlist stringlist; - int num_auth_methods; - GList *iter; - int i; - - CORBA_exception_init (&ev); - - num_auth_methods = g_list_length (auth_methods); - - stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_auth_methods); - stringlist._maximum = num_auth_methods; - stringlist._length = num_auth_methods; - - for (i = 0, iter = auth_methods; iter; iter = iter->next, i ++) { - stringlist._buffer[i] = CORBA_string_dup ((char*)iter->data); - } - - GNOME_Evolution_Addressbook_BookListener_notifySupportedAuthMethods ( - book->priv->listener, status, - &stringlist, - &ev); - - CORBA_exception_free (&ev); - - CORBA_free(stringlist._buffer); -} - -static void -view_destroy(gpointer data, GObject *where_object_was) -{ - PASBook *book = (PASBook *)data; - EIterator *iterator; - gboolean success = FALSE; - EList *views = pas_backend_get_book_views (book->priv->backend); - - for (iterator = e_list_get_iterator(views); - e_iterator_is_valid(iterator); - e_iterator_next(iterator)) { - const PASBookView *view = e_iterator_get(iterator); - if (view == (PASBookView*)where_object_was) { - e_iterator_delete(iterator); - success = TRUE; - break; - } - } - if (!success) - g_warning ("Failed to remove from book_views list"); - g_object_unref(iterator); - g_object_unref(views); -} - -/** - * pas_book_respond_get_book_view: - */ -void -pas_book_respond_get_book_view (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status, - PASBookView *book_view) -{ - CORBA_Environment ev; - CORBA_Object object = CORBA_OBJECT_NIL; - - printf ("pas_book_respond_get_book_view\n"); - - CORBA_exception_init (&ev); - - if (book_view) { - object = bonobo_object_corba_objref(BONOBO_OBJECT(book_view)); - - g_object_weak_ref (G_OBJECT (book_view), view_destroy, book); - } - - GNOME_Evolution_Addressbook_BookListener_notifyViewRequested ( - book->priv->listener, status, object, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_respond_get_book_view: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -/** - * pas_book_respond_get_contact: - */ -void -pas_book_respond_get_contact (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status, - char *vcard) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookListener_notifyContactRequested (book->priv->listener, - status, - vcard, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("could not notify listener of get-contact response"); - - CORBA_exception_free (&ev); -} - -/** - * pas_book_respond_get_contact_list: - */ -void -pas_book_respond_get_contact_list (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status, - GList *card_list) -{ - CORBA_Environment ev; - GNOME_Evolution_Addressbook_stringlist stringlist; - int num_cards; - int i; - GList *l; - - CORBA_exception_init (&ev); - - num_cards = g_list_length (card_list); - - stringlist._buffer = CORBA_sequence_CORBA_string_allocbuf (num_cards); - stringlist._maximum = num_cards; - stringlist._length = num_cards; - - for (i = 0, l = card_list; l; l = l->next, i ++) - stringlist._buffer[i] = CORBA_string_dup (l->data); - - g_list_foreach (card_list, (GFunc)g_free, NULL); - g_list_free (card_list); - - - GNOME_Evolution_Addressbook_BookListener_notifyContactListRequested (book->priv->listener, - status, - &stringlist, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("could not notify listener of get-contact-list response"); - - CORBA_exception_free (&ev); - - CORBA_free(stringlist._buffer); -} - -/** - * pas_book_respond_get_changes: - */ -void -pas_book_respond_get_changes (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status, - GList *changes) -{ - CORBA_Environment ev; - GNOME_Evolution_Addressbook_BookChangeList changelist; - int num_changes; - int i; - GList *l; - - CORBA_exception_init (&ev); - - num_changes = g_list_length (changes); - - changelist._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_BookChangeItem_allocbuf (num_changes); - changelist._maximum = num_changes; - changelist._length = num_changes; - - for (i = 0, l = changes; l; l = l->next, i ++) { - GNOME_Evolution_Addressbook_BookChangeItem *change = (GNOME_Evolution_Addressbook_BookChangeItem*)l->data; - changelist._buffer[i] = *change; - changelist._buffer[i].vcard = CORBA_string_dup (change->vcard); - } - - g_list_foreach (changes, (GFunc)CORBA_free, NULL); - g_list_free (changes); - - GNOME_Evolution_Addressbook_BookListener_notifyChangesRequested (book->priv->listener, - status, - &changelist, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("could not notify listener of get-changes response"); - - CORBA_exception_free (&ev); - - CORBA_free(changelist._buffer); -} - -/** - * pas_book_report_writable: - */ -void -pas_book_report_writable (PASBook *book, - gboolean writable) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_BookListener_notifyWritable ( - book->priv->listener, (CORBA_boolean) writable, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("pas_book_report_writable: Exception " - "responding to BookListener!\n"); - } - - CORBA_exception_free (&ev); -} - -static void -pas_book_construct (PASBook *book, - PASBackend *backend, - const char *uri, - GNOME_Evolution_Addressbook_BookListener listener) -{ - PASBookPrivate *priv; - CORBA_Environment ev; - - g_return_if_fail (book != NULL); - - priv = book->priv; - - CORBA_exception_init (&ev); - book->priv->listener = CORBA_Object_duplicate (listener, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("pas_book_construct(): could not duplicate the listener"); - CORBA_exception_free (&ev); - return; - } - - CORBA_exception_free (&ev); - - priv->backend = backend; - priv->uri = g_strdup (uri); - -} - -/** - * pas_book_new: - */ -PASBook * -pas_book_new (PASBackend *backend, - const char *uri, - GNOME_Evolution_Addressbook_BookListener listener) -{ - PASBook *book; - char *caps = pas_backend_get_static_capabilities (backend); - - book = g_object_new (PAS_TYPE_BOOK, - "poa", bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_REQUEST, NULL), - NULL); - - pas_book_construct (book, backend, uri, listener); - - g_free (caps); - - return book; -} - -static void -pas_book_dispose (GObject *object) -{ - PASBook *book = PAS_BOOK (object); - - if (book->priv) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - CORBA_Object_release (book->priv->listener, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("pas_book_construct(): could not release the listener"); - - CORBA_exception_free (&ev); - - g_free (book->priv->uri); - g_free (book->priv); - book->priv = NULL; - } - - if (G_OBJECT_CLASS (pas_book_parent_class)->dispose) - G_OBJECT_CLASS (pas_book_parent_class)->dispose (object); -} - -static void -pas_book_class_init (PASBookClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - POA_GNOME_Evolution_Addressbook_Book__epv *epv; - - pas_book_parent_class = g_type_class_peek_parent (klass); - - object_class->dispose = pas_book_dispose; - - epv = &klass->epv; - - epv->open = impl_GNOME_Evolution_Addressbook_Book_open; - epv->remove = impl_GNOME_Evolution_Addressbook_Book_remove; - epv->getContact = impl_GNOME_Evolution_Addressbook_Book_getContact; - epv->getContactList = impl_GNOME_Evolution_Addressbook_Book_getContactList; - epv->authenticateUser = impl_GNOME_Evolution_Addressbook_Book_authenticateUser; - epv->addContact = impl_GNOME_Evolution_Addressbook_Book_addContact; - epv->removeContacts = impl_GNOME_Evolution_Addressbook_Book_removeContacts; - epv->modifyContact = impl_GNOME_Evolution_Addressbook_Book_modifyContact; - epv->getStaticCapabilities = impl_GNOME_Evolution_Addressbook_Book_getStaticCapabilities; - epv->getSupportedFields = impl_GNOME_Evolution_Addressbook_Book_getSupportedFields; - epv->getSupportedAuthMethods = impl_GNOME_Evolution_Addressbook_Book_getSupportedAuthMethods; - epv->getBookView = impl_GNOME_Evolution_Addressbook_Book_getBookView; - epv->getChanges = impl_GNOME_Evolution_Addressbook_Book_getChanges; - epv->cancelOperation = impl_GNOME_Evolution_Addressbook_Book_cancelOperation; -} - -static void -pas_book_init (PASBook *book) -{ - book->priv = g_new0 (PASBookPrivate, 1); -} - -BONOBO_TYPE_FUNC_FULL ( - PASBook, - GNOME_Evolution_Addressbook_Book, - BONOBO_TYPE_OBJECT, - pas_book); diff --git a/addressbook/backend/pas/pas-book.h b/addressbook/backend/pas/pas-book.h deleted file mode 100644 index 2cb84569c2..0000000000 --- a/addressbook/backend/pas/pas-book.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * A wrapper object which exports the GNOME_Evolution_Addressbook_Book CORBA interface - * and which maintains a request queue. - * - * Author: - * Nat Friedman (nat@ximian.com) - * - * Copyright 2000, Ximian, Inc. - */ - -#ifndef __PAS_BOOK_H__ -#define __PAS_BOOK_H__ - -#include -#include -#include "e-util/e-list.h" - -#include - -#define PAS_TYPE_BOOK (pas_book_get_type ()) -#define PAS_BOOK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PAS_TYPE_BOOK, PASBook)) -#define PAS_BOOK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PAS_BOOK_FACTORY_TYPE, PASBookClass)) -#define PAS_IS_BOOK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAS_TYPE_BOOK)) -#define PAS_IS_BOOK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PAS_TYPE_BOOK)) -#define PAS_BOOK_GET_CLASS(k) (G_TYPE_INSTANCE_GET_CLASS ((obj), PAS_TYPE_BOOK, PASBookClass)) - -typedef struct _PASBookPrivate PASBookPrivate; - -struct _PASBook { - BonoboObject parent_object; - PASBookPrivate *priv; -}; - -struct _PASBookClass { - BonoboObjectClass parent_class; - - POA_GNOME_Evolution_Addressbook_Book__epv epv; - - /* Padding for future expansion */ - void (*_pas_reserved0) (void); - void (*_pas_reserved1) (void); - void (*_pas_reserved2) (void); - void (*_pas_reserved3) (void); - void (*_pas_reserved4) (void); -}; - - -PASBook *pas_book_new (PASBackend *backend, - const char *uri, - GNOME_Evolution_Addressbook_BookListener listener); -GNOME_Evolution_Addressbook_BookListener pas_book_get_listener (PASBook *book); -PASBackend *pas_book_get_backend (PASBook *book); -const char *pas_book_get_uri (PASBook *book); - -void pas_book_respond_open (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status); -void pas_book_respond_remove (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status); -void pas_book_respond_create (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status, - EContact *contact); -void pas_book_respond_remove_contacts (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status, - GList *ids); -void pas_book_respond_modify (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status, - EContact *contact); -void pas_book_respond_authenticate_user (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status); -void pas_book_respond_get_supported_fields (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status, - GList *fields); -void pas_book_respond_get_supported_auth_methods (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status, - GList *fields); - -void pas_book_respond_get_book_view (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status, - PASBookView *book_view); -void pas_book_respond_get_contact (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status, - char *vcard); -void pas_book_respond_get_contact_list (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status, - GList *cards); -void pas_book_respond_get_changes (PASBook *book, - GNOME_Evolution_Addressbook_CallStatus status, - GList *changes); - -void pas_book_report_writable (PASBook *book, - gboolean writable); - -GType pas_book_get_type (void); - -#endif /* ! __PAS_BOOK_H__ */ diff --git a/addressbook/backend/pas/pas-marshal.list b/addressbook/backend/pas/pas-marshal.list deleted file mode 100644 index 9d6744db44..0000000000 --- a/addressbook/backend/pas/pas-marshal.list +++ /dev/null @@ -1,2 +0,0 @@ -NONE:NONE -NONE:POINTER diff --git a/addressbook/backend/pas/pas-types.h b/addressbook/backend/pas/pas-types.h deleted file mode 100644 index 19611a4e23..0000000000 --- a/addressbook/backend/pas/pas-types.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Blanket header containing the typedefs for object types used in the - * PAS stuff, so we can disentangle the #includes. - * - * Author: Chris Toshok - * - * Copyright 2003, Ximian, Inc. - */ - -#ifndef __PAS_TYPES_H__ -#define __PAS_TYPES_H__ - -typedef struct _PASBookView PASBookView; -typedef struct _PASBookViewClass PASBookViewClass; - -typedef struct _PASBackendCardSExp PASBackendCardSExp; -typedef struct _PASBackendCardSExpClass PASBackendCardSExpClass; - -typedef struct _PASBackend PASBackend; -typedef struct _PASBackendClass PASBackendClass; - -typedef struct _PASBackendSummary PASBackendSummary; -typedef struct _PASBackendSummaryClass PASBackendSummaryClass; - -typedef struct _PASBackendSync PASBackendSync; -typedef struct _PASBackendSyncClass PASBackendSyncClass; - -typedef struct _PASBook PASBook; -typedef struct _PASBookClass PASBookClass; - -#endif /* __PAS_TYPES_H__ */ diff --git a/addressbook/backend/pas/ximian-vcard.h b/addressbook/backend/pas/ximian-vcard.h deleted file mode 100644 index 961a5cadb4..0000000000 --- a/addressbook/backend/pas/ximian-vcard.h +++ /dev/null @@ -1,81 +0,0 @@ -#define XIMIAN_VCARD \ -"BEGIN:VCARD\n" \ -"X-EVOLUTION-FILE-AS:Ximian\\, Inc.\n" \ -"ADR;TYPE=WORK:;Suite 3 West;401 Park Drive;Boston;MA;02215;USA\n" \ -"LABEL;TYPE=WORK:401 Park Drive\\nSuite 3 West\\nBoston\\, MA\\n02215\\nUSA\n" \ -"TEL;WORK;VOICE:(617) 375-3800\n" \ -"TEL;WORK;FAX:(617) 236-8630\n" \ -"EMAIL;INTERNET:hello@ximian.com\n" \ -"URL:http://www.ximian.com/\n" \ -"ORG:Ximian\\, Inc.;\n" \ -"NOTE:Welcome to the Ximian Addressbook.\n" \ -"PHOTO;ENCODING=b;TYPE=JPEG:/9j/4AAQSkZJRgABAQEARwBHAAD//gAXQ3JlYXRlZCB3aXRo\n" \ -" IFRoZSBHSU1Q/9sAQwAIBgYHBgUIBwcHCQkICgwUDQwLCwwZEhMPFB0aHx4dGhwcICQuJyAiLCM\n" \ -" cHCg3KSwwMTQ0NB8nOT04MjwuMzQy/9sAQwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMj\n" \ -" IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgAbgBkAwEiAAIRAQMRAf/EA\n" \ -" BwAAAIDAQEBAQAAAAAAAAAAAAAHBQYIBAMBAv/EAEYQAAEDAwEFBgMEBgQPAAAAAAECAwQABREG\n" \ -" BxIhMWETIkFRcYEUkaEIMkLBFSNSsbLRFmJydRgkMzY3Q0RGgpKTosLh8P/EABsBAQACAwEBAAA\n" \ -" AAAAAAAAAAAAEBQIDBgEH/8QALREAAQMCAwYGAgMAAAAAAAAAAQACAwQREiFRBRMiMUFhMnGBkb\n" \ -" HRBsEUofD/2gAMAwEAAhEDEQA/AH/RRRREVwXe9W2wwFzbpNZixkc1uqwPQeZ6CoHXevLfom1ds\n" \ -" 9h6a6D8PGCsFZHMk+CR4n86yzdbrqfaZqYBSnp0hRPZMoG62ynoOSR1Pua8Lg0XPJegX5Jv6k+0\n" \ -" bBjrWxp22LlkcBIlHs0HqEjiR64peT9umupqyWrhHhpP4WI6eHureNW7Tmw+DGaTI1FJVJdxksM\n" \ -" qKG09CrmfbFMCHpCw2xATDs8JrH4gykq+Z4mqifbMUZsxpd/QUllK53M2SCb2xa+bXvf0gcV0Uw\n" \ -" 0R/DVktH2hdUwlpFxjQrg1490tLPuOH0pvv2qE4jdchx1p8lNAj91Va87OtM3RCt+2Nx3Dyci/q\n" \ -" yPYcD7g1EZ+RR4rSMI9b/S2mhdbhKsmkdtWmNTuNxnXVW2cvgGZRASo+SV8j74PSmOlQUMpORWP\n" \ -" NU7MrjY0rlQFmdDTxOE4cQOo8R1Hyqe2Z7ZJ2m32bXfHnJVpJCUuqO8uP7+Kenh4eVXkFRFUMxx\n" \ -" G4UOSN0Zs4LU1FeEOWxOityYzqHWXEhSFoOQoHkQa963rBFFFFERUdfr1E09Y5d1mr3Y8ZsrV5n\n" \ -" yA6k4A6mpGkL9ojUym0W/TrLmAsGU+AeYBwgfPJ/4RREqrrcb1tJ1oUpBXLmObqUZ7rSByT0SkZ\n" \ -" J8zk1pHQmiLXo+zpbabC3SAp55Q7zyvM9PIUudiGmURbS7fpCMvzFFton8LSTxx6qH0FM7VV9VY\n" \ -" 9MzZ7aQt5tASw3+26ohKB/zEVSVFVvZzGMw02tqe/kpbI8LMR6/C/Xxq9QagfbbP+IW1QQ4Rycf\n" \ -" xncHRAIJ/rEfsmu2a9Fgsl2XIZjtj8bqwgfM1+9L2VFksESAV9o6hG886ebjqjvLWepUSarutdn\n" \ -" MXV+obRcZks/CwCQ5DKMpeBOTxzwzgA9KwfTtfxPOSB5GQUXc9pOjoC+zXe2HV5xiOC6PmkEfWp\n" \ -" xe6tAWghSVDIIOQRXxekNOx4b0WPZYLLTram19mwlJKSMHjjNUzQd2dZM7SNxczcLOsttqVzdYz\n" \ -" 3FewI9iKpK2mjMZdFe7ed9NfT9qZDI4OAd1Vkko50ndoui22kuXq2NBOO9JZSOH9sD9/z86c8gc\n" \ -" DUJNQlaFJUkKSoYII4EVGoKp9PIHt9e6lyRNlZhcqlsJ2guQpydL3F4mO7kw1KP3Fcyj0PEjrnz\n" \ -" rSAIIyOVYfvsJ3TGqlCKpTfYuJfjLHMDOR8jw9q2Foy+o1FpWBckY/XMpUoeRxxHsciu/jeJGB7\n" \ -" eRXPvaWuLT0U/RRRWaxQeVY82x3BVw2oXbJyhgoZR0AQM/UmthK+6fSsWbRQW9pV73x/tZPtwNE\n" \ -" Wj9Nw0WuwwIKQAGI6G/cAZ+tRW0lx5nTEW4Ntqdat9xjy5CEjJLSFZP5H2qaYdCkpUk5BGQa7Ap\n" \ -" DrSm3EpWhYKVJUMgg8wRXz+kqyyTG7VXUsV22Clrfc48+CzMiPIejvIC23EHIUDXNe79b7HbXbh\n" \ -" c5SI8ZvmtZ5nyA5k9BS7d0nfdMPuSdD3JtEZaitdom5Uznx3DzT6cPWkvq/V1611fGW5nZtBCgy\n" \ -" zFbXhtCycE5JxknxPhXR07RUeB3D11H+9lAfwcxmrrqLbxcHpikWGAw1FScByUkqWvrgEBPpxqi\n" \ -" ztdXWdqmNqIIjx7gykJUphJCXAM/eBJ5g4PQCmBZNiDKWEu364uF0jJYh4AT6qUDn2FVu6bPIkT\n" \ -" aTB08xKeMOU2H99eCtKRvZGQMZ7hwceNZxVGzsbmMzIBv5dfNeOjnsCdUwbTtKsV8nJgIccZkqw\n" \ -" lJcThDqvJJz8s4zUtLVzpc2vZZKt+qBIkyUKt0V0ONKSe+7g5SCPDr9Kv0tznXP1cNMyQfxnXBC\n" \ -" tqUyuB3gslftPjJLkGWB3u82o/Ij86bf2e7iqRoxyIpWfhpC0JHQ4V/5GlVtJcBt0RPiXif+00w\n" \ -" Ps5BQtNxP4TJP8Ka6rZZJpW37/Kq68ATlPeiiirBQ0HlWR9t9qVbtpEp/dwiY0h5J8Mgbp/h+ta\n" \ -" 4pM7fdKLumn2rxGbKn4BKl4HEtn73ywD7GiL7o28JuulLbKCsqLKUL/tJ7p+oqyIe4c6RGyzU4g\n" \ -" THLNJc3WpCt9gk8A54j3GPcdaZuoosy82V23QpaYpkEIdeIJKUeIAHieXPkTXA11DuassJsCefY\n" \ -" /SvYZN5FiGZU9edRwLDAXJny2mRukoStQBWQOQHjSjg7PYE7ZmzcZb7cG6KK5CZD6txOCcJQvPg\n" \ -" QAQfAn2q6RNOWi1D9J3R5dwlR2xmZPVv9mlI8ByTj59ar09Lm0jUIQl5Y0zAUMrQSPiXfHHpyz4\n" \ -" D1qTRvMQIieQAQXOtllfIDre/X2WqVmI8Qz6D9q0bP9SO37SrSpW8ZUVXw7q+YcKeSgeRyMZ65q\n" \ -" qammvWTalEv1yjOJtaWfh25CBvBOUkHPlxUeHlyq/MiPCitxorSGWG07qG0DASK45xZlx3GJDaH\n" \ -" WljCkLGQR6VGinY2ofIG8Lri2gOi37hxYG3zC+uT2HY6ZDbyFMrAUlwK7pB5HNRcp7nxqpzdN3G\n" \ -" CFQ7NObTa3nApcaSN/suOe4SDw6VK3O4swojsp9WGmxk9fIDrW4UzWkbt2K/v691vjec8YtZUTa\n" \ -" BL+IuMaIjiWWytXQn/wBD608tgtrVC0W2+tOFSFqd9icD6AVnmFFl6n1AhoAmRPdwcfgR4n2H7q\n" \ -" 2Ppi1N2exRojaQlKEBIHkAK7Gmi3MTWaLn6iTeSF+qmaKKK3rSiuedEanQ3I7qQpC0kEEZzXRRR\n" \ -" FjnaRoSVoq/KcYQv9HOr3mHB/qzz3SenhVi0ftAbnNNwLo6G5iQEodUcJd9fJX760ZqLTkHUdsd\n" \ -" hTWEOtuJwQoVl/XGyS7aakOPwGnJcDORujK0DqPH2qJV0cdUzC/0Oi3QTuhddqY84IuFukwnFFK\n" \ -" JDSmlEcwFDGR86ISI1tgtQ4jYaYaTuoSP/udJS1azvFoAZLnbsp4dm/klPQHmKs0faVEWkfEw32\n" \ -" 1f1CFj8q56XZNSwYG5t7fSt46yB5ucimM5L4c643pXWqU5tCteMpRKUfIIH86ipmvnnAUwoQSf2\n" \ -" 3lZ+g/nWEey5yfCtrquBo8Su0+4sQ46pEp1LTSeZUfoPOlnfr67fZKQlK0QkK/VtficV5nrXOkX\n" \ -" XUk9KQHp0gnghI7qPyAp1bOdkCmH2rneQHHxxQjHdb9OvWr2j2c2Didm74VZVVplGFuQXRsc2fO\n" \ -" Qgb1cmsSXQN1JH+TT4D+dPEAAADkK848duMylppISkDGBXrVkoCKKKKIiiqrrbX9m0JARIua1re\n" \ -" dJDMdoArcI58+AA8zVLsO26RqiS9Gsukpct5lHaKbTLaSrd8wFEZ9s0RN6vGRGZktlDqAoHzFKq\n" \ -" JtomzrPOuzGjZvwEBRTJfckttpbUOae9jJ5cBk8R514Wrbo7e489+3aTlvtQGTIkqElsdm2Mkq4\n" \ -" 4zyPKiKf1Hsj09flKdXEQh4/jR3VfMUvJ/2et1ZMOe8keSgFfyqz2LbfJ1M9IZs2kJsx2O0XnEN\n" \ -" yEAhA4ZwcZ58hxr7ZdtkvUS5SbTo2fJMRsuPkPoSG0jzKsDPPhz4HyoipDewC47+FXFWOjYH51Y\n" \ -" bTsAgtrSqc88/jwWrA+QxUlYtujupZ6oNo0nLlSUtqdKEyW04SMZOVYHiKjP8ACUt5/wB3pX/XT\n" \ -" /KiJnWLQ1nsTSURorad39lIFWZKUoThIAHSlNqDbLP0siKu96MnQ0ygSyVyGzvYxnlnB4jga87F\n" \ -" ttlamXJbs2j50xcZvtXUtyEZCfPB5+gyaIm9RSetm3J68RbhJgaSmPM25vtZaviW09knjxIOM8j\n" \ -" y8q7LHtzstwv/AOhrlBftkkudkFOLS43v5xgqSeHHx5daImrRX5QtK0hSTkGiiLMP2ho8wa1iSn\n" \ -" QoxVRQ20fAKClFQ9eIqq7LLJe7vreG7ZZCoZhqD8iZjustjnnwORkY8c+Wa1ZqbStt1PBMa4MId\n" \ -" Rz7wzg+dL8bEbA1vpa7RtK+CkpdWAfXjRFB7UpCNe6Kdm6NnJft1qluKuUJlvdKznPbYH3hzPXJ\n" \ -" PMGqZsk/zc2gf3G5/Cumc3sRsTO92Rcb3uB3XVjP1r4jYfYGwoN76QsYUEurGR5HjREudhUt2BP\n" \ -" 1TMYID0eyuuoJGRvJII+oq96I2iwtVz7rb7ZZWbalyzyJ9wKUjLsrKEkjH4cE8+Jz049bew+wNb\n" \ -" 3Z76N4YO66sZHlzob2H2Bkktb6CRglLqxkeXOiJZbAv9IMj+7X/wB6ag9lGnEaj17CRJA+BhZmy\n" \ -" lK+6EI44PQq3R6E06W9h9gZVvNb6FYxlLqwcfOhvYhYWt7s99G8MK3XVjI68aIo7UxgbR9IajhQ\n" \ -" 7/Du9yiSF3S3tMNrStlkAAt94DPDI4eJFUvYfNetqNYz4xAfjWZx5skZAUnJHD1FMVrYhYWVbzW\n" \ -" +2ojGUOrBx86EbD7A0FBvfRvDCt11YyPI8aIo23zdP6i2e621TaUJiXCfa1IucFPJt5KVnfHRWS\n" \ -" euPPNZ2YadfkNsspUp1aglCU8yTyrTSNh9gbCgjfSFjCgl1YyPI8al9PbItP2WamUywkuJ5KOVE\n" \ -" emeVEVw02ZH9H4YkEqdDYCifE4oqXbaS02lCRhIGBRRF//Z\n" \ -"END:VCARD" -- cgit v1.2.3