2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 2001-2012 Match Grun and the Claws Mail team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 * General functions for accessing address index file.
26 #include "claws-features.h"
32 #include <glib/gi18n.h>
36 #include "addrcache.h"
38 #include "addressbook.h"
39 #include "addrindex.h"
41 #include "addrquery.h"
42 #include "addr_compl.h"
44 #include "alertpanel.h"
45 #include "passwordstore.h"
47 #ifndef DEV_STANDALONE
48 #include "prefs_gtk.h"
59 #include "ldapserver.h"
61 #include "ldapquery.h"
62 #include "ldapupdate.h"
70 #define TAG_ADDRESS_INDEX "addressbook"
72 #define TAG_IF_ADDRESS_BOOK "book_list"
73 #define TAG_IF_VCARD "vcard_list"
74 #define TAG_IF_JPILOT "jpilot_list"
75 #define TAG_IF_LDAP "ldap_list"
77 #define TAG_DS_ADDRESS_BOOK "book"
78 #define TAG_DS_VCARD "vcard"
79 #define TAG_DS_JPILOT "jpilot"
80 #define TAG_DS_LDAP "server"
82 /* XML Attribute names */
83 #define ATTAG_BOOK_NAME "name"
84 #define ATTAG_BOOK_FILE "file"
86 #define ATTAG_VCARD_NAME "name"
87 #define ATTAG_VCARD_FILE "file"
89 #define ATTAG_JPILOT_NAME "name"
90 #define ATTAG_JPILOT_FILE "file"
91 #define ATTAG_JPILOT_CUSTOM_1 "custom-1"
92 #define ATTAG_JPILOT_CUSTOM_2 "custom-2"
93 #define ATTAG_JPILOT_CUSTOM_3 "custom-3"
94 #define ATTAG_JPILOT_CUSTOM_4 "custom-4"
95 #define ATTAG_JPILOT_CUSTOM "custom-"
97 #define ATTAG_LDAP_NAME "name"
98 #define ATTAG_LDAP_HOST "host"
99 #define ATTAG_LDAP_PORT "port"
100 #define ATTAG_LDAP_BASE_DN "base-dn"
101 #define ATTAG_LDAP_BIND_DN "bind-dn"
102 #define ATTAG_LDAP_BIND_PASS "bind-pass"
103 #define ATTAG_LDAP_CRITERIA "criteria"
104 #define ATTAG_LDAP_MAX_ENTRY "max-entry"
105 #define ATTAG_LDAP_TIMEOUT "timeout"
106 #define ATTAG_LDAP_MAX_AGE "max-age"
107 #define ATTAG_LDAP_DYN_SEARCH "dyn-search"
108 #define ATTAG_LDAP_MATCH_OPT "match-opt"
109 #define ATTAG_LDAP_ENABLE_TLS "enable-tls"
110 #define ATTAG_LDAP_ENABLE_SSL "enable-ssl"
112 #define ELTAG_LDAP_ATTR_SRCH "attribute"
113 #define ATTAG_LDAP_ATTR_NAME "name"
115 /* Attribute values */
116 #define ATVAL_BOOLEAN_YES "yes"
117 #define ATVAL_BOOLEAN_NO "no"
118 #define ATVAL_LDAP_MATCH_BEGIN "begin-with"
119 #define ATVAL_LDAP_MATCH_CONTAINS "contains"
122 #define ATTAG_LDAP_DEFAULT "default"
124 #define DISP_NEW_COMMON _("Common addresses")
125 #define DISP_NEW_PERSONAL _("Personal addresses")
127 /* Old address book */
128 #define TAG_IF_OLD_COMMON "common_address"
129 #define TAG_IF_OLD_PERSONAL "personal_address"
131 #define DISP_OLD_COMMON _("Common address")
132 #define DISP_OLD_PERSONAL _("Personal address")
137 static AddressIndex
*_addressIndex_
= NULL
;
140 * Define attribute name-value pair.
142 typedef struct _AddressIfAttr AddressIfAttrib
;
143 struct _AddressIfAttr
{
148 static AddressDataSource
*addrindex_create_datasource ( AddressIfType ifType
);
150 static GList
*addrindex_ds_get_all_persons ( AddressDataSource
*ds
);
151 static GList
*addrindex_ds_get_all_groups ( AddressDataSource
*ds
);
152 static AddressDataSource
*addrindex_get_datasource ( AddressIndex
*addrIndex
,
153 const gchar
*cacheID
);
154 static AddressInterface
*addrindex_get_interface ( AddressIndex
*addrIndex
,
155 AddressIfType ifType
);
156 static gint
addrindex_write_to ( AddressIndex
*addrIndex
,
157 const gchar
*newFile
);
160 * Define DOM fragment.
162 typedef struct _AddressIfFrag AddressIfFragment
;
163 struct _AddressIfFrag
{
170 * Build interface with default values.
172 * \param type Interface type.
173 * \param name Interface name.
174 * \param tagIf XML tag name for interface in address index file.
175 * \param tagDS XML tag name for datasource in address index file.
176 * \return Address interface object.
178 static AddressInterface
*addrindex_create_interface(
179 gint type
, gchar
*name
, gchar
*tagIf
, gchar
*tagDS
)
181 AddressInterface
*iface
= g_new0( AddressInterface
, 1 );
183 ADDRITEM_TYPE(iface
) = ITEMTYPE_INTERFACE
;
184 ADDRITEM_ID(iface
) = NULL
;
185 ADDRITEM_NAME(iface
) = g_strdup( name
);
186 ADDRITEM_PARENT(iface
) = NULL
;
187 ADDRITEM_SUBTYPE(iface
) = type
;
189 iface
->name
= g_strdup( name
);
190 iface
->listTag
= g_strdup( tagIf
);
191 iface
->itemTag
= g_strdup( tagDS
);
192 iface
->legacyFlag
= FALSE
;
193 iface
->haveLibrary
= TRUE
;
194 iface
->useInterface
= TRUE
;
195 iface
->readOnly
= TRUE
;
197 /* Set callbacks to NULL values - override for each interface */
198 iface
->getAccessFlag
= NULL
;
199 iface
->getModifyFlag
= NULL
;
200 iface
->getReadFlag
= NULL
;
201 iface
->getStatusCode
= NULL
;
202 iface
->getReadData
= NULL
;
203 iface
->getRootFolder
= NULL
;
204 iface
->getListFolder
= NULL
;
205 iface
->getListPerson
= NULL
;
206 iface
->getAllPersons
= NULL
;
207 iface
->getAllGroups
= NULL
;
208 iface
->getName
= NULL
;
209 iface
->listSource
= NULL
;
212 iface
->externalQuery
= FALSE
;
213 iface
->searchOrder
= 0; /* Ignored */
214 iface
->startSearch
= NULL
;
215 iface
->stopSearch
= NULL
;
221 * Build table of of all address book interfaces.
222 * \param addrIndex Address index object.
224 static void addrindex_build_if_list( AddressIndex
*addrIndex
) {
225 AddressInterface
*iface
;
227 /* Create intrinsic XML address book interface */
228 iface
= addrindex_create_interface(
229 ADDR_IF_BOOK
, "Address Book", TAG_IF_ADDRESS_BOOK
,
230 TAG_DS_ADDRESS_BOOK
);
231 iface
->readOnly
= FALSE
;
232 iface
->getModifyFlag
= ( void * ) addrbook_get_modified
;
233 iface
->getAccessFlag
= ( void * ) addrbook_get_accessed
;
234 iface
->getReadFlag
= ( void * ) addrbook_get_read_flag
;
235 iface
->getStatusCode
= ( void * ) addrbook_get_status
;
236 iface
->getReadData
= ( void * ) addrbook_read_data
;
237 iface
->getRootFolder
= ( void * ) addrbook_get_root_folder
;
238 iface
->getListFolder
= ( void * ) addrbook_get_list_folder
;
239 iface
->getListPerson
= ( void * ) addrbook_get_list_person
;
240 iface
->getAllPersons
= ( void * ) addrbook_get_all_persons
;
241 iface
->getAllGroups
= ( void * ) addrbook_get_all_groups
;
242 iface
->getName
= ( void * ) addrbook_get_name
;
243 iface
->setAccessFlag
= ( void * ) addrbook_set_accessed
;
244 iface
->searchOrder
= 0;
246 /* Add to list of interfaces in address book */
247 addrIndex
->interfaceList
=
248 g_list_append( addrIndex
->interfaceList
, iface
);
249 ADDRITEM_PARENT(iface
) = ADDRITEM_OBJECT(addrIndex
);
251 /* Create vCard interface */
252 iface
= addrindex_create_interface(
253 ADDR_IF_VCARD
, "vCard", TAG_IF_VCARD
, TAG_DS_VCARD
);
254 iface
->getModifyFlag
= ( void * ) vcard_get_modified
;
255 iface
->getAccessFlag
= ( void * ) vcard_get_accessed
;
256 iface
->getReadFlag
= ( void * ) vcard_get_read_flag
;
257 iface
->getStatusCode
= ( void * ) vcard_get_status
;
258 iface
->getReadData
= ( void * ) vcard_read_data
;
259 iface
->getRootFolder
= ( void * ) vcard_get_root_folder
;
260 iface
->getListFolder
= ( void * ) vcard_get_list_folder
;
261 iface
->getListPerson
= ( void * ) vcard_get_list_person
;
262 iface
->getAllPersons
= ( void * ) vcard_get_all_persons
;
263 iface
->getName
= ( void * ) vcard_get_name
;
264 iface
->setAccessFlag
= ( void * ) vcard_set_accessed
;
265 iface
->searchOrder
= 0;
266 addrIndex
->interfaceList
=
267 g_list_append( addrIndex
->interfaceList
, iface
);
268 ADDRITEM_PARENT(iface
) = ADDRITEM_OBJECT(addrIndex
);
270 /* Create JPilot interface */
271 iface
= addrindex_create_interface(
272 ADDR_IF_JPILOT
, "J-Pilot", TAG_IF_JPILOT
,
275 iface
->haveLibrary
= jpilot_test_pilot_lib();
276 iface
->useInterface
= iface
->haveLibrary
;
277 iface
->getModifyFlag
= ( void * ) jpilot_get_modified
;
278 iface
->getAccessFlag
= ( void * ) jpilot_get_accessed
;
279 iface
->getReadFlag
= ( void * ) jpilot_get_read_flag
;
280 iface
->getStatusCode
= ( void * ) jpilot_get_status
;
281 iface
->getReadData
= ( void * ) jpilot_read_data
;
282 iface
->getRootFolder
= ( void * ) jpilot_get_root_folder
;
283 iface
->getListFolder
= ( void * ) jpilot_get_list_folder
;
284 iface
->getListPerson
= ( void * ) jpilot_get_list_person
;
285 iface
->getAllPersons
= ( void * ) jpilot_get_all_persons
;
286 iface
->getName
= ( void * ) jpilot_get_name
;
287 iface
->setAccessFlag
= ( void * ) jpilot_set_accessed
;
288 iface
->searchOrder
= 0;
290 iface
->useInterface
= FALSE
;
291 iface
->haveLibrary
= FALSE
;
293 addrIndex
->interfaceList
=
294 g_list_append( addrIndex
->interfaceList
, iface
);
295 ADDRITEM_PARENT(iface
) = ADDRITEM_OBJECT(addrIndex
);
297 /* Create LDAP interface */
298 iface
= addrindex_create_interface(
299 ADDR_IF_LDAP
, "LDAP", TAG_IF_LDAP
, TAG_DS_LDAP
);
301 iface
->readOnly
= FALSE
;
302 /* iface->haveLibrary = ldapsvr_test_ldap_lib(); */
303 iface
->haveLibrary
= ldaputil_test_ldap_lib();
304 iface
->useInterface
= iface
->haveLibrary
;
305 iface
->getModifyFlag
= ( void * ) ldapsvr_get_modified
;
306 iface
->getAccessFlag
= ( void * ) ldapsvr_get_accessed
;
307 iface
->getReadFlag
= ( void * ) ldapsvr_get_read_flag
;
308 iface
->getStatusCode
= ( void * ) ldapsvr_get_status
;
309 iface
->getReadData
= ( void * ) ldapsvr_read_data
;
310 iface
->getRootFolder
= ( void * ) ldapsvr_get_root_folder
;
311 iface
->getListFolder
= ( void * ) ldapsvr_get_list_folder
;
312 iface
->getListPerson
= ( void * ) ldapsvr_get_list_person
;
313 iface
->getName
= ( void * ) ldapsvr_get_name
;
314 iface
->setAccessFlag
= ( void * ) ldapsvr_set_accessed
;
315 iface
->externalQuery
= TRUE
;
316 iface
->searchOrder
= 1;
318 iface
->useInterface
= FALSE
;
319 iface
->haveLibrary
= FALSE
;
321 addrIndex
->interfaceList
=
322 g_list_append( addrIndex
->interfaceList
, iface
);
323 ADDRITEM_PARENT(iface
) = ADDRITEM_OBJECT(addrIndex
);
325 /* Two old legacy data sources (pre 0.7.0) */
326 iface
= addrindex_create_interface(
327 ADDR_IF_COMMON
, "Old Address - common",
328 TAG_IF_OLD_COMMON
, NULL
);
329 iface
->legacyFlag
= TRUE
;
330 addrIndex
->interfaceList
=
331 g_list_append( addrIndex
->interfaceList
, iface
);
332 ADDRITEM_PARENT(iface
) = ADDRITEM_OBJECT(addrIndex
);
334 iface
= addrindex_create_interface(
335 ADDR_IF_COMMON
, "Old Address - personal",
336 TAG_IF_OLD_PERSONAL
, NULL
);
337 iface
->legacyFlag
= TRUE
;
338 addrIndex
->interfaceList
=
339 g_list_append( addrIndex
->interfaceList
, iface
);
340 ADDRITEM_PARENT(iface
) = ADDRITEM_OBJECT(addrIndex
);
346 * \param fragment Fragment to free.
348 static void addrindex_free_fragment( AddressIfFragment
*fragment
) {
352 node
= fragment
->children
;
354 AddressIfFragment
*child
= node
->data
;
355 addrindex_free_fragment( child
);
357 node
= g_list_next( node
);
359 g_list_free( fragment
->children
);
361 /* Free attributes */
362 node
= fragment
->attributes
;
364 AddressIfAttrib
*nv
= node
->data
;
369 node
= g_list_next( node
);
371 g_list_free( fragment
->attributes
);
373 g_free( fragment
->name
);
374 fragment
->name
= NULL
;
375 fragment
->attributes
= NULL
;
376 fragment
->children
= NULL
;
382 * Create a new data source.
383 * \param ifType Interface type to create.
384 * \return Initialized data source.
386 AddressDataSource
*addrindex_create_datasource( AddressIfType ifType
) {
387 AddressDataSource
*ds
= g_new0( AddressDataSource
, 1 );
389 ADDRITEM_TYPE(ds
) = ITEMTYPE_DATASOURCE
;
390 ADDRITEM_ID(ds
) = NULL
;
391 ADDRITEM_NAME(ds
) = NULL
;
392 ADDRITEM_PARENT(ds
) = NULL
;
393 ADDRITEM_SUBTYPE(ds
) = 0;
395 ds
->rawDataSource
= NULL
;
396 ds
->interface
= NULL
;
401 * Free up data source.
402 * \param ds Data source to free.
404 void addrindex_free_datasource( AddressDataSource
*ds
) {
405 AddressInterface
*iface
;
407 cm_return_if_fail( ds
!= NULL
);
409 iface
= ds
->interface
;
410 if( ds
->rawDataSource
!= NULL
) {
411 if( iface
!= NULL
) {
412 if( iface
->useInterface
) {
413 if( iface
->type
== ADDR_IF_BOOK
) {
414 AddressBookFile
*abf
= ds
->rawDataSource
;
415 addrbook_free_book( abf
);
417 else if( iface
->type
== ADDR_IF_VCARD
) {
418 VCardFile
*vcf
= ds
->rawDataSource
;
422 else if( iface
->type
== ADDR_IF_JPILOT
) {
423 JPilotFile
*jpf
= ds
->rawDataSource
;
428 else if( iface
->type
== ADDR_IF_LDAP
) {
429 LdapServer
*server
= ds
->rawDataSource
;
430 ldapsvr_free( server
);
437 AddressIfFragment
*fragment
= ds
->rawDataSource
;
438 addrindex_free_fragment( fragment
);
443 ADDRITEM_TYPE(ds
) = ITEMTYPE_NONE
;
444 ADDRITEM_ID(ds
) = NULL
;
445 ADDRITEM_NAME(ds
) = NULL
;
446 ADDRITEM_PARENT(ds
) = NULL
;
447 ADDRITEM_SUBTYPE(ds
) = 0;
448 ds
->type
= ADDR_IF_NONE
;
449 ds
->interface
= NULL
;
450 ds
->rawDataSource
= NULL
;
456 * Free up all data sources for specified interface.
457 * \param iface Address interface to process.
459 static void addrindex_free_all_datasources( AddressInterface
*iface
) {
460 GList
*node
= iface
->listSource
;
462 AddressDataSource
*ds
= node
->data
;
463 addrindex_free_datasource( ds
);
465 node
= g_list_next( node
);
470 * Free up specified interface.
471 * \param iface Interface to process.
473 static void addrindex_free_interface( AddressInterface
*iface
) {
474 /* Free up data sources */
475 addrindex_free_all_datasources( iface
);
476 g_list_free( iface
->listSource
);
478 /* Free internal storage */
479 g_free( ADDRITEM_ID(iface
) );
480 g_free( ADDRITEM_NAME(iface
) );
481 g_free( iface
->name
);
482 g_free( iface
->listTag
);
483 g_free( iface
->itemTag
);
485 /* Clear all pointers */
486 ADDRITEM_TYPE(iface
) = ITEMTYPE_NONE
;
487 ADDRITEM_ID(iface
) = NULL
;
488 ADDRITEM_NAME(iface
) = NULL
;
489 ADDRITEM_PARENT(iface
) = NULL
;
490 ADDRITEM_SUBTYPE(iface
) = 0;
491 iface
->type
= ADDR_IF_NONE
;
493 iface
->listTag
= NULL
;
494 iface
->itemTag
= NULL
;
495 iface
->legacyFlag
= FALSE
;
496 iface
->useInterface
= FALSE
;
497 iface
->haveLibrary
= FALSE
;
498 iface
->listSource
= NULL
;
501 iface
->searchOrder
= 0;
502 iface
->startSearch
= NULL
;
503 iface
->stopSearch
= NULL
;
509 * Return cache ID for specified data source.
511 * \param addrIndex Address index.
512 * \param ds Data source.
513 * \return ID or NULL if not found. This should be <code>g_free()</code>
516 gchar
*addrindex_get_cache_id( AddressIndex
*addrIndex
, AddressDataSource
*ds
) {
517 gchar
*cacheID
= NULL
;
518 AddrBookBase
*adbase
;
521 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
522 cm_return_val_if_fail( ds
!= NULL
, NULL
);
524 adbase
= ( AddrBookBase
* ) ds
->rawDataSource
;
526 cache
= adbase
->addressCache
;
528 cacheID
= g_strdup( cache
->cacheID
);
536 * Return reference to data source for specified cacheID.
537 * \param addrIndex Address index.
539 * \return Data source, or NULL if not found.
541 static AddressDataSource
*addrindex_get_datasource(
542 AddressIndex
*addrIndex
, const gchar
*cacheID
)
544 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
545 cm_return_val_if_fail( cacheID
!= NULL
, NULL
);
546 return ( AddressDataSource
* ) g_hash_table_lookup( addrIndex
->hashCache
, cacheID
);
550 * Return reference to address cache for specified cacheID.
551 * \param addrIndex Address index.
553 * \return Address cache, or NULL if not found.
555 AddressCache
*addrindex_get_cache( AddressIndex
*addrIndex
, const gchar
*cacheID
) {
556 AddressDataSource
*ds
;
557 AddrBookBase
*adbase
;
560 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
561 cm_return_val_if_fail( cacheID
!= NULL
, NULL
);
564 ds
= addrindex_get_datasource( addrIndex
, cacheID
);
566 adbase
= ( AddrBookBase
* ) ds
->rawDataSource
;
567 cache
= adbase
->addressCache
;
573 * Add data source into hash table.
574 * \param addrIndex Address index.
575 * \param ds Data source.
577 static void addrindex_hash_add_cache(
578 AddressIndex
*addrIndex
, AddressDataSource
*ds
)
582 cacheID
= addrindex_get_cache_id( addrIndex
, ds
);
584 g_hash_table_insert( addrIndex
->hashCache
, cacheID
, ds
);
589 * Free hash table callback function.
591 static gboolean
addrindex_free_cache_cb( gpointer key
, gpointer value
, gpointer data
) {
599 * Free hash table of address cache items.
601 static void addrindex_free_cache_hash( GHashTable
*table
) {
602 g_hash_table_foreach_remove( table
, addrindex_free_cache_cb
, NULL
);
603 g_hash_table_destroy( table
);
607 * Remove data source from internal hashtable.
608 * \param addrIndex Address index.
609 * \param ds Data source to remove.
611 static void addrindex_hash_remove_cache(
612 AddressIndex
*addrIndex
, AddressDataSource
*ds
)
616 cacheID
= addrindex_get_cache_id( addrIndex
, ds
);
618 g_hash_table_remove( addrIndex
->hashCache
, cacheID
);
625 * Create a new address index. This is created as a singleton object.
626 * \return Initialized address index object.
628 AddressIndex
*addrindex_create_index( void ) {
631 if( _addressIndex_
== NULL
) {
632 index
= g_new0( AddressIndex
, 1 );
633 ADDRITEM_TYPE(index
) = ITEMTYPE_INDEX
;
634 ADDRITEM_ID(index
) = NULL
;
635 ADDRITEM_NAME(index
) = g_strdup( "Address Index" );
636 ADDRITEM_PARENT(index
) = NULL
;
637 ADDRITEM_SUBTYPE(index
) = 0;
638 index
->filePath
= NULL
;
639 index
->fileName
= NULL
;
640 index
->retVal
= MGU_SUCCESS
;
641 index
->needsConversion
= FALSE
;
642 index
->wasConverted
= FALSE
;
643 index
->conversionError
= FALSE
;
644 index
->interfaceList
= NULL
;
645 index
->lastType
= ADDR_IF_NONE
;
646 index
->dirtyFlag
= FALSE
;
647 index
->hashCache
= g_hash_table_new( g_str_hash
, g_str_equal
);
648 index
->loadedFlag
= FALSE
;
649 index
->searchOrder
= NULL
;
650 addrindex_build_if_list( index
);
651 _addressIndex_
= index
;
653 return _addressIndex_
;
657 * Property - Specify file path to address index file.
658 * \param addrIndex Address index.
659 * \param value Path to index file.
661 void addrindex_set_file_path( AddressIndex
*addrIndex
, const gchar
*value
) {
662 cm_return_if_fail( addrIndex
!= NULL
);
663 addrIndex
->filePath
= mgu_replace_string( addrIndex
->filePath
, value
);
667 * Property - Specify file name to address index file.
668 * \param addrIndex Address index.
669 * \param value File name.
671 void addrindex_set_file_name( AddressIndex
*addrIndex
, const gchar
*value
) {
672 cm_return_if_fail( addrIndex
!= NULL
);
673 addrIndex
->fileName
= mgu_replace_string( addrIndex
->fileName
, value
);
677 * Return list of address interfaces.
678 * \param addrIndex Address index.
679 * \return List of address interfaces.
681 GList
*addrindex_get_interface_list( AddressIndex
*addrIndex
) {
682 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
683 return addrIndex
->interfaceList
;
687 * Perform any other initialization of address index.
689 void addrindex_initialize( void ) {
691 addrcompl_initialize();
695 * Perform any other teardown of address index.
697 void addrindex_teardown( void ) {
698 addrcompl_teardown();
703 * Free up address index.
704 * \param addrIndex Address index.
706 void addrindex_free_index( AddressIndex
*addrIndex
) {
709 cm_return_if_fail( addrIndex
!= NULL
);
712 g_list_free( addrIndex
->searchOrder
);
713 addrIndex
->searchOrder
= NULL
;
715 /* Free internal storage */
716 g_free( ADDRITEM_ID(addrIndex
) );
717 g_free( ADDRITEM_NAME(addrIndex
) );
718 g_free( addrIndex
->filePath
);
719 g_free( addrIndex
->fileName
);
722 ADDRITEM_TYPE(addrIndex
) = ITEMTYPE_NONE
;
723 ADDRITEM_ID(addrIndex
) = NULL
;
724 ADDRITEM_NAME(addrIndex
) = NULL
;
725 ADDRITEM_PARENT(addrIndex
) = NULL
;
726 ADDRITEM_SUBTYPE(addrIndex
) = 0;
727 addrIndex
->filePath
= NULL
;
728 addrIndex
->fileName
= NULL
;
729 addrIndex
->retVal
= MGU_SUCCESS
;
730 addrIndex
->needsConversion
= FALSE
;
731 addrIndex
->wasConverted
= FALSE
;
732 addrIndex
->conversionError
= FALSE
;
733 addrIndex
->lastType
= ADDR_IF_NONE
;
734 addrIndex
->dirtyFlag
= FALSE
;
736 /* Free up interfaces */
737 node
= addrIndex
->interfaceList
;
739 AddressInterface
*iface
= node
->data
;
740 addrindex_free_interface( iface
);
741 node
= g_list_next( node
);
743 g_list_free( addrIndex
->interfaceList
);
744 addrIndex
->interfaceList
= NULL
;
746 /* Free up hash cache */
747 addrindex_free_cache_hash( addrIndex
->hashCache
);
748 addrIndex
->hashCache
= NULL
;
750 addrIndex
->loadedFlag
= FALSE
;
754 _addressIndex_
= NULL
;
758 * Print address index.
759 * \param addrIndex Address index.
760 * \parem stream Stream to print.
762 void addrindex_print_index( AddressIndex
*addrIndex
, FILE *stream
) {
763 cm_return_if_fail( addrIndex
!= NULL
);
764 fprintf( stream
, "AddressIndex:\n" );
765 fprintf( stream
, "\tfile path: '%s'\n", addrIndex
->filePath
);
766 fprintf( stream
, "\tfile name: '%s'\n", addrIndex
->fileName
);
767 fprintf( stream
, "\t status: %d\n", addrIndex
->retVal
);
768 fprintf( stream
, "\tconverted: '%s'\n",
769 addrIndex
->wasConverted
? "yes" : "no" );
770 fprintf( stream
, "\tcvt error: '%s'\n",
771 addrIndex
->conversionError
? "yes" : "no" );
772 fprintf( stream
, "\t---\n" );
776 * Retrieve reference to address interface for specified interface type.
777 * \param addrIndex Address index.
778 * \param ifType Interface type.
779 * \return Address interface, or NULL if not found.
781 static AddressInterface
*addrindex_get_interface(
782 AddressIndex
*addrIndex
, AddressIfType ifType
)
784 AddressInterface
*retVal
= NULL
;
787 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
789 node
= addrIndex
->interfaceList
;
791 AddressInterface
*iface
= node
->data
;
792 node
= g_list_next( node
);
793 if( iface
->type
== ifType
) {
802 * Add raw data source to index. The raw data object (an AddressBookFile or
803 * VCardFile object, for example) should be supplied as the raw dataSource
806 * \param addrIndex Address index.
807 * \param ifType Interface type to add.
808 * \param dataSource Actual raw data source to add.
809 * \return Data source added, or NULL if invalid interface type.
811 AddressDataSource
*addrindex_index_add_datasource(
812 AddressIndex
*addrIndex
, AddressIfType ifType
, gpointer dataSource
)
814 AddressInterface
*iface
;
815 AddressDataSource
*ds
= NULL
;
817 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
818 cm_return_val_if_fail( dataSource
!= NULL
, NULL
);
820 iface
= addrindex_get_interface( addrIndex
, ifType
);
822 ds
= addrindex_create_datasource( ifType
);
823 ADDRITEM_PARENT(ds
) = ADDRITEM_OBJECT(iface
);
825 ds
->rawDataSource
= dataSource
;
826 ds
->interface
= iface
;
827 iface
->listSource
= g_list_append( iface
->listSource
, ds
);
828 addrIndex
->dirtyFlag
= TRUE
;
830 addrindex_hash_add_cache( addrIndex
, ds
);
836 * Remove specified data source from index.
837 * \param addrIndex Address index.
838 * \param dataSource Data source to add.
839 * \return Reference to data source if removed, or NULL if data source was not
840 * found in index. Note the this object must still be freed.
842 AddressDataSource
*addrindex_index_remove_datasource(
843 AddressIndex
*addrIndex
, AddressDataSource
*dataSource
)
845 AddressDataSource
*retVal
= FALSE
;
846 AddressInterface
*iface
;
848 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
849 cm_return_val_if_fail( dataSource
!= NULL
, NULL
);
851 iface
= addrindex_get_interface( addrIndex
, dataSource
->type
);
853 iface
->listSource
= g_list_remove( iface
->listSource
, dataSource
);
854 addrIndex
->dirtyFlag
= TRUE
;
855 dataSource
->interface
= NULL
;
857 /* Remove cache from hash table */
858 addrindex_hash_remove_cache( addrIndex
, dataSource
);
866 * Retrieve a reference to address interface for specified interface type and
867 * XML interface tag name.
868 * \param addrIndex Address index.
869 * \param tag XML interface tag name to match.
870 * \param ifType Interface type to match.
871 * \return Reference to address index, or NULL if not found in index.
873 static AddressInterface
*addrindex_tag_get_interface(
874 AddressIndex
*addrIndex
, gchar
*tag
, AddressIfType ifType
)
876 AddressInterface
*retVal
= NULL
;
877 GList
*node
= addrIndex
->interfaceList
;
880 AddressInterface
*iface
= node
->data
;
881 node
= g_list_next( node
);
883 if( strcmp( iface
->listTag
, tag
) == 0 ) {
889 if( iface
->type
== ifType
) {
899 * Retrieve a reference to address interface for specified interface type and
900 * XML datasource tag name.
901 * \param addrIndex Address index.
902 * \param ifType Interface type to match.
903 * \param tag XML datasource tag name to match.
904 * \return Reference to address index, or NULL if not found in index.
906 static AddressInterface
*addrindex_tag_get_datasource(
907 AddressIndex
*addrIndex
, AddressIfType ifType
, gchar
*tag
)
909 AddressInterface
*retVal
= NULL
;
910 GList
*node
= addrIndex
->interfaceList
;
913 AddressInterface
*iface
= node
->data
;
914 node
= g_list_next( node
);
915 if( iface
->type
== ifType
&& iface
->itemTag
) {
916 if( strcmp( iface
->itemTag
, tag
) == 0 ) {
925 /* **********************************************************************
926 * Interface XML parsing functions.
927 * ***********************************************************************
931 * Write start of XML element to file.
933 * \param lvl Indentation level.
934 * \param name Element name.
936 static int addrindex_write_elem_s( FILE *fp
, const gint lvl
, const gchar
*name
) {
938 for( i
= 0; i
< lvl
; i
++ )
939 if (fputs( " ", fp
) == EOF
)
941 if (fputs( "<", fp
) == EOF
)
943 if (fputs( name
, fp
) == EOF
)
949 * Write end of XML element to file.
951 * \param lvl Indentation level.
952 * \param name Element name.
954 static int addrindex_write_elem_e( FILE *fp
, const gint lvl
, const gchar
*name
) {
956 for( i
= 0; i
< lvl
; i
++ )
957 if (fputs( " ", fp
) == EOF
)
959 if (fputs( "</", fp
) == EOF
)
961 if (fputs( name
, fp
) == EOF
)
963 if (fputs( ">\n", fp
) == EOF
)
969 * Write XML attribute to file.
971 * \param name Attribute name.
972 * \param value Attribute value.
974 static int addrindex_write_attr( FILE *fp
, const gchar
*name
, const gchar
*value
) {
975 if (fputs( " ", fp
) == EOF
)
977 if (fputs( name
, fp
) == EOF
)
979 if (fputs( "=\"", fp
) == EOF
)
981 if (xml_file_put_escape_str( fp
, value
) < 0)
983 if (fputs( "\"", fp
) == EOF
)
988 #if !defined(USE_LDAP) || !defined(USE_JPILOT)
990 * Return DOM fragment for current XML tag from file.
991 * \param file XML file being processed.
992 * \return Fragment representing DOM fragment for configuration element.
994 static AddressIfFragment
*addrindex_read_fragment( XMLFile
*file
) {
995 AddressIfFragment
*fragment
;
996 AddressIfFragment
*child
;
1006 /* g_print( "addrindex_read_fragment\n" ); */
1008 prevLevel
= file
->level
;
1010 /* Get current tag name */
1011 xtag
= xml_get_current_tag( file
);
1013 /* Create new fragment */
1014 fragment
= g_new0( AddressIfFragment
, 1 );
1015 fragment
->name
= g_strdup( xtag
->tag
);
1016 fragment
->children
= NULL
;
1017 fragment
->attributes
= NULL
;
1019 /* Read attributes */
1021 attr
= xml_get_current_tag_attr( file
);
1023 name
= ((XMLAttr
*)attr
->data
)->name
;
1024 value
= ((XMLAttr
*)attr
->data
)->value
;
1025 nv
= g_new0( AddressIfAttrib
, 1 );
1026 nv
->name
= g_strdup( name
);
1027 nv
->value
= g_strdup( value
);
1028 list
= g_list_append( list
, nv
);
1029 attr
= g_list_next( attr
);
1031 fragment
->attributes
= list
;
1033 /* Now read the children */
1035 rc
= xml_parse_next_tag( file
);
1040 if( file
->level
< prevLevel
) {
1041 /* We must be above level we start at */
1044 child
= addrindex_read_fragment( file
);
1045 fragment
->children
= g_list_append( fragment
->children
, child
);
1052 * Write DOM fragment to file.
1053 * \param fp File to write.
1054 * \param fragment DOM fragment for configuration element.
1055 * \param lvl Indent level.
1057 static int addrindex_write_fragment(
1058 FILE *fp
, const AddressIfFragment
*fragment
, const gint lvl
)
1063 if (addrindex_write_elem_s( fp
, lvl
, fragment
->name
) < 0)
1065 node
= fragment
->attributes
;
1067 AddressIfAttrib
*nv
= node
->data
;
1068 if (addrindex_write_attr( fp
, nv
->name
, nv
->value
) < 0)
1070 node
= g_list_next( node
);
1072 if( fragment
->children
) {
1073 if (fputs(" >\n", fp
) == EOF
)
1076 /* Output children */
1077 node
= fragment
->children
;
1079 AddressIfFragment
*child
= node
->data
;
1080 if (addrindex_write_fragment( fp
, child
, 1+lvl
) < 0)
1082 node
= g_list_next( node
);
1085 /* Output closing tag */
1086 if (addrindex_write_elem_e( fp
, lvl
, fragment
->name
) < 0)
1090 if (fputs(" />\n", fp
) == EOF
)
1099 * Read/parse address index file, creating a data source for a regular
1100 * intrinsic XML addressbook.
1101 * \param file Address index file.
1102 * \return Data source.
1104 static AddressDataSource
*addrindex_parse_book( XMLFile
*file
) {
1105 AddressDataSource
*ds
;
1106 AddressBookFile
*abf
;
1109 ds
= addrindex_create_datasource( ADDR_IF_BOOK
);
1110 abf
= addrbook_create_book();
1111 attr
= xml_get_current_tag_attr( file
);
1113 gchar
*name
= ((XMLAttr
*)attr
->data
)->name
;
1114 gchar
*value
= ((XMLAttr
*)attr
->data
)->value
;
1115 if( strcmp( name
, ATTAG_BOOK_NAME
) == 0 ) {
1116 addrbook_set_name( abf
, value
);
1118 else if( strcmp( name
, ATTAG_BOOK_FILE
) == 0) {
1119 addrbook_set_file( abf
, value
);
1121 attr
= g_list_next( attr
);
1123 ds
->rawDataSource
= abf
;
1127 static int addrindex_write_book( FILE *fp
, AddressDataSource
*ds
, gint lvl
) {
1128 AddressBookFile
*abf
= ds
->rawDataSource
;
1130 if (addrindex_write_elem_s( fp
, lvl
, TAG_DS_ADDRESS_BOOK
) < 0)
1132 if (addrindex_write_attr( fp
, ATTAG_BOOK_NAME
, addrbook_get_name( abf
) ) < 0)
1134 if (addrindex_write_attr( fp
, ATTAG_BOOK_FILE
, abf
->fileName
) < 0)
1136 if (fputs( " />\n", fp
) == EOF
)
1142 static AddressDataSource
*addrindex_parse_vcard( XMLFile
*file
) {
1143 AddressDataSource
*ds
;
1147 ds
= addrindex_create_datasource( ADDR_IF_VCARD
);
1148 vcf
= vcard_create();
1149 attr
= xml_get_current_tag_attr( file
);
1151 gchar
*name
= ((XMLAttr
*)attr
->data
)->name
;
1152 gchar
*value
= ((XMLAttr
*)attr
->data
)->value
;
1153 if( strcmp( name
, ATTAG_VCARD_NAME
) == 0 ) {
1154 vcard_set_name( vcf
, value
);
1156 else if( strcmp( name
, ATTAG_VCARD_FILE
) == 0) {
1157 vcard_set_file( vcf
, value
);
1159 attr
= g_list_next( attr
);
1161 ds
->rawDataSource
= vcf
;
1165 static int addrindex_write_vcard( FILE *fp
, AddressDataSource
*ds
, gint lvl
) {
1166 VCardFile
*vcf
= ds
->rawDataSource
;
1168 if (addrindex_write_elem_s( fp
, lvl
, TAG_DS_VCARD
) < 0)
1170 if (addrindex_write_attr( fp
, ATTAG_VCARD_NAME
, vcard_get_name( vcf
) ) < 0)
1172 if (addrindex_write_attr( fp
, ATTAG_VCARD_FILE
, vcf
->path
) < 0)
1174 if (fputs( " />\n", fp
) == EOF
)
1181 static AddressDataSource
*addrindex_parse_jpilot( XMLFile
*file
) {
1182 AddressDataSource
*ds
;
1186 ds
= addrindex_create_datasource( ADDR_IF_JPILOT
);
1187 jpf
= jpilot_create();
1188 attr
= xml_get_current_tag_attr( file
);
1190 gchar
*name
= ((XMLAttr
*)attr
->data
)->name
;
1191 gchar
*value
= ((XMLAttr
*)attr
->data
)->value
;
1192 if( strcmp( name
, ATTAG_JPILOT_NAME
) == 0 ) {
1193 jpilot_set_name( jpf
, value
);
1195 else if( strcmp( name
, ATTAG_JPILOT_FILE
) == 0 ) {
1196 jpilot_set_file( jpf
, value
);
1198 else if( strcmp( name
, ATTAG_JPILOT_CUSTOM_1
) == 0 ) {
1199 jpilot_add_custom_label( jpf
, value
);
1201 else if( strcmp( name
, ATTAG_JPILOT_CUSTOM_2
) == 0 ) {
1202 jpilot_add_custom_label( jpf
, value
);
1204 else if( strcmp( name
, ATTAG_JPILOT_CUSTOM_3
) == 0 ) {
1205 jpilot_add_custom_label( jpf
, value
);
1207 else if( strcmp( name
, ATTAG_JPILOT_CUSTOM_4
) == 0 ) {
1208 jpilot_add_custom_label( jpf
, value
);
1210 attr
= g_list_next( attr
);
1212 ds
->rawDataSource
= jpf
;
1216 static int addrindex_write_jpilot( FILE *fp
,AddressDataSource
*ds
, gint lvl
) {
1217 JPilotFile
*jpf
= ds
->rawDataSource
;
1221 GList
*customLbl
= jpilot_get_custom_labels( jpf
);
1222 if (addrindex_write_elem_s( fp
, lvl
, TAG_DS_JPILOT
) < 0)
1224 if (addrindex_write_attr( fp
, ATTAG_JPILOT_NAME
, jpilot_get_name( jpf
) ) < 0)
1226 if (addrindex_write_attr( fp
, ATTAG_JPILOT_FILE
, jpf
->path
) < 0)
1232 g_snprintf( name
, sizeof(name
), "%s%d",
1233 ATTAG_JPILOT_CUSTOM
, ind
);
1234 if (addrindex_write_attr( fp
, name
, node
->data
) < 0)
1237 node
= g_list_next( node
);
1239 if (fputs( " />\n", fp
) == EOF
)
1247 * Just read/write DOM fragments (preserve data found in file).
1249 static AddressDataSource
*addrindex_parse_jpilot( XMLFile
*file
) {
1250 AddressDataSource
*ds
;
1252 ds
= addrindex_create_datasource( ADDR_IF_JPILOT
);
1253 ds
->rawDataSource
= addrindex_read_fragment( file
);
1257 static int addrindex_write_jpilot( FILE *fp
, AddressDataSource
*ds
, gint lvl
) {
1258 AddressIfFragment
*fragment
= ds
->rawDataSource
;
1260 if (addrindex_write_fragment( fp
, fragment
, lvl
) < 0)
1269 * Parse LDAP criteria attribute data from XML file.
1270 * \param file Index file.
1271 * \param ctl LDAP control object to populate.
1273 static void addrindex_parse_ldap_attrlist( XMLFile
*file
, LdapControl
*ctl
) {
1282 if( file
== NULL
) {
1287 prevLevel
= file
->level
;
1288 xtagPrev
= xml_get_current_tag( file
);
1290 rc
= xml_parse_next_tag( file
);
1292 /* Terminate prematurely */
1293 mgu_free_dlist( list
);
1297 if( file
->level
< prevLevel
) {
1298 /* We must be above level we start at */
1302 /* Get a tag (element) */
1303 xtag
= xml_get_current_tag( file
);
1304 if( strcmp( xtag
->tag
, ELTAG_LDAP_ATTR_SRCH
) == 0 ) {
1305 /* LDAP criteria attribute */
1306 attr
= xml_get_current_tag_attr( file
);
1308 gchar
*name
= ((XMLAttr
*)attr
->data
)->name
;
1309 gchar
*value
= ((XMLAttr
*)attr
->data
)->value
;
1310 if( strcmp( name
, ATTAG_LDAP_ATTR_NAME
) == 0 ) {
1311 if( value
&& strlen( value
) > 0 ) {
1312 list
= g_list_append(
1313 list
, g_strdup( value
) );
1316 attr
= g_list_next( attr
);
1320 if( xtag
!= xtagPrev
) {
1321 /* Found a new tag */
1327 /* Build list of search attributes */
1328 ldapctl_criteria_list_clear( ctl
);
1331 ldapctl_criteria_list_add( ctl
, node
->data
);
1332 g_free( node
->data
);
1334 node
= g_list_next( node
);
1336 g_list_free( list
);
1341 void ldapsvr_set_control( LdapServer
*server
, LdapControl
*ctl
);
1343 * Parse LDAP control data from XML file.
1344 * \param file Index file.
1345 * \return Initialized data soruce object.
1347 static AddressDataSource
*addrindex_parse_ldap( XMLFile
*file
) {
1348 AddressDataSource
*ds
;
1352 gchar
*serverName
= NULL
;
1353 gchar
*criteria
= NULL
;
1354 gboolean bDynSearch
;
1355 gboolean bTLS
, bSSL
;
1357 gchar
*password
= NULL
;
1359 /* g_print( "addrindex_parse_ldap\n" ); */
1360 /* Set up some defaults */
1364 iMatch
= LDAPCTL_MATCH_BEGINWITH
;
1366 ds
= addrindex_create_datasource( ADDR_IF_LDAP
);
1367 ctl
= ldapctl_create();
1368 attr
= xml_get_current_tag_attr( file
);
1370 gchar
*name
= ((XMLAttr
*)attr
->data
)->name
;
1371 gchar
*value
= ((XMLAttr
*)attr
->data
)->value
;
1372 gint ivalue
= atoi( value
);
1374 if( strcmp( name
, ATTAG_LDAP_NAME
) == 0 ) {
1375 g_free( serverName
);
1376 serverName
= g_strdup( value
);
1378 else if( strcmp( name
, ATTAG_LDAP_HOST
) == 0 ) {
1379 ldapctl_set_host( ctl
, value
);
1381 else if( strcmp( name
, ATTAG_LDAP_PORT
) == 0 ) {
1382 ldapctl_set_port( ctl
, ivalue
);
1384 else if( strcmp( name
, ATTAG_LDAP_BASE_DN
) == 0 ) {
1385 ldapctl_set_base_dn( ctl
, value
);
1387 else if( strcmp( name
, ATTAG_LDAP_BIND_DN
) == 0 ) {
1388 ldapctl_set_bind_dn( ctl
, value
);
1390 else if( strcmp( name
, ATTAG_LDAP_BIND_PASS
) == 0 ) {
1393 else if( strcmp( name
, ATTAG_LDAP_CRITERIA
) == 0 ) {
1395 criteria
= g_strdup( value
);
1396 g_print("criteria %s\n", criteria
);
1398 else if( strcmp( name
, ATTAG_LDAP_MAX_ENTRY
) == 0 ) {
1399 ldapctl_set_max_entries( ctl
, ivalue
);
1401 else if( strcmp( name
, ATTAG_LDAP_TIMEOUT
) == 0 ) {
1402 ldapctl_set_timeout( ctl
, ivalue
);
1404 else if( strcmp( name
, ATTAG_LDAP_MAX_AGE
) == 0 ) {
1405 ldapctl_set_max_query_age( ctl
, ivalue
);
1407 else if( strcmp( name
, ATTAG_LDAP_DYN_SEARCH
) == 0 ) {
1409 if( strcmp( value
, ATVAL_BOOLEAN_YES
) == 0 ) {
1413 else if( strcmp( name
, ATTAG_LDAP_MATCH_OPT
) == 0 ) {
1414 iMatch
= LDAPCTL_MATCH_BEGINWITH
;
1415 if( strcmp( value
, ATVAL_LDAP_MATCH_CONTAINS
) == 0 ) {
1416 iMatch
= LDAPCTL_MATCH_CONTAINS
;
1419 else if( strcmp( name
, ATTAG_LDAP_ENABLE_TLS
) == 0 ) {
1421 if( strcmp( value
, ATVAL_BOOLEAN_YES
) == 0 ) {
1425 else if( strcmp( name
, ATTAG_LDAP_ENABLE_SSL
) == 0 ) {
1427 if( strcmp( value
, ATVAL_BOOLEAN_YES
) == 0 ) {
1431 attr
= g_list_next( attr
);
1434 if (password
!= NULL
)
1435 passwd_store_set(PWS_CORE
, "LDAP", ctl
->hostName
, password
, TRUE
);
1437 server
= ldapsvr_create_noctl();
1438 ldapsvr_set_name( server
, serverName
);
1439 ldapsvr_set_search_flag( server
, bDynSearch
);
1440 ldapctl_set_matching_option( ctl
, iMatch
);
1441 ldapctl_set_tls( ctl
, bTLS
);
1442 ldapctl_set_ssl( ctl
, bSSL
);
1443 g_free( serverName
);
1444 ldapsvr_set_control( server
, ctl
);
1445 ds
->rawDataSource
= server
;
1447 addrindex_parse_ldap_attrlist( file
, ctl
);
1449 * If criteria have been specified and no attributes were listed, then
1450 * convert old style criteria into an attribute list. Any criteria will
1451 * be dropped when saving data.
1454 if( ! ldapctl_get_criteria_list( ctl
) ) {
1455 ldapctl_parse_ldap_search( ctl
, criteria
);
1459 /* ldapsvr_print_data( server, stdout ); */
1464 static int addrindex_write_ldap( FILE *fp
, AddressDataSource
*ds
, gint lvl
) {
1465 LdapServer
*server
= ds
->rawDataSource
;
1466 LdapControl
*ctl
= NULL
;
1471 ctl
= server
->control
;
1473 if( ctl
== NULL
) return 0;
1475 /* Output start element with attributes */
1476 if (addrindex_write_elem_s( fp
, lvl
, TAG_DS_LDAP
) < 0)
1478 if (addrindex_write_attr( fp
, ATTAG_LDAP_NAME
, ldapsvr_get_name( server
) ) < 0)
1480 if (addrindex_write_attr( fp
, ATTAG_LDAP_HOST
, ctl
->hostName
) < 0)
1483 sprintf( value
, "%d", ctl
->port
);
1484 if (addrindex_write_attr( fp
, ATTAG_LDAP_PORT
, value
) < 0)
1487 if (addrindex_write_attr( fp
, ATTAG_LDAP_BASE_DN
, ctl
->baseDN
) < 0)
1489 if (addrindex_write_attr( fp
, ATTAG_LDAP_BIND_DN
, ctl
->bindDN
) < 0)
1492 sprintf( value
, "%d", ctl
->maxEntries
);
1493 if (addrindex_write_attr( fp
, ATTAG_LDAP_MAX_ENTRY
, value
) < 0)
1495 sprintf( value
, "%d", ctl
->timeOut
);
1496 if (addrindex_write_attr( fp
, ATTAG_LDAP_TIMEOUT
, value
) < 0)
1498 sprintf( value
, "%d", ctl
->maxQueryAge
);
1499 if (addrindex_write_attr( fp
, ATTAG_LDAP_MAX_AGE
, value
) < 0)
1502 if (addrindex_write_attr( fp
, ATTAG_LDAP_DYN_SEARCH
,
1503 server
->searchFlag
?
1504 ATVAL_BOOLEAN_YES
: ATVAL_BOOLEAN_NO
) < 0)
1507 if (addrindex_write_attr( fp
, ATTAG_LDAP_MATCH_OPT
,
1508 ( ctl
->matchingOption
== LDAPCTL_MATCH_CONTAINS
) ?
1509 ATVAL_LDAP_MATCH_CONTAINS
: ATVAL_LDAP_MATCH_BEGIN
) < 0)
1512 if (addrindex_write_attr( fp
, ATTAG_LDAP_ENABLE_TLS
,
1514 ATVAL_BOOLEAN_YES
: ATVAL_BOOLEAN_NO
) < 0)
1516 if (addrindex_write_attr( fp
, ATTAG_LDAP_ENABLE_SSL
,
1518 ATVAL_BOOLEAN_YES
: ATVAL_BOOLEAN_NO
) < 0)
1521 if (fputs(" >\n", fp
) == EOF
)
1524 /* Output attributes */
1525 node
= ldapctl_get_criteria_list( ctl
);
1527 if (addrindex_write_elem_s( fp
, 1+lvl
, ELTAG_LDAP_ATTR_SRCH
) < 0)
1529 if (addrindex_write_attr( fp
, ATTAG_LDAP_ATTR_NAME
, node
->data
) < 0)
1531 if (fputs(" />\n", fp
) == EOF
)
1533 node
= g_list_next( node
);
1536 /* End of element */
1537 if (addrindex_write_elem_e( fp
, lvl
, TAG_DS_LDAP
) < 0)
1545 * Just read/write DOM fragments (preserve data found in file).
1547 static AddressDataSource
*addrindex_parse_ldap( XMLFile
*file
) {
1548 AddressDataSource
*ds
;
1550 ds
= addrindex_create_datasource( ADDR_IF_LDAP
);
1551 ds
->rawDataSource
= addrindex_read_fragment( file
);
1555 static int addrindex_write_ldap( FILE *fp
, AddressDataSource
*ds
, gint lvl
) {
1556 AddressIfFragment
*fragment
= ds
->rawDataSource
;
1558 if (addrindex_write_fragment( fp
, fragment
, lvl
) < 0)
1565 /* **********************************************************************
1566 * Address index I/O functions.
1567 * ***********************************************************************
1570 * Read address index file, creating appropriate data sources for each address
1573 * \param addrIndex Address index.
1574 * \param file Address index file.
1576 static void addrindex_read_index( AddressIndex
*addrIndex
, XMLFile
*file
) {
1578 AddressInterface
*iface
= NULL
, *dsIFace
= NULL
;
1579 AddressDataSource
*ds
;
1582 addrIndex
->loadedFlag
= FALSE
;
1584 rc
= xml_parse_next_tag( file
);
1585 if( rc
< 0 || file
->level
== 0 ) return;
1587 xtag
= xml_get_current_tag( file
);
1589 iface
= addrindex_tag_get_interface( addrIndex
, xtag
->tag
, ADDR_IF_NONE
);
1591 addrIndex
->lastType
= iface
->type
;
1592 if( iface
->legacyFlag
) addrIndex
->needsConversion
= TRUE
;
1595 dsIFace
= addrindex_tag_get_datasource(
1596 addrIndex
, addrIndex
->lastType
, xtag
->tag
);
1598 /* Add data source to list */
1600 if( addrIndex
->lastType
== ADDR_IF_BOOK
) {
1601 ds
= addrindex_parse_book( file
);
1602 if( ds
->rawDataSource
) {
1603 addrbook_set_path( ds
->rawDataSource
,
1604 addrIndex
->filePath
);
1607 else if( addrIndex
->lastType
== ADDR_IF_VCARD
) {
1608 ds
= addrindex_parse_vcard( file
);
1610 else if( addrIndex
->lastType
== ADDR_IF_JPILOT
) {
1611 ds
= addrindex_parse_jpilot( file
);
1613 else if( addrIndex
->lastType
== ADDR_IF_LDAP
) {
1614 ds
= addrindex_parse_ldap( file
);
1617 ds
->interface
= dsIFace
;
1618 addrindex_hash_add_cache( addrIndex
, ds
);
1619 dsIFace
->listSource
=
1620 g_list_append( dsIFace
->listSource
, ds
);
1628 * Search order sorting comparison function for building search order list.
1630 static gint
addrindex_search_order_compare( gconstpointer ptrA
, gconstpointer ptrB
) {
1631 AddressInterface
*ifaceA
= ( AddressInterface
* ) ptrA
;
1632 AddressInterface
*ifaceB
= ( AddressInterface
* ) ptrB
;
1634 return ifaceA
->searchOrder
- ifaceB
->searchOrder
;
1638 * Build list of data sources to process.
1639 * \param addrIndex Address index object.
1641 static void addrindex_build_search_order( AddressIndex
*addrIndex
) {
1644 /* Clear existing list */
1645 g_list_free( addrIndex
->searchOrder
);
1646 addrIndex
->searchOrder
= NULL
;
1648 /* Build new list */
1649 nodeIf
= addrIndex
->interfaceList
;
1651 AddressInterface
*iface
= nodeIf
->data
;
1652 if( iface
->useInterface
) {
1653 if( iface
->searchOrder
> 0 ) {
1654 /* Add to search order list */
1655 addrIndex
->searchOrder
= g_list_insert_sorted(
1656 addrIndex
->searchOrder
, iface
,
1657 addrindex_search_order_compare
);
1660 nodeIf
= g_list_next( nodeIf
);
1664 static gint
addrindex_read_file( AddressIndex
*addrIndex
) {
1665 XMLFile
*file
= NULL
;
1666 gchar
*fileSpec
= NULL
;
1668 cm_return_val_if_fail( addrIndex
!= NULL
, -1 );
1670 fileSpec
= g_strconcat( addrIndex
->filePath
, G_DIR_SEPARATOR_S
, addrIndex
->fileName
, NULL
);
1671 addrIndex
->retVal
= MGU_NO_FILE
;
1672 file
= xml_open_file( fileSpec
);
1675 if( file
== NULL
) {
1677 g_print( " file '%s' does not exist.\n", addrIndex->fileName );
1679 return addrIndex
->retVal
;
1682 addrIndex
->retVal
= MGU_BAD_FORMAT
;
1683 if( xml_get_dtd( file
) == 0 ) {
1684 if( xml_parse_next_tag( file
) == 0 ) {
1685 if( xml_compare_tag( file
, TAG_ADDRESS_INDEX
) ) {
1686 addrindex_read_index( addrIndex
, file
);
1687 addrIndex
->retVal
= MGU_SUCCESS
;
1691 xml_close_file( file
);
1693 addrindex_build_search_order( addrIndex
);
1695 return addrIndex
->retVal
;
1698 static int addrindex_write_index( AddressIndex
*addrIndex
, FILE *fp
) {
1699 GList
*nodeIF
, *nodeDS
;
1701 gint lvlItem
= 1 + lvlList
;
1703 nodeIF
= addrIndex
->interfaceList
;
1705 AddressInterface
*iface
= nodeIF
->data
;
1706 if( ! iface
->legacyFlag
) {
1707 nodeDS
= iface
->listSource
;
1708 if (addrindex_write_elem_s( fp
, lvlList
, iface
->listTag
) < 0)
1710 if (fputs( ">\n", fp
) == EOF
)
1713 AddressDataSource
*ds
= nodeDS
->data
;
1715 if( iface
->type
== ADDR_IF_BOOK
) {
1716 if (addrindex_write_book( fp
, ds
, lvlItem
) < 0)
1719 if( iface
->type
== ADDR_IF_VCARD
) {
1720 if (addrindex_write_vcard( fp
, ds
, lvlItem
) < 0)
1723 if( iface
->type
== ADDR_IF_JPILOT
) {
1724 if (addrindex_write_jpilot( fp
, ds
, lvlItem
) < 0)
1727 if( iface
->type
== ADDR_IF_LDAP
) {
1728 if (addrindex_write_ldap( fp
, ds
, lvlItem
) < 0)
1732 nodeDS
= g_list_next( nodeDS
);
1734 if (addrindex_write_elem_e( fp
, lvlList
, iface
->listTag
) < 0)
1737 nodeIF
= g_list_next( nodeIF
);
1743 * Write data to specified file.
1744 * Enter: addrIndex Address index object.
1745 * newFile New file name.
1746 * return: Status code, from addrIndex->retVal.
1747 * Note: File will be created in directory specified by addrIndex.
1749 static gint
addrindex_write_to( AddressIndex
*addrIndex
, const gchar
*newFile
) {
1752 #ifndef DEV_STANDALONE
1756 cm_return_val_if_fail( addrIndex
!= NULL
, -1 );
1758 fileSpec
= g_strconcat( addrIndex
->filePath
, G_DIR_SEPARATOR_S
, newFile
, NULL
);
1759 addrIndex
->retVal
= MGU_OPEN_FILE
;
1760 #ifdef DEV_STANDALONE
1761 fp
= g_fopen( fileSpec
, "wb" );
1764 fputs( "<?xml version=\"1.0\" ?>\n", fp
);
1766 pfile
= prefs_write_open( fileSpec
);
1770 if (fprintf( fp
, "<?xml version=\"1.0\" encoding=\"%s\" ?>\n", CS_INTERNAL
) < 0)
1773 if (addrindex_write_elem_s( fp
, 0, TAG_ADDRESS_INDEX
) < 0)
1775 if (fputs( ">\n", fp
) == EOF
)
1778 if (addrindex_write_index( addrIndex
, fp
) < 0)
1780 if (addrindex_write_elem_e( fp
, 0, TAG_ADDRESS_INDEX
) < 0)
1783 addrIndex
->retVal
= MGU_SUCCESS
;
1784 #ifdef DEV_STANDALONE
1787 if( prefs_file_close( pfile
) < 0 ) {
1788 addrIndex
->retVal
= MGU_ERROR_WRITE
;
1794 return addrIndex
->retVal
;
1796 g_warning("error writing AB index");
1797 addrIndex
->retVal
= MGU_ERROR_WRITE
;
1799 prefs_file_close_revert( pfile
);
1800 return addrIndex
->retVal
;
1804 * Save address index data to original file.
1805 * return: Status code, from addrIndex->retVal.
1807 gint
addrindex_save_data( AddressIndex
*addrIndex
) {
1813 cm_return_val_if_fail( addrIndex
!= NULL
, -1 );
1816 nodeIf
= addrIndex
->interfaceList
;
1817 /* save LDAP interfaces */
1819 AddressInterface
*iface
= nodeIf
->data
;
1820 if( iface
->type
== ADDR_IF_LDAP
) {
1821 nodeDS
= iface
->listSource
;
1823 AddressDataSource
*ds
= nodeDS
->data
;
1824 LdapServer
*abf
= ds
->rawDataSource
;
1825 if( ldapsvr_get_read_flag( abf
) ) {
1826 if( ldapsvr_get_modified( abf
) ) {
1827 ldapsvr_update_book( abf
, NULL
);
1828 if( abf
->retVal
!= LDAPRC_SUCCESS
) {
1829 alertpanel( _("Address(es) update"),
1830 _("Update failed. Changes not written to Directory."),
1831 GTK_STOCK_CLOSE
, NULL
, NULL
);
1834 abf
->retVal
= MGU_SUCCESS
;
1835 ldapsvr_set_modified( abf
, FALSE
);
1839 nodeDS
= g_list_next( nodeDS
);
1843 nodeIf
= g_list_next( nodeIf
);
1846 addrIndex
->retVal
= MGU_NO_FILE
;
1847 if( addrIndex
->fileName
== NULL
|| *addrIndex
->fileName
== '\0' ) return addrIndex
->retVal
;
1848 if( addrIndex
->filePath
== NULL
|| *addrIndex
->filePath
== '\0' ) return addrIndex
->retVal
;
1850 addrindex_write_to( addrIndex
, addrIndex
->fileName
);
1851 if( addrIndex
->retVal
== MGU_SUCCESS
) {
1852 addrIndex
->dirtyFlag
= FALSE
;
1854 return addrIndex
->retVal
;
1858 * Save all address book files which may have changed.
1859 * Return: Status code, set if there was a problem saving data.
1861 gint
addrindex_save_all_books( AddressIndex
*addrIndex
) {
1862 gint retVal
= MGU_SUCCESS
;
1863 GList
*nodeIf
, *nodeDS
;
1865 nodeIf
= addrIndex
->interfaceList
;
1867 AddressInterface
*iface
= nodeIf
->data
;
1868 if( iface
->type
== ADDR_IF_BOOK
) {
1869 nodeDS
= iface
->listSource
;
1871 AddressDataSource
*ds
= nodeDS
->data
;
1872 AddressBookFile
*abf
= ds
->rawDataSource
;
1873 if( addrbook_get_dirty( abf
) ) {
1874 if( addrbook_get_read_flag( abf
) ) {
1875 addrbook_save_data( abf
);
1876 if( abf
->retVal
!= MGU_SUCCESS
) {
1877 retVal
= abf
->retVal
;
1881 nodeDS
= g_list_next( nodeDS
);
1885 nodeIf
= g_list_next( nodeIf
);
1891 /* **********************************************************************
1892 * Address book conversion to new format.
1893 * ***********************************************************************
1896 #define ELTAG_IF_OLD_FOLDER "folder"
1897 #define ELTAG_IF_OLD_GROUP "group"
1898 #define ELTAG_IF_OLD_ITEM "item"
1899 #define ELTAG_IF_OLD_NAME "name"
1900 #define ELTAG_IF_OLD_ADDRESS "address"
1901 #define ELTAG_IF_OLD_REMARKS "remarks"
1902 #define ATTAG_IF_OLD_NAME "name"
1904 #define TEMPNODE_ROOT 0
1905 #define TEMPNODE_FOLDER 1
1906 #define TEMPNODE_GROUP 2
1907 #define TEMPNODE_ADDRESS 3
1909 typedef struct _AddressCvt_Node AddressCvtNode
;
1910 struct _AddressCvt_Node
{
1919 * Parse current address item.
1921 static AddressCvtNode
*addrindex_parse_item( XMLFile
*file
) {
1926 nn
= g_new0( AddressCvtNode
, 1 );
1927 nn
->type
= TEMPNODE_ADDRESS
;
1930 level
= file
->level
;
1933 xml_parse_next_tag(file
);
1934 if (file
->level
< level
) return nn
;
1936 element
= xml_get_element( file
);
1937 if( xml_compare_tag( file
, ELTAG_IF_OLD_NAME
) ) {
1938 nn
->name
= g_strdup( element
);
1940 if( xml_compare_tag( file
, ELTAG_IF_OLD_ADDRESS
) ) {
1941 nn
->address
= g_strdup( element
);
1943 if( xml_compare_tag( file
, ELTAG_IF_OLD_REMARKS
) ) {
1944 nn
->remarks
= g_strdup( element
);
1947 xml_parse_next_tag(file
);
1952 * Create a temporary node below specified node.
1954 static AddressCvtNode
*addrindex_add_object( AddressCvtNode
*node
, gint type
, gchar
*name
, gchar
*addr
, char *rem
) {
1956 nn
= g_new0( AddressCvtNode
, 1 );
1958 nn
->name
= g_strdup( name
);
1959 nn
->remarks
= g_strdup( rem
);
1960 node
->list
= g_list_append( node
->list
, nn
);
1965 * Process current temporary node.
1967 static void addrindex_add_obj( XMLFile
*file
, AddressCvtNode
*node
) {
1970 AddressCvtNode
*newNode
= NULL
;
1975 prev_level
= file
->level
;
1976 xml_parse_next_tag( file
);
1977 if (file
->level
< prev_level
) return;
1981 if( xml_compare_tag( file
, ELTAG_IF_OLD_GROUP
) ) {
1982 attr
= xml_get_current_tag_attr(file
);
1984 name
= ((XMLAttr
*)attr
->data
)->name
;
1985 if( strcmp( name
, ATTAG_IF_OLD_NAME
) == 0 ) {
1986 value
= ((XMLAttr
*)attr
->data
)->value
;
1989 newNode
= addrindex_add_object( node
, TEMPNODE_GROUP
, value
, "", "" );
1990 addrindex_add_obj( file
, newNode
);
1993 else if( xml_compare_tag( file
, ELTAG_IF_OLD_FOLDER
) ) {
1994 attr
= xml_get_current_tag_attr(file
);
1996 name
= ((XMLAttr
*)attr
->data
)->name
;
1997 if( strcmp( name
, ATTAG_IF_OLD_NAME
) == 0 ) {
1998 value
= ((XMLAttr
*)attr
->data
)->value
;
2001 newNode
= addrindex_add_object( node
, TEMPNODE_FOLDER
, value
, "", "" );
2002 addrindex_add_obj( file
, newNode
);
2004 else if( xml_compare_tag( file
, ELTAG_IF_OLD_ITEM
) ) {
2005 newNode
= addrindex_parse_item( file
);
2006 node
->list
= g_list_append( node
->list
, newNode
);
2009 g_warning("Invalid tag");
2015 * Consume all nodes below current tag.
2017 static void addrindex_consume_tree( XMLFile
*file
) {
2021 prev_level
= file
->level
;
2022 xml_parse_next_tag( file
);
2023 if (file
->level
< prev_level
)
2026 addrindex_consume_tree( file
);
2031 * Free up temporary tree.
2033 static void addrindex_free_node( AddressCvtNode
*node
) {
2034 GList
*list
= node
->list
;
2037 AddressCvtNode
*lNode
= list
->data
;
2038 list
= g_list_next( list
);
2039 addrindex_free_node( lNode
);
2041 node
->type
= TEMPNODE_ROOT
;
2042 g_free( node
->name
);
2043 g_free( node
->address
);
2044 g_free( node
->remarks
);
2045 g_list_free( node
->list
);
2050 * Process address book for specified node.
2052 static void addrindex_process_node(
2053 AddressBookFile
*abf
, AddressCvtNode
*node
, ItemFolder
*parent
,
2054 ItemGroup
*parentGrp
, ItemFolder
*folderGrp
)
2057 ItemFolder
*itemFolder
= NULL
;
2058 ItemGroup
*itemGParent
= parentGrp
;
2059 ItemFolder
*itemGFolder
= folderGrp
;
2060 AddressCache
*cache
= abf
->addressCache
;
2062 if( node
->type
== TEMPNODE_ROOT
) {
2063 itemFolder
= parent
;
2065 else if( node
->type
== TEMPNODE_FOLDER
) {
2066 itemFolder
= addritem_create_item_folder();
2067 addritem_folder_set_name( itemFolder
, node
->name
);
2068 addrcache_id_folder( cache
, itemFolder
);
2069 addrcache_folder_add_folder( cache
, parent
, itemFolder
);
2072 else if( node
->type
== TEMPNODE_GROUP
) {
2073 ItemGroup
*itemGroup
;
2076 /* Create a folder for group */
2077 fName
= g_strdup_printf( "Cvt - %s", node
->name
);
2078 itemGFolder
= addritem_create_item_folder();
2079 addritem_folder_set_name( itemGFolder
, fName
);
2080 addrcache_id_folder( cache
, itemGFolder
);
2081 addrcache_folder_add_folder( cache
, parent
, itemGFolder
);
2084 /* Add group into folder */
2085 itemGroup
= addritem_create_item_group();
2086 addritem_group_set_name( itemGroup
, node
->name
);
2087 addrcache_id_group( cache
, itemGroup
);
2088 addrcache_folder_add_group( cache
, itemGFolder
, itemGroup
);
2089 itemGParent
= itemGroup
;
2091 else if( node
->type
== TEMPNODE_ADDRESS
) {
2092 ItemPerson
*itemPerson
;
2093 ItemEMail
*itemEMail
;
2095 /* Create person and email objects */
2096 itemPerson
= addritem_create_item_person();
2097 addritem_person_set_common_name( itemPerson
, node
->name
);
2098 addrcache_id_person( cache
, itemPerson
);
2099 itemEMail
= addritem_create_item_email();
2100 addritem_email_set_address( itemEMail
, node
->address
);
2101 addritem_email_set_remarks( itemEMail
, node
->remarks
);
2102 addrcache_id_email( cache
, itemEMail
);
2103 addrcache_person_add_email( cache
, itemPerson
, itemEMail
);
2105 /* Add person into appropriate folder */
2107 addrcache_folder_add_person( cache
, itemGFolder
, itemPerson
);
2110 addrcache_folder_add_person( cache
, parent
, itemPerson
);
2113 /* Add email address only into group */
2115 addrcache_group_add_email( cache
, parentGrp
, itemEMail
);
2121 AddressCvtNode
*lNode
= list
->data
;
2122 list
= g_list_next( list
);
2123 addrindex_process_node( abf
, lNode
, itemFolder
, itemGParent
, itemGFolder
);
2128 * Process address book to specified file number.
2130 static gboolean
addrindex_process_book( AddressIndex
*addrIndex
, XMLFile
*file
, gchar
*displayName
) {
2131 gboolean retVal
= FALSE
;
2132 AddressBookFile
*abf
= NULL
;
2133 AddressCvtNode
*rootNode
= NULL
;
2134 gchar
*newFile
= NULL
;
2135 GList
*fileList
= NULL
;
2138 /* Setup root node */
2139 rootNode
= g_new0( AddressCvtNode
, 1 );
2140 rootNode
->type
= TEMPNODE_ROOT
;
2141 rootNode
->name
= g_strdup( "root" );
2142 rootNode
->list
= NULL
;
2143 addrindex_add_obj( file
, rootNode
);
2144 /* addrindex_print_node( rootNode, stdout ); */
2146 /* Create new address book */
2147 abf
= addrbook_create_book();
2148 addrbook_set_name( abf
, displayName
);
2149 addrbook_set_path( abf
, addrIndex
->filePath
);
2151 /* Determine next available file number */
2152 fileList
= addrbook_get_bookfile_list( abf
);
2154 fileNum
= 1 + abf
->maxValue
;
2156 g_list_free( fileList
);
2159 newFile
= addrbook_gen_new_file_name( fileNum
);
2161 addrbook_set_file( abf
, newFile
);
2164 addrindex_process_node( abf
, rootNode
, abf
->addressCache
->rootFolder
, NULL
, NULL
);
2166 /* addrbook_dump_book( abf, stdout ); */
2167 addrbook_save_data( abf
);
2168 addrIndex
->retVal
= abf
->retVal
;
2169 if( abf
->retVal
== MGU_SUCCESS
) retVal
= TRUE
;
2171 addrbook_free_book( abf
);
2173 addrindex_free_node( rootNode
);
2176 /* Create entries in address index */
2178 abf
= addrbook_create_book();
2179 addrbook_set_name( abf
, displayName
);
2180 addrbook_set_path( abf
, addrIndex
->filePath
);
2181 addrbook_set_file( abf
, newFile
);
2182 addrindex_index_add_datasource( addrIndex
, ADDR_IF_BOOK
, abf
);
2189 * Process tree converting data.
2191 static void addrindex_convert_tree( AddressIndex
*addrIndex
, XMLFile
*file
) {
2197 prev_level
= file
->level
;
2198 xml_parse_next_tag( file
);
2199 if (file
->level
< prev_level
) return;
2201 xtag
= xml_get_current_tag( file
);
2202 /* g_print( "tag : %d : %s\n", prev_level, xtag->tag ); */
2203 if( strcmp( xtag
->tag
, TAG_IF_OLD_COMMON
) == 0 ) {
2204 if( addrindex_process_book( addrIndex
, file
, DISP_OLD_COMMON
) ) {
2205 addrIndex
->needsConversion
= FALSE
;
2206 addrIndex
->wasConverted
= TRUE
;
2211 if( strcmp( xtag
->tag
, TAG_IF_OLD_PERSONAL
) == 0 ) {
2212 if( addrindex_process_book( addrIndex
, file
, DISP_OLD_PERSONAL
) ) {
2213 addrIndex
->needsConversion
= FALSE
;
2214 addrIndex
->wasConverted
= TRUE
;
2219 addrindex_consume_tree( file
);
2223 static gint
addrindex_convert_data( AddressIndex
*addrIndex
) {
2224 XMLFile
*file
= NULL
;
2227 fileSpec
= g_strconcat( addrIndex
->filePath
, G_DIR_SEPARATOR_S
, addrIndex
->fileName
, NULL
);
2228 addrIndex
->retVal
= MGU_NO_FILE
;
2229 file
= xml_open_file( fileSpec
);
2232 if( file
== NULL
) {
2233 /* g_print( " file '%s' does not exist.\n", addrIndex->fileName ); */
2234 return addrIndex
->retVal
;
2237 addrIndex
->retVal
= MGU_BAD_FORMAT
;
2238 if( xml_get_dtd( file
) == 0 ) {
2239 if( xml_parse_next_tag( file
) == 0 ) {
2240 if( xml_compare_tag( file
, TAG_ADDRESS_INDEX
) ) {
2241 addrindex_convert_tree( addrIndex
, file
);
2245 xml_close_file( file
);
2246 return addrIndex
->retVal
;
2250 * Create a new address book file.
2252 static gboolean
addrindex_create_new_book( AddressIndex
*addrIndex
, gchar
*displayName
) {
2253 gboolean retVal
= FALSE
;
2254 AddressBookFile
*abf
= NULL
;
2255 gchar
*newFile
= NULL
;
2256 GList
*fileList
= NULL
;
2259 /* Create new address book */
2260 abf
= addrbook_create_book();
2261 addrbook_set_name( abf
, displayName
);
2262 addrbook_set_path( abf
, addrIndex
->filePath
);
2264 /* Determine next available file number */
2265 fileList
= addrbook_get_bookfile_list( abf
);
2267 fileNum
= 1 + abf
->maxValue
;
2269 g_list_free( fileList
);
2272 newFile
= addrbook_gen_new_file_name( fileNum
);
2274 addrbook_set_file( abf
, newFile
);
2277 addrbook_save_data( abf
);
2278 addrIndex
->retVal
= abf
->retVal
;
2279 if( abf
->retVal
== MGU_SUCCESS
) retVal
= TRUE
;
2280 addrbook_free_book( abf
);
2283 /* Create entries in address index */
2285 abf
= addrbook_create_book();
2286 addrbook_set_name( abf
, displayName
);
2287 addrbook_set_path( abf
, addrIndex
->filePath
);
2288 addrbook_set_file( abf
, newFile
);
2289 addrindex_index_add_datasource( addrIndex
, ADDR_IF_BOOK
, abf
);
2296 * Read data for address index performing a conversion if necesary.
2297 * Enter: addrIndex Address index object.
2298 * return: Status code, from addrIndex->retVal.
2299 * Note: New address book files will be created in directory specified by
2300 * addrIndex. Three files will be created, for the following:
2301 * "Common addresses"
2302 * "Personal addresses"
2303 * "Gathered addresses" - a new address book.
2305 gint
addrindex_read_data( AddressIndex
*addrIndex
) {
2306 cm_return_val_if_fail( addrIndex
!= NULL
, -1 );
2308 addrIndex
->conversionError
= FALSE
;
2309 addrindex_read_file( addrIndex
);
2310 if( addrIndex
->retVal
== MGU_SUCCESS
) {
2311 if( addrIndex
->needsConversion
) {
2312 if( addrindex_convert_data( addrIndex
) == MGU_SUCCESS
)
2313 addrIndex
->conversionError
= FALSE
;
2315 addrIndex
->conversionError
= TRUE
;
2317 addrIndex
->dirtyFlag
= TRUE
;
2319 return addrIndex
->retVal
;
2323 * Create new address books for a new address index.
2324 * Enter: addrIndex Address index object.
2325 * return: Status code, from addrIndex->retVal.
2326 * Note: New address book files will be created in directory specified by
2327 * addrIndex. Three files will be created, for the following:
2328 * "Common addresses"
2329 * "Personal addresses"
2330 * "Gathered addresses" - a new address book.
2332 gint
addrindex_create_new_books( AddressIndex
*addrIndex
) {
2335 cm_return_val_if_fail( addrIndex
!= NULL
, -1 );
2337 flg
= addrindex_create_new_book( addrIndex
, DISP_NEW_COMMON
);
2339 flg
= addrindex_create_new_book( addrIndex
, DISP_NEW_PERSONAL
);
2340 addrIndex
->dirtyFlag
= TRUE
;
2342 return addrIndex
->retVal
;
2345 /* **********************************************************************
2346 * New interface stuff.
2347 * ***********************************************************************
2351 * Return modified flag for specified data source.
2353 gboolean
addrindex_ds_get_modify_flag( AddressDataSource
*ds
) {
2354 gboolean retVal
= FALSE
;
2355 AddressInterface
*iface
;
2357 if( ds
== NULL
) return retVal
;
2358 iface
= ds
->interface
;
2359 if( iface
== NULL
) return retVal
;
2360 if( iface
->getModifyFlag
) {
2361 retVal
= ( iface
->getModifyFlag
) ( ds
->rawDataSource
);
2367 * Return accessed flag for specified data source.
2369 gboolean
addrindex_ds_get_access_flag( AddressDataSource
*ds
) {
2370 gboolean retVal
= FALSE
;
2371 AddressInterface
*iface
;
2373 if( ds
== NULL
) return retVal
;
2374 iface
= ds
->interface
;
2375 if( iface
== NULL
) return retVal
;
2376 if( iface
->getAccessFlag
) {
2377 retVal
= ( iface
->getAccessFlag
) ( ds
->rawDataSource
);
2383 * Return data read flag for specified data source.
2385 gboolean
addrindex_ds_get_read_flag( AddressDataSource
*ds
) {
2386 gboolean retVal
= TRUE
;
2387 AddressInterface
*iface
;
2389 if( ds
== NULL
) return retVal
;
2390 iface
= ds
->interface
;
2391 if( iface
== NULL
) return retVal
;
2392 if( iface
->getReadFlag
) {
2393 retVal
= ( iface
->getReadFlag
) ( ds
->rawDataSource
);
2399 * Return status code for specified data source.
2401 gint
addrindex_ds_get_status_code( AddressDataSource
*ds
) {
2402 gint retVal
= MGU_SUCCESS
;
2403 AddressInterface
*iface
;
2405 if( ds
== NULL
) return retVal
;
2406 iface
= ds
->interface
;
2407 if( iface
== NULL
) return retVal
;
2408 if( iface
->getStatusCode
) {
2409 retVal
= ( iface
->getStatusCode
) ( ds
->rawDataSource
);
2415 * Return data read flag for specified data source.
2417 gint
addrindex_ds_read_data( AddressDataSource
*ds
) {
2418 gint retVal
= MGU_SUCCESS
;
2419 AddressInterface
*iface
;
2421 if( ds
== NULL
) return retVal
;
2422 iface
= ds
->interface
;
2423 if( iface
== NULL
) return retVal
;
2424 if( iface
->getReadData
) {
2426 gchar *name = ( iface->getName ) ( ds->rawDataSource );
2427 g_print( "addrindex_ds_read_data...reading:::%s:::\n", name );
2429 retVal
= ( iface
->getReadData
) ( ds
->rawDataSource
);
2435 * Return data read flag for specified data source.
2437 ItemFolder
*addrindex_ds_get_root_folder( AddressDataSource
*ds
) {
2438 ItemFolder
*retVal
= NULL
;
2439 AddressInterface
*iface
;
2441 if( ds
== NULL
) return retVal
;
2442 iface
= ds
->interface
;
2443 if( iface
== NULL
) return retVal
;
2444 if( iface
->getRootFolder
) {
2445 retVal
= ( iface
->getRootFolder
) ( ds
->rawDataSource
);
2451 * Return name for specified data source.
2453 gchar
*addrindex_ds_get_name( AddressDataSource
*ds
) {
2454 gchar
*retVal
= FALSE
;
2455 AddressInterface
*iface
;
2457 if( ds
== NULL
) return retVal
;
2458 iface
= ds
->interface
;
2459 if( iface
== NULL
) return retVal
;
2460 if( iface
->getName
) {
2461 retVal
= ( iface
->getName
) ( ds
->rawDataSource
);
2467 * Set the access flag inside the data source.
2469 void addrindex_ds_set_access_flag( AddressDataSource
*ds
, gboolean
*value
) {
2470 AddressInterface
*iface
;
2472 if( ds
== NULL
) return;
2473 iface
= ds
->interface
;
2474 if( iface
== NULL
) return;
2475 if( iface
->setAccessFlag
) {
2476 ( iface
->setAccessFlag
) ( ds
->rawDataSource
, value
);
2481 * Return read only flag for specified data source.
2483 gboolean
addrindex_ds_get_readonly( AddressDataSource
*ds
) {
2484 AddressInterface
*iface
;
2485 if( ds
== NULL
) return TRUE
;
2486 iface
= ds
->interface
;
2487 if( iface
== NULL
) return TRUE
;
2488 return iface
->readOnly
;
2492 * Return list of all persons for specified data source.
2494 static GList
*addrindex_ds_get_all_persons( AddressDataSource
*ds
) {
2495 GList
*retVal
= NULL
;
2496 AddressInterface
*iface
;
2498 if( ds
== NULL
) return retVal
;
2499 iface
= ds
->interface
;
2500 if( iface
== NULL
) return retVal
;
2501 if( iface
->getAllPersons
) {
2502 retVal
= ( iface
->getAllPersons
) ( ds
->rawDataSource
);
2508 * Return list of all groups for specified data source.
2510 static GList
*addrindex_ds_get_all_groups( AddressDataSource
*ds
) {
2511 GList
*retVal
= NULL
;
2512 AddressInterface
*iface
;
2514 if( ds
== NULL
) return retVal
;
2515 iface
= ds
->interface
;
2516 if( iface
== NULL
) return retVal
;
2517 if( iface
->getAllGroups
) {
2518 retVal
= ( iface
->getAllGroups
) ( ds
->rawDataSource
);
2523 /* **********************************************************************
2524 * Address search stuff.
2525 * ***********************************************************************
2529 * Setup or register the dynamic search that will be performed. The search
2530 * is registered with the query manager.
2532 * \param searchTerm Search term. A private copy will be made.
2533 * \param callBackEntry Callback function that should be called when
2534 * each entry is received.
2535 * \param callBackEnd Callback function that should be called when
2536 * search has finished running.
2537 * \return ID allocated to query that will be executed.
2539 gint
addrindex_setup_search(
2540 const gchar
*searchTerm
, void *callBackEnd
, void *callBackEntry
)
2545 /* Set up a dynamic address query */
2546 req
= qrymgr_add_request( searchTerm
, callBackEnd
, callBackEntry
);
2547 queryID
= req
->queryID
;
2548 qryreq_set_search_type( req
, ADDRSEARCH_DYNAMIC
);
2550 /* g_print( "***> query ID ::%d::\n", queryID ); */
2557 * Function prototypes (not in header file or circular reference errors are
2560 LdapQuery
*ldapsvr_new_dynamic_search(
2561 LdapServer
*server
, QueryRequest
*req
);
2562 LdapQuery
*ldapsvr_new_explicit_search(
2563 LdapServer
*server
, QueryRequest
*req
, ItemFolder
*folder
);
2564 void ldapsvr_execute_query( LdapServer
*server
, LdapQuery
*qry
);
2569 * Execute the previously registered dynamic search.
2571 * \param req Address query object to execute.
2572 * \return <i>TRUE</i> if search started successfully, or <i>FALSE</i> if
2575 static gboolean
addrindex_start_dynamic( QueryRequest
*req
) {
2576 AddressInterface
*iface
;
2577 AddressDataSource
*ds
;
2582 /* g_print( "addrindex_start_dynamic::%d::\n", req->queryID ); */
2583 nodeIf
= _addressIndex_
->searchOrder
;
2585 iface
= nodeIf
->data
;
2586 nodeIf
= g_list_next( nodeIf
);
2588 if( ! iface
->useInterface
) {
2591 if( ! iface
->externalQuery
) {
2596 nodeDS
= iface
->listSource
;
2599 nodeDS
= g_list_next( nodeDS
);
2601 if( type
== ADDR_IF_LDAP
) {
2605 server
= ds
->rawDataSource
;
2606 if( ! server
->searchFlag
) {
2609 if( ldapsvr_reuse_previous( server
, req
) ) {
2613 /* Start a new dynamic search */
2614 qry
= ldapsvr_new_dynamic_search( server
, req
);
2616 ldapsvr_execute_query( server
, qry
);
2626 * Stop the previously registered search.
2628 * \param queryID ID of search query to stop.
2630 void addrindex_stop_search( const gint queryID
){
2632 AddrQueryObject
*aqo
;
2635 /* g_print( "addrindex_stop_search/queryID=%d\n", queryID ); */
2636 /* If query ID does not match, search has not been setup */
2637 req
= qrymgr_find_request( queryID
);
2642 /* Stop all queries that were associated with request */
2643 node
= req
->queryList
;
2647 if( aqo
->queryType
== ADDRQUERY_LDAP
) {
2648 LdapQuery
*qry
= ( LdapQuery
* ) aqo
;
2649 ldapqry_set_stop_flag( qry
, TRUE
);
2653 node
= g_list_next( node
);
2656 /* Delete query request */
2657 qrymgr_delete_request( queryID
);
2661 * Setup or register the explicit search that will be performed. The search is
2662 * registered with the query manager.
2664 * \param ds Data source to search.
2665 * \param searchTerm Search term to locate.
2666 * \param folder Folder to receive search results; may be NULL.
2667 * \param callbackEnd Function to call when search has terminated.
2668 * \param callbackEntry Function to called for each entry processed.
2669 * \return ID allocated to query that will be executed.
2671 gint
addrindex_setup_explicit_search(
2672 AddressDataSource
*ds
, const gchar
*searchTerm
, ItemFolder
*folder
,
2673 void *callBackEnd
, void *callBackEntry
)
2680 /* Name the query */
2681 name
= g_strdup_printf( "Search '%s'", searchTerm
);
2683 /* Set up query request */
2684 if (!strcmp(searchTerm
, "*"))
2685 mySearch
= g_strdup("*@");
2687 mySearch
= g_strdup(searchTerm
);
2689 req
= qrymgr_add_request( mySearch
, callBackEnd
, callBackEntry
);
2693 qryreq_set_search_type( req
, ADDRSEARCH_EXPLICIT
);
2694 queryID
= req
->queryID
;
2696 if( ds
->type
== ADDR_IF_LDAP
) {
2700 server
= ds
->rawDataSource
;
2701 ldapsvr_new_explicit_search( server
, req
, folder
);
2705 qrymgr_delete_request( queryID
);
2714 * Execute the previously registered explicit search.
2716 * \param req Address query request object to execute.
2717 * \return <i>TRUE</i> if search started successfully, or <i>FALSE</i> if
2720 static gboolean
addrindex_start_explicit( QueryRequest
*req
) {
2722 AddrQueryObject
*aqo
;
2726 /* Note: there should only be one query in the list. */
2727 aqo
= req
->queryList
->data
;
2729 if( aqo
->queryType
== ADDRQUERY_LDAP
) {
2733 qry
= ( LdapQuery
* ) aqo
;
2734 server
= qry
->server
;
2736 /* Start the search */
2738 ldapsvr_execute_query( server
, qry
);
2745 * Start the previously registered search.
2747 * \param queryID ID of search query to be executed.
2748 * \return <i>TRUE</i> if search started successfully, or <i>FALSE</i> if
2751 gboolean
addrindex_start_search( const gint queryID
) {
2754 AddrSearchType searchType
;
2757 /* g_print( "addrindex_start_search/queryID=%d\n", queryID ); */
2758 req
= qrymgr_find_request( queryID
);
2763 searchType
= req
->searchType
;
2764 if( searchType
== ADDRSEARCH_DYNAMIC
) {
2765 retVal
= addrindex_start_dynamic( req
);
2767 else if( searchType
== ADDRSEARCH_EXPLICIT
) {
2768 retVal
= addrindex_start_explicit( req
);
2775 * Remove results (folder and data) for specified data source and folder.
2776 * \param ds Data source to process.
2777 * \param folder Results folder to remove.
2779 void addrindex_remove_results( AddressDataSource
*ds
, ItemFolder
*folder
) {
2780 AddrBookBase
*adbase
;
2783 /* g_print( "addrindex_remove_results/start\n" ); */
2785 /* Test for folder */
2786 if( folder
->folderType
!= ADDRFOLDER_QUERY_RESULTS
) return;
2787 /* g_print( "folder name ::%s::\n", ADDRITEM_NAME(folder) ); */
2788 adbase
= ( AddrBookBase
* ) ds
->rawDataSource
;
2789 if( adbase
== NULL
) return;
2791 /* Hide folder to prevent re-display */
2792 addritem_folder_set_hidden( folder
, TRUE
);
2794 if( ds
->type
== ADDR_IF_LDAP
) {
2799 qry
= ( LdapQuery
* ) folder
->folderData
;
2800 queryID
= ADDRQUERY_ID(qry
);
2801 /* g_print( "calling ldapquery_remove_results...queryID=%d\n", queryID ); */
2802 delFlag
= ldapquery_remove_results( qry
);
2804 ldapqry_free( qry
);
2806 /* g_print( "calling ldapquery_remove_results...done\n" ); */
2809 g_print( "delFlag IS-TRUE\n" );
2812 g_print( "delFlag IS-FALSE\n" );
2817 /* g_print( "addrindex_remove_results/end\n" ); */
2819 /* Delete query request */
2821 qrymgr_delete_request( queryID
);
2825 /* **********************************************************************
2826 * Address completion stuff.
2827 * ***********************************************************************
2830 static void addrindex_load_completion_load_persons(
2831 gint (*callBackFunc
) ( const gchar
*, const gchar
*,
2832 const gchar
*, const gchar
*, GList
* ),
2833 AddressDataSource
*ds
)
2835 GList
*listP
, *nodeP
;
2839 /* Read address book */
2840 if( addrindex_ds_get_modify_flag( ds
) ) {
2841 addrindex_ds_read_data( ds
);
2844 if( ! addrindex_ds_get_read_flag( ds
) ) {
2845 addrindex_ds_read_data( ds
);
2848 /* Get all groups */
2849 listP
= addrindex_ds_get_all_groups( ds
);
2852 ItemGroup
*group
= nodeP
->data
;
2853 GList
*emails
= NULL
;
2854 for (nodeM
= group
->listEMail
; nodeM
; nodeM
= g_list_next(nodeM
)) {
2855 ItemEMail
*email
= nodeM
->data
;
2857 emails
= g_list_append(emails
, email
);
2859 callBackFunc( ((AddrItemObject
*)group
)->name
, NULL
,
2860 NULL
, NULL
, emails
);
2861 nodeP
= g_list_next( nodeP
);
2864 /* Free up the list */
2865 g_list_free( listP
);
2866 /* Get all persons */
2867 listP
= addrindex_ds_get_all_persons( ds
);
2870 ItemPerson
*person
= nodeP
->data
;
2871 nodeM
= person
->listEMail
;
2873 /* Figure out name to use */
2874 sName
= ADDRITEM_NAME(person
);
2875 if( sName
== NULL
|| *sName
== '\0' ) {
2876 sName
= person
->nickName
;
2879 /* Process each E-Mail address */
2881 ItemEMail
*email
= nodeM
->data
;
2883 callBackFunc( sName
, email
->address
, person
->nickName
,
2884 ADDRITEM_NAME(email
), NULL
);
2886 nodeM
= g_list_next( nodeM
);
2888 nodeP
= g_list_next( nodeP
);
2891 /* Free up the list */
2892 g_list_free( listP
);
2896 * This function is used by the address completion function to load
2897 * addresses for all non-external address book interfaces.
2899 * \param callBackFunc Function to be called when an address is
2901 * \param folderpath Addressbook's Book/folder path to restrict to (if NULL or ""
2902 * or "Any", assume the whole addressbook
2903 * \return <i>TRUE</i> if data loaded, <i>FALSE</i> if address index not loaded.
2906 gboolean
addrindex_load_completion(
2907 gint (*callBackFunc
) ( const gchar
*, const gchar
*,
2908 const gchar
*, const gchar
*, GList
* ),
2911 GList
*nodeIf
, *nodeDS
;
2913 if( folderpath
!= NULL
) {
2914 AddressDataSource
*book
;
2917 /* split the folder path we've received, we'll try to match this path, subpath by
2918 subpath against the book/folder structure in order and restrict loading of
2919 addresses to that subpart (if matches). book/folder path must exist and
2920 folderpath must not be empty or NULL */
2922 if( ! addressbook_peek_folder_exists( folderpath
, &book
, &folder
) ) {
2923 g_warning("addrindex_load_completion: folder path '%s' doesn't exist", folderpath
);
2927 if( folder
!= NULL
) {
2934 debug_print("addrindex_load_completion: folder %p '%s'\n", folder
, folder
->obj
.name
);
2936 /* Load email addresses */
2937 items
= addritem_folder_get_person_list( folder
);
2938 for( ; items
!= NULL
; items
= g_list_next( items
) ) {
2939 person
= items
->data
;
2940 nodeM
= person
->listEMail
;
2942 /* Figure out name to use */
2943 sName
= ADDRITEM_NAME(person
);
2944 if( sName
== NULL
|| *sName
== '\0' ) {
2945 sName
= person
->nickName
;
2948 /* Process each E-Mail address */
2950 ItemEMail
*email
= nodeM
->data
;
2952 callBackFunc( sName
, email
->address
, person
->nickName
,
2953 ADDRITEM_NAME(email
), NULL
);
2955 nodeM
= g_list_next( nodeM
);
2958 /* Free up the list */
2959 mgu_clear_list( items
);
2960 g_list_free( items
);
2966 if( book
!= NULL
) {
2968 AddressBookFile
*abf
= book
->rawDataSource
;
2970 debug_print("addrindex_load_completion: book %p '%s'\n", book
, abf
?abf
->fileName
:"(null)");
2972 addrindex_load_completion_load_persons( callBackFunc
, book
);
2977 g_warning("addrindex_load_completion: book/folder path is valid but got no pointer");
2984 nodeIf
= addrindex_get_interface_list( _addressIndex_
);
2986 AddressInterface
*iface
= nodeIf
->data
;
2988 nodeIf
= g_list_next( nodeIf
);
2990 if( ! iface
->useInterface
|| iface
->externalQuery
)
2993 nodeDS
= iface
->listSource
;
2995 addrindex_load_completion_load_persons( callBackFunc
, nodeDS
->data
);
2996 nodeDS
= g_list_next( nodeDS
);
3005 * This function can be used to collect information about
3006 * addressbook entries that contain a specific attribute.
3008 * \param attr Name of attribute to look for
3009 * \param callBackFunc Function to be called when a matching attribute was found
3010 * \return <i>TRUE</i>
3012 gboolean
addrindex_load_person_attribute(
3014 gint (*callBackFunc
) ( ItemPerson
*, const gchar
* ) )
3016 AddressDataSource
*ds
;
3017 GList
*nodeIf
, *nodeDS
;
3018 GList
*listP
, *nodeP
;
3021 nodeIf
= addrindex_get_interface_list( _addressIndex_
);
3024 AddressInterface
*iface
= nodeIf
->data
;
3026 nodeIf
= g_list_next( nodeIf
);
3028 if( ! iface
->useInterface
|| iface
->externalQuery
)
3031 nodeDS
= iface
->listSource
;
3035 /* Read address book */
3036 if( addrindex_ds_get_modify_flag( ds
) ) {
3037 addrindex_ds_read_data( ds
);
3040 if( ! addrindex_ds_get_read_flag( ds
) ) {
3041 addrindex_ds_read_data( ds
);
3044 /* Check addressbook name */
3045 cur_bname
= addrindex_ds_get_name( ds
);
3047 /* Get all persons */
3048 listP
= addrindex_ds_get_all_persons( ds
);
3051 ItemPerson
*person
= nodeP
->data
;
3053 /* Return all ItemPerson's if attr is NULL */
3054 if( attr
== NULL
) {
3055 callBackFunc(person
, cur_bname
);
3058 /* Return ItemPerson's with specific attribute */
3060 nodeA
= person
->listAttrib
;
3061 /* Process each User Attribute */
3063 UserAttribute
*attrib
= nodeA
->data
;
3065 !strcmp( attrib
->name
,attr
) ) {
3066 callBackFunc(person
, cur_bname
);
3068 nodeA
= g_list_next( nodeA
);
3071 nodeP
= g_list_next( nodeP
);
3073 /* Free up the list */
3074 g_list_free( listP
);
3076 nodeDS
= g_list_next( nodeDS
);
3083 * This function can be used to collect information about
3084 * addressbook entries
3086 * \param callBackFunc Function to be called for each ItemPerson
3087 * \return <i>TRUE</i>
3089 gboolean
addrindex_load_person_ds( gint (*callBackFunc
)
3090 ( ItemPerson
*, AddressDataSource
* ) )
3092 AddressDataSource
*ds
;
3093 GList
*nodeIf
, *nodeDS
;
3094 GList
*listP
, *nodeP
;
3096 nodeIf
= addrindex_get_interface_list( _addressIndex_
);
3098 AddressInterface
*iface
= nodeIf
->data
;
3100 nodeIf
= g_list_next( nodeIf
);
3102 if( ! iface
->useInterface
|| iface
->externalQuery
)
3105 nodeDS
= iface
->listSource
;
3109 /* Read address book */
3110 if( addrindex_ds_get_modify_flag( ds
) ) {
3111 addrindex_ds_read_data( ds
);
3114 if( ! addrindex_ds_get_read_flag( ds
) ) {
3115 addrindex_ds_read_data( ds
);
3118 /* Get all persons */
3119 listP
= addrindex_ds_get_all_persons( ds
);
3122 ItemPerson
*person
= nodeP
->data
;
3124 callBackFunc(person
, ds
);
3125 nodeP
= g_list_next( nodeP
);
3127 /* Free up the list */
3128 g_list_free( listP
);
3130 nodeDS
= g_list_next( nodeDS
);
3136 gchar
*addrindex_get_picture_file(const gchar
*emailaddr
)
3138 AddressDataSource
*ds
;
3139 GList
*nodeIf
, *nodeDS
;
3140 GList
*listP
, *nodeP
;
3141 gboolean found
= FALSE
;
3142 gchar
*filename
= NULL
;
3143 gchar
*raw_addr
= NULL
;
3148 Xstrdup_a(raw_addr
, emailaddr
, return NULL
);
3149 extract_address(raw_addr
);
3151 nodeIf
= addrindex_get_interface_list( _addressIndex_
);
3153 AddressInterface
*iface
= nodeIf
->data
;
3155 nodeIf
= g_list_next( nodeIf
);
3157 if( ! iface
->useInterface
|| iface
->externalQuery
)
3160 nodeDS
= iface
->listSource
;
3161 while( nodeDS
&& !found
) {
3164 /* Read address book */
3165 if( addrindex_ds_get_modify_flag( ds
) ) {
3166 addrindex_ds_read_data( ds
);
3169 if( ! addrindex_ds_get_read_flag( ds
) ) {
3170 addrindex_ds_read_data( ds
);
3173 /* Get all persons */
3174 listP
= addrindex_ds_get_all_persons( ds
);
3178 ItemPerson
*person
= nodeP
->data
;
3179 nodeM
= person
->listEMail
;
3181 ItemEMail
*email
= nodeM
->data
;
3182 if (email
->address
&& !strcasecmp(raw_addr
, email
->address
)) {
3184 filename
= g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S
,
3185 ADDRBOOK_DIR
, G_DIR_SEPARATOR_S
,
3186 person
->picture
, ".png", NULL
);
3189 nodeM
= nodeM
->next
;
3191 nodeP
= g_list_next( nodeP
);
3193 /* Free up the list */
3194 g_list_free( listP
);
3196 nodeDS
= g_list_next( nodeDS
);