2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 2001-2022 the Claws Mail team and Match Grun
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"
46 #include "file-utils.h"
48 #ifndef DEV_STANDALONE
49 #include "prefs_gtk.h"
60 #include "ldapserver.h"
62 #include "ldapquery.h"
63 #include "ldapupdate.h"
71 #define TAG_ADDRESS_INDEX "addressbook"
73 #define TAG_IF_ADDRESS_BOOK "book_list"
74 #define TAG_IF_VCARD "vcard_list"
75 #define TAG_IF_JPILOT "jpilot_list"
76 #define TAG_IF_LDAP "ldap_list"
78 #define TAG_DS_ADDRESS_BOOK "book"
79 #define TAG_DS_VCARD "vcard"
80 #define TAG_DS_JPILOT "jpilot"
81 #define TAG_DS_LDAP "server"
83 /* XML Attribute names */
84 #define ATTAG_BOOK_NAME "name"
85 #define ATTAG_BOOK_FILE "file"
87 #define ATTAG_VCARD_NAME "name"
88 #define ATTAG_VCARD_FILE "file"
90 #define ATTAG_JPILOT_NAME "name"
91 #define ATTAG_JPILOT_FILE "file"
92 #define ATTAG_JPILOT_CUSTOM_1 "custom-1"
93 #define ATTAG_JPILOT_CUSTOM_2 "custom-2"
94 #define ATTAG_JPILOT_CUSTOM_3 "custom-3"
95 #define ATTAG_JPILOT_CUSTOM_4 "custom-4"
96 #define ATTAG_JPILOT_CUSTOM "custom-"
98 #define ATTAG_LDAP_NAME "name"
99 #define ATTAG_LDAP_HOST "host"
100 #define ATTAG_LDAP_PORT "port"
101 #define ATTAG_LDAP_BASE_DN "base-dn"
102 #define ATTAG_LDAP_BIND_DN "bind-dn"
103 #define ATTAG_LDAP_BIND_PASS "bind-pass"
104 #define ATTAG_LDAP_CRITERIA "criteria"
105 #define ATTAG_LDAP_MAX_ENTRY "max-entry"
106 #define ATTAG_LDAP_TIMEOUT "timeout"
107 #define ATTAG_LDAP_MAX_AGE "max-age"
108 #define ATTAG_LDAP_DYN_SEARCH "dyn-search"
109 #define ATTAG_LDAP_MATCH_OPT "match-opt"
110 #define ATTAG_LDAP_ENABLE_TLS "enable-tls"
111 #define ATTAG_LDAP_ENABLE_SSL "enable-ssl"
113 #define ELTAG_LDAP_ATTR_SRCH "attribute"
114 #define ATTAG_LDAP_ATTR_NAME "name"
116 /* Attribute values */
117 #define ATVAL_BOOLEAN_YES "yes"
118 #define ATVAL_BOOLEAN_NO "no"
119 #define ATVAL_LDAP_MATCH_BEGIN "begin-with"
120 #define ATVAL_LDAP_MATCH_CONTAINS "contains"
123 #define ATTAG_LDAP_DEFAULT "default"
125 #define DISP_NEW_COMMON _("Common addresses")
126 #define DISP_NEW_PERSONAL _("Personal addresses")
128 /* Old address book */
129 #define TAG_IF_OLD_COMMON "common_address"
130 #define TAG_IF_OLD_PERSONAL "personal_address"
132 #define DISP_OLD_COMMON _("Common address")
133 #define DISP_OLD_PERSONAL _("Personal address")
138 static AddressIndex
*_addressIndex_
= NULL
;
141 * Define attribute name-value pair.
143 typedef struct _AddressIfAttr AddressIfAttrib
;
144 struct _AddressIfAttr
{
149 static AddressDataSource
*addrindex_create_datasource ( AddressIfType ifType
);
151 static GList
*addrindex_ds_get_all_persons ( AddressDataSource
*ds
);
152 static GList
*addrindex_ds_get_all_groups ( AddressDataSource
*ds
);
153 static AddressDataSource
*addrindex_get_datasource ( AddressIndex
*addrIndex
,
154 const gchar
*cacheID
);
155 static AddressInterface
*addrindex_get_interface ( AddressIndex
*addrIndex
,
156 AddressIfType ifType
);
157 static gint
addrindex_write_to ( AddressIndex
*addrIndex
,
158 const gchar
*newFile
);
161 * Define DOM fragment.
163 typedef struct _AddressIfFrag AddressIfFragment
;
164 struct _AddressIfFrag
{
165 AddressBookType type
;
166 AddressCache
*addressCache
;
173 * Build interface with default values.
175 * \param type Interface type.
176 * \param name Interface name.
177 * \param tagIf XML tag name for interface in address index file.
178 * \param tagDS XML tag name for datasource in address index file.
179 * \return Address interface object.
181 static AddressInterface
*addrindex_create_interface(
182 gint type
, gchar
*name
, gchar
*tagIf
, gchar
*tagDS
)
184 AddressInterface
*iface
= g_new0( AddressInterface
, 1 );
186 ADDRITEM_TYPE(iface
) = ITEMTYPE_INTERFACE
;
187 ADDRITEM_ID(iface
) = NULL
;
188 ADDRITEM_NAME(iface
) = g_strdup( name
);
189 ADDRITEM_PARENT(iface
) = NULL
;
190 ADDRITEM_SUBTYPE(iface
) = type
;
192 iface
->name
= g_strdup( name
);
193 iface
->listTag
= g_strdup( tagIf
);
194 iface
->itemTag
= g_strdup( tagDS
);
195 iface
->legacyFlag
= FALSE
;
196 iface
->haveLibrary
= TRUE
;
197 iface
->useInterface
= TRUE
;
198 iface
->readOnly
= TRUE
;
200 /* Set callbacks to NULL values - override for each interface */
201 iface
->getAccessFlag
= NULL
;
202 iface
->getModifyFlag
= NULL
;
203 iface
->getReadFlag
= NULL
;
204 iface
->getStatusCode
= NULL
;
205 iface
->getReadData
= NULL
;
206 iface
->getRootFolder
= NULL
;
207 iface
->getListFolder
= NULL
;
208 iface
->getListPerson
= NULL
;
209 iface
->getAllPersons
= NULL
;
210 iface
->getAllGroups
= NULL
;
211 iface
->getName
= NULL
;
212 iface
->listSource
= NULL
;
215 iface
->externalQuery
= FALSE
;
216 iface
->searchOrder
= 0; /* Ignored */
217 iface
->startSearch
= NULL
;
218 iface
->stopSearch
= NULL
;
224 * Build table of of all address book interfaces.
225 * \param addrIndex Address index object.
227 static void addrindex_build_if_list( AddressIndex
*addrIndex
) {
228 AddressInterface
*iface
;
230 /* Create intrinsic XML address book interface */
231 iface
= addrindex_create_interface(
232 ADDR_IF_BOOK
, "Address Book", TAG_IF_ADDRESS_BOOK
,
233 TAG_DS_ADDRESS_BOOK
);
234 iface
->readOnly
= FALSE
;
235 iface
->getModifyFlag
= ( void * ) addrbook_get_modified
;
236 iface
->getAccessFlag
= ( void * ) addrbook_get_accessed
;
237 iface
->getReadFlag
= ( void * ) addrbook_get_read_flag
;
238 iface
->getStatusCode
= ( void * ) addrbook_get_status
;
239 iface
->getReadData
= ( void * ) addrbook_read_data
;
240 iface
->getRootFolder
= ( void * ) addrbook_get_root_folder
;
241 iface
->getListFolder
= ( void * ) addrbook_get_list_folder
;
242 iface
->getListPerson
= ( void * ) addrbook_get_list_person
;
243 iface
->getAllPersons
= ( void * ) addrbook_get_all_persons
;
244 iface
->getAllGroups
= ( void * ) addrbook_get_all_groups
;
245 iface
->getName
= ( void * ) addrbook_get_name
;
246 iface
->setAccessFlag
= ( void * ) addrbook_set_accessed
;
247 iface
->searchOrder
= 0;
249 /* Add to list of interfaces in address book */
250 addrIndex
->interfaceList
=
251 g_list_append( addrIndex
->interfaceList
, iface
);
252 ADDRITEM_PARENT(iface
) = ADDRITEM_OBJECT(addrIndex
);
254 /* Create vCard interface */
255 iface
= addrindex_create_interface(
256 ADDR_IF_VCARD
, "vCard", TAG_IF_VCARD
, TAG_DS_VCARD
);
257 iface
->getModifyFlag
= ( void * ) vcard_get_modified
;
258 iface
->getAccessFlag
= ( void * ) vcard_get_accessed
;
259 iface
->getReadFlag
= ( void * ) vcard_get_read_flag
;
260 iface
->getStatusCode
= ( void * ) vcard_get_status
;
261 iface
->getReadData
= ( void * ) vcard_read_data
;
262 iface
->getRootFolder
= ( void * ) vcard_get_root_folder
;
263 iface
->getListFolder
= ( void * ) vcard_get_list_folder
;
264 iface
->getListPerson
= ( void * ) vcard_get_list_person
;
265 iface
->getAllPersons
= ( void * ) vcard_get_all_persons
;
266 iface
->getName
= ( void * ) vcard_get_name
;
267 iface
->setAccessFlag
= ( void * ) vcard_set_accessed
;
268 iface
->searchOrder
= 0;
269 addrIndex
->interfaceList
=
270 g_list_append( addrIndex
->interfaceList
, iface
);
271 ADDRITEM_PARENT(iface
) = ADDRITEM_OBJECT(addrIndex
);
273 /* Create JPilot interface */
274 iface
= addrindex_create_interface(
275 ADDR_IF_JPILOT
, "J-Pilot", TAG_IF_JPILOT
,
278 iface
->haveLibrary
= jpilot_test_pilot_lib();
279 iface
->useInterface
= iface
->haveLibrary
;
280 iface
->getModifyFlag
= ( void * ) jpilot_get_modified
;
281 iface
->getAccessFlag
= ( void * ) jpilot_get_accessed
;
282 iface
->getReadFlag
= ( void * ) jpilot_get_read_flag
;
283 iface
->getStatusCode
= ( void * ) jpilot_get_status
;
284 iface
->getReadData
= ( void * ) jpilot_read_data
;
285 iface
->getRootFolder
= ( void * ) jpilot_get_root_folder
;
286 iface
->getListFolder
= ( void * ) jpilot_get_list_folder
;
287 iface
->getListPerson
= ( void * ) jpilot_get_list_person
;
288 iface
->getAllPersons
= ( void * ) jpilot_get_all_persons
;
289 iface
->getName
= ( void * ) jpilot_get_name
;
290 iface
->setAccessFlag
= ( void * ) jpilot_set_accessed
;
291 iface
->searchOrder
= 0;
293 iface
->useInterface
= FALSE
;
294 iface
->haveLibrary
= FALSE
;
296 addrIndex
->interfaceList
=
297 g_list_append( addrIndex
->interfaceList
, iface
);
298 ADDRITEM_PARENT(iface
) = ADDRITEM_OBJECT(addrIndex
);
300 /* Create LDAP interface */
301 iface
= addrindex_create_interface(
302 ADDR_IF_LDAP
, "LDAP", TAG_IF_LDAP
, TAG_DS_LDAP
);
304 iface
->readOnly
= FALSE
;
305 /* iface->haveLibrary = ldapsvr_test_ldap_lib(); */
306 iface
->haveLibrary
= ldaputil_test_ldap_lib();
307 iface
->useInterface
= iface
->haveLibrary
;
308 iface
->getModifyFlag
= ( void * ) ldapsvr_get_modified
;
309 iface
->getAccessFlag
= ( void * ) ldapsvr_get_accessed
;
310 iface
->getReadFlag
= ( void * ) ldapsvr_get_read_flag
;
311 iface
->getStatusCode
= ( void * ) ldapsvr_get_status
;
312 iface
->getReadData
= ( void * ) ldapsvr_read_data
;
313 iface
->getRootFolder
= ( void * ) ldapsvr_get_root_folder
;
314 iface
->getListFolder
= ( void * ) ldapsvr_get_list_folder
;
315 iface
->getListPerson
= ( void * ) ldapsvr_get_list_person
;
316 iface
->getName
= ( void * ) ldapsvr_get_name
;
317 iface
->setAccessFlag
= ( void * ) ldapsvr_set_accessed
;
318 iface
->externalQuery
= TRUE
;
319 iface
->searchOrder
= 1;
321 iface
->useInterface
= FALSE
;
322 iface
->haveLibrary
= FALSE
;
324 addrIndex
->interfaceList
=
325 g_list_append( addrIndex
->interfaceList
, iface
);
326 ADDRITEM_PARENT(iface
) = ADDRITEM_OBJECT(addrIndex
);
328 /* Two old legacy data sources (pre 0.7.0) */
329 iface
= addrindex_create_interface(
330 ADDR_IF_COMMON
, "Old Address - common",
331 TAG_IF_OLD_COMMON
, NULL
);
332 iface
->legacyFlag
= TRUE
;
333 addrIndex
->interfaceList
=
334 g_list_append( addrIndex
->interfaceList
, iface
);
335 ADDRITEM_PARENT(iface
) = ADDRITEM_OBJECT(addrIndex
);
337 iface
= addrindex_create_interface(
338 ADDR_IF_COMMON
, "Old Address - personal",
339 TAG_IF_OLD_PERSONAL
, NULL
);
340 iface
->legacyFlag
= TRUE
;
341 addrIndex
->interfaceList
=
342 g_list_append( addrIndex
->interfaceList
, iface
);
343 ADDRITEM_PARENT(iface
) = ADDRITEM_OBJECT(addrIndex
);
349 * \param fragment Fragment to free.
351 static void addrindex_free_fragment( AddressIfFragment
*fragment
) {
355 node
= fragment
->children
;
357 AddressIfFragment
*child
= node
->data
;
358 addrindex_free_fragment( child
);
360 node
= g_list_next( node
);
362 g_list_free( fragment
->children
);
364 /* Free attributes */
365 node
= fragment
->attributes
;
367 AddressIfAttrib
*nv
= node
->data
;
372 node
= g_list_next( node
);
374 g_list_free( fragment
->attributes
);
376 g_free( fragment
->name
);
377 fragment
->name
= NULL
;
378 fragment
->attributes
= NULL
;
379 fragment
->children
= NULL
;
385 * Create a new data source.
386 * \param ifType Interface type to create.
387 * \return Initialized data source.
389 AddressDataSource
*addrindex_create_datasource( AddressIfType ifType
) {
390 AddressDataSource
*ds
= g_new0( AddressDataSource
, 1 );
392 ADDRITEM_TYPE(ds
) = ITEMTYPE_DATASOURCE
;
393 ADDRITEM_ID(ds
) = NULL
;
394 ADDRITEM_NAME(ds
) = NULL
;
395 ADDRITEM_PARENT(ds
) = NULL
;
396 ADDRITEM_SUBTYPE(ds
) = 0;
398 ds
->rawDataSource
= NULL
;
399 ds
->interface
= NULL
;
404 * Free up data source.
405 * \param ds Data source to free.
407 void addrindex_free_datasource( AddressDataSource
*ds
) {
408 AddressInterface
*iface
;
410 cm_return_if_fail( ds
!= NULL
);
412 iface
= ds
->interface
;
413 if( ds
->rawDataSource
!= NULL
) {
414 if( iface
!= NULL
) {
415 if( iface
->useInterface
) {
416 if( iface
->type
== ADDR_IF_BOOK
) {
417 AddressBookFile
*abf
= ds
->rawDataSource
;
418 addrbook_free_book( abf
);
420 else if( iface
->type
== ADDR_IF_VCARD
) {
421 VCardFile
*vcf
= ds
->rawDataSource
;
425 else if( iface
->type
== ADDR_IF_JPILOT
) {
426 JPilotFile
*jpf
= ds
->rawDataSource
;
431 else if( iface
->type
== ADDR_IF_LDAP
) {
432 LdapServer
*server
= ds
->rawDataSource
;
433 ldapsvr_free( server
);
440 AddressIfFragment
*fragment
= ds
->rawDataSource
;
441 addrindex_free_fragment( fragment
);
446 ADDRITEM_TYPE(ds
) = ITEMTYPE_NONE
;
447 ADDRITEM_ID(ds
) = NULL
;
448 ADDRITEM_NAME(ds
) = NULL
;
449 ADDRITEM_PARENT(ds
) = NULL
;
450 ADDRITEM_SUBTYPE(ds
) = 0;
451 ds
->type
= ADDR_IF_NONE
;
452 ds
->interface
= NULL
;
453 ds
->rawDataSource
= NULL
;
459 * Free up all data sources for specified interface.
460 * \param iface Address interface to process.
462 static void addrindex_free_all_datasources( AddressInterface
*iface
) {
463 GList
*node
= iface
->listSource
;
465 AddressDataSource
*ds
= node
->data
;
466 addrindex_free_datasource( ds
);
468 node
= g_list_next( node
);
473 * Free up specified interface.
474 * \param iface Interface to process.
476 static void addrindex_free_interface( AddressInterface
*iface
) {
477 /* Free up data sources */
478 addrindex_free_all_datasources( iface
);
479 g_list_free( iface
->listSource
);
481 /* Free internal storage */
482 g_free( ADDRITEM_ID(iface
) );
483 g_free( ADDRITEM_NAME(iface
) );
484 g_free( iface
->name
);
485 g_free( iface
->listTag
);
486 g_free( iface
->itemTag
);
488 /* Clear all pointers */
489 ADDRITEM_TYPE(iface
) = ITEMTYPE_NONE
;
490 ADDRITEM_ID(iface
) = NULL
;
491 ADDRITEM_NAME(iface
) = NULL
;
492 ADDRITEM_PARENT(iface
) = NULL
;
493 ADDRITEM_SUBTYPE(iface
) = 0;
494 iface
->type
= ADDR_IF_NONE
;
496 iface
->listTag
= NULL
;
497 iface
->itemTag
= NULL
;
498 iface
->legacyFlag
= FALSE
;
499 iface
->useInterface
= FALSE
;
500 iface
->haveLibrary
= FALSE
;
501 iface
->listSource
= NULL
;
504 iface
->searchOrder
= 0;
505 iface
->startSearch
= NULL
;
506 iface
->stopSearch
= NULL
;
512 * Return cache ID for specified data source.
514 * \param addrIndex Address index.
515 * \param ds Data source.
516 * \return ID or NULL if not found. This should be <code>g_free()</code>
519 gchar
*addrindex_get_cache_id( AddressIndex
*addrIndex
, AddressDataSource
*ds
) {
520 gchar
*cacheID
= NULL
;
521 AddrBookBase
*adbase
;
524 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
525 cm_return_val_if_fail( ds
!= NULL
, NULL
);
527 adbase
= ( AddrBookBase
* ) ds
->rawDataSource
;
529 cache
= adbase
->addressCache
;
531 cacheID
= g_strdup( cache
->cacheID
);
539 * Return reference to data source for specified cacheID.
540 * \param addrIndex Address index.
542 * \return Data source, or NULL if not found.
544 static AddressDataSource
*addrindex_get_datasource(
545 AddressIndex
*addrIndex
, const gchar
*cacheID
)
547 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
548 cm_return_val_if_fail( cacheID
!= NULL
, NULL
);
549 return ( AddressDataSource
* ) g_hash_table_lookup( addrIndex
->hashCache
, cacheID
);
553 * Return reference to address cache for specified cacheID.
554 * \param addrIndex Address index.
556 * \return Address cache, or NULL if not found.
558 AddressCache
*addrindex_get_cache( AddressIndex
*addrIndex
, const gchar
*cacheID
) {
559 AddressDataSource
*ds
;
560 AddrBookBase
*adbase
;
563 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
564 cm_return_val_if_fail( cacheID
!= NULL
, NULL
);
567 ds
= addrindex_get_datasource( addrIndex
, cacheID
);
569 adbase
= ( AddrBookBase
* ) ds
->rawDataSource
;
570 cache
= adbase
->addressCache
;
576 * Add data source into hash table.
577 * \param addrIndex Address index.
578 * \param ds Data source.
580 static void addrindex_hash_add_cache(
581 AddressIndex
*addrIndex
, AddressDataSource
*ds
)
585 cacheID
= addrindex_get_cache_id( addrIndex
, ds
);
587 g_hash_table_insert( addrIndex
->hashCache
, cacheID
, ds
);
592 * Free hash table callback function.
594 static gboolean
addrindex_free_cache_cb( gpointer key
, gpointer value
, gpointer data
) {
602 * Free hash table of address cache items.
604 static void addrindex_free_cache_hash( GHashTable
*table
) {
605 g_hash_table_foreach_remove( table
, addrindex_free_cache_cb
, NULL
);
606 g_hash_table_destroy( table
);
610 * Remove data source from internal hashtable.
611 * \param addrIndex Address index.
612 * \param ds Data source to remove.
614 static void addrindex_hash_remove_cache(
615 AddressIndex
*addrIndex
, AddressDataSource
*ds
)
619 cacheID
= addrindex_get_cache_id( addrIndex
, ds
);
621 g_hash_table_remove( addrIndex
->hashCache
, cacheID
);
628 * Create a new address index. This is created as a singleton object.
629 * \return Initialized address index object.
631 AddressIndex
*addrindex_create_index( void ) {
634 if( _addressIndex_
== NULL
) {
635 index
= g_new0( AddressIndex
, 1 );
636 ADDRITEM_TYPE(index
) = ITEMTYPE_INDEX
;
637 ADDRITEM_ID(index
) = NULL
;
638 ADDRITEM_NAME(index
) = g_strdup( "Address Index" );
639 ADDRITEM_PARENT(index
) = NULL
;
640 ADDRITEM_SUBTYPE(index
) = 0;
641 index
->filePath
= NULL
;
642 index
->fileName
= NULL
;
643 index
->retVal
= MGU_SUCCESS
;
644 index
->needsConversion
= FALSE
;
645 index
->wasConverted
= FALSE
;
646 index
->conversionError
= FALSE
;
647 index
->interfaceList
= NULL
;
648 index
->lastType
= ADDR_IF_NONE
;
649 index
->dirtyFlag
= FALSE
;
650 index
->hashCache
= g_hash_table_new( g_str_hash
, g_str_equal
);
651 index
->loadedFlag
= FALSE
;
652 index
->searchOrder
= NULL
;
653 addrindex_build_if_list( index
);
654 _addressIndex_
= index
;
656 return _addressIndex_
;
660 * Property - Specify file path to address index file.
661 * \param addrIndex Address index.
662 * \param value Path to index file.
664 void addrindex_set_file_path( AddressIndex
*addrIndex
, const gchar
*value
) {
665 cm_return_if_fail( addrIndex
!= NULL
);
666 addrIndex
->filePath
= mgu_replace_string( addrIndex
->filePath
, value
);
670 * Property - Specify file name to address index file.
671 * \param addrIndex Address index.
672 * \param value File name.
674 void addrindex_set_file_name( AddressIndex
*addrIndex
, const gchar
*value
) {
675 cm_return_if_fail( addrIndex
!= NULL
);
676 addrIndex
->fileName
= mgu_replace_string( addrIndex
->fileName
, value
);
680 * Return list of address interfaces.
681 * \param addrIndex Address index.
682 * \return List of address interfaces.
684 GList
*addrindex_get_interface_list( AddressIndex
*addrIndex
) {
685 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
686 return addrIndex
->interfaceList
;
690 * Perform any other initialization of address index.
692 void addrindex_initialize( void ) {
694 addrcompl_initialize();
698 * Perform any other teardown of address index.
700 void addrindex_teardown( void ) {
701 addrcompl_teardown();
706 * Free up address index.
707 * \param addrIndex Address index.
709 void addrindex_free_index( AddressIndex
*addrIndex
) {
712 cm_return_if_fail( addrIndex
!= NULL
);
715 g_list_free( addrIndex
->searchOrder
);
716 addrIndex
->searchOrder
= NULL
;
718 /* Free internal storage */
719 g_free( ADDRITEM_ID(addrIndex
) );
720 g_free( ADDRITEM_NAME(addrIndex
) );
721 g_free( addrIndex
->filePath
);
722 g_free( addrIndex
->fileName
);
725 ADDRITEM_TYPE(addrIndex
) = ITEMTYPE_NONE
;
726 ADDRITEM_ID(addrIndex
) = NULL
;
727 ADDRITEM_NAME(addrIndex
) = NULL
;
728 ADDRITEM_PARENT(addrIndex
) = NULL
;
729 ADDRITEM_SUBTYPE(addrIndex
) = 0;
730 addrIndex
->filePath
= NULL
;
731 addrIndex
->fileName
= NULL
;
732 addrIndex
->retVal
= MGU_SUCCESS
;
733 addrIndex
->needsConversion
= FALSE
;
734 addrIndex
->wasConverted
= FALSE
;
735 addrIndex
->conversionError
= FALSE
;
736 addrIndex
->lastType
= ADDR_IF_NONE
;
737 addrIndex
->dirtyFlag
= FALSE
;
739 /* Free up interfaces */
740 node
= addrIndex
->interfaceList
;
742 AddressInterface
*iface
= node
->data
;
743 addrindex_free_interface( iface
);
744 node
= g_list_next( node
);
746 g_list_free( addrIndex
->interfaceList
);
747 addrIndex
->interfaceList
= NULL
;
749 /* Free up hash cache */
750 addrindex_free_cache_hash( addrIndex
->hashCache
);
751 addrIndex
->hashCache
= NULL
;
753 addrIndex
->loadedFlag
= FALSE
;
757 _addressIndex_
= NULL
;
761 * Print address index.
762 * \param addrIndex Address index.
763 * \parem stream Stream to print.
765 void addrindex_print_index( AddressIndex
*addrIndex
, FILE *stream
) {
766 cm_return_if_fail( addrIndex
!= NULL
);
767 fprintf( stream
, "AddressIndex:\n" );
768 fprintf( stream
, "\tfile path: '%s'\n", addrIndex
->filePath
);
769 fprintf( stream
, "\tfile name: '%s'\n", addrIndex
->fileName
);
770 fprintf( stream
, "\t status: %d\n", addrIndex
->retVal
);
771 fprintf( stream
, "\tconverted: '%s'\n",
772 addrIndex
->wasConverted
? "yes" : "no" );
773 fprintf( stream
, "\tcvt error: '%s'\n",
774 addrIndex
->conversionError
? "yes" : "no" );
775 fprintf( stream
, "\t---\n" );
779 * Retrieve reference to address interface for specified interface type.
780 * \param addrIndex Address index.
781 * \param ifType Interface type.
782 * \return Address interface, or NULL if not found.
784 static AddressInterface
*addrindex_get_interface(
785 AddressIndex
*addrIndex
, AddressIfType ifType
)
787 AddressInterface
*retVal
= NULL
;
790 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
792 node
= addrIndex
->interfaceList
;
794 AddressInterface
*iface
= node
->data
;
795 node
= g_list_next( node
);
796 if( iface
->type
== ifType
) {
805 * Add raw data source to index. The raw data object (an AddressBookFile or
806 * VCardFile object, for example) should be supplied as the raw dataSource
809 * \param addrIndex Address index.
810 * \param ifType Interface type to add.
811 * \param dataSource Actual raw data source to add.
812 * \return Data source added, or NULL if invalid interface type.
814 AddressDataSource
*addrindex_index_add_datasource(
815 AddressIndex
*addrIndex
, AddressIfType ifType
, gpointer dataSource
)
817 AddressInterface
*iface
;
818 AddressDataSource
*ds
= NULL
;
820 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
821 cm_return_val_if_fail( dataSource
!= NULL
, NULL
);
823 iface
= addrindex_get_interface( addrIndex
, ifType
);
825 ds
= addrindex_create_datasource( ifType
);
826 ADDRITEM_PARENT(ds
) = ADDRITEM_OBJECT(iface
);
828 ds
->rawDataSource
= dataSource
;
829 ds
->interface
= iface
;
830 iface
->listSource
= g_list_append( iface
->listSource
, ds
);
831 addrIndex
->dirtyFlag
= TRUE
;
833 addrindex_hash_add_cache( addrIndex
, ds
);
839 * Remove specified data source from index.
840 * \param addrIndex Address index.
841 * \param dataSource Data source to add.
842 * \return Reference to data source if removed, or NULL if data source was not
843 * found in index. Note the this object must still be freed.
845 AddressDataSource
*addrindex_index_remove_datasource(
846 AddressIndex
*addrIndex
, AddressDataSource
*dataSource
)
848 AddressDataSource
*retVal
= FALSE
;
849 AddressInterface
*iface
;
851 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
852 cm_return_val_if_fail( dataSource
!= NULL
, NULL
);
854 iface
= addrindex_get_interface( addrIndex
, dataSource
->type
);
856 iface
->listSource
= g_list_remove( iface
->listSource
, dataSource
);
857 addrIndex
->dirtyFlag
= TRUE
;
858 dataSource
->interface
= NULL
;
860 /* Remove cache from hash table */
861 addrindex_hash_remove_cache( addrIndex
, dataSource
);
869 * Retrieve a reference to address interface for specified interface type and
870 * XML interface tag name.
871 * \param addrIndex Address index.
872 * \param tag XML interface tag name to match.
873 * \param ifType Interface type to match.
874 * \return Reference to address index, or NULL if not found in index.
876 static AddressInterface
*addrindex_tag_get_interface(
877 AddressIndex
*addrIndex
, gchar
*tag
, AddressIfType ifType
)
879 AddressInterface
*retVal
= NULL
;
880 GList
*node
= addrIndex
->interfaceList
;
883 AddressInterface
*iface
= node
->data
;
884 node
= g_list_next( node
);
886 if( strcmp( iface
->listTag
, tag
) == 0 ) {
892 if( iface
->type
== ifType
) {
902 * Retrieve a reference to address interface for specified interface type and
903 * XML datasource tag name.
904 * \param addrIndex Address index.
905 * \param ifType Interface type to match.
906 * \param tag XML datasource tag name to match.
907 * \return Reference to address index, or NULL if not found in index.
909 static AddressInterface
*addrindex_tag_get_datasource(
910 AddressIndex
*addrIndex
, AddressIfType ifType
, gchar
*tag
)
912 AddressInterface
*retVal
= NULL
;
913 GList
*node
= addrIndex
->interfaceList
;
916 AddressInterface
*iface
= node
->data
;
917 node
= g_list_next( node
);
918 if( iface
->type
== ifType
&& iface
->itemTag
) {
919 if( strcmp( iface
->itemTag
, tag
) == 0 ) {
928 /* **********************************************************************
929 * Interface XML parsing functions.
930 * ***********************************************************************
934 * Write start of XML element to file.
936 * \param lvl Indentation level.
937 * \param name Element name.
939 static int addrindex_write_elem_s( FILE *fp
, const gint lvl
, const gchar
*name
) {
941 for( i
= 0; i
< lvl
; i
++ )
942 if (claws_fputs( " ", fp
) == EOF
)
944 if (claws_fputs( "<", fp
) == EOF
)
946 if (claws_fputs( name
, fp
) == EOF
)
952 * Write end of XML element to file.
954 * \param lvl Indentation level.
955 * \param name Element name.
957 static int addrindex_write_elem_e( FILE *fp
, const gint lvl
, const gchar
*name
) {
959 for( i
= 0; i
< lvl
; i
++ )
960 if (claws_fputs( " ", fp
) == EOF
)
962 if (claws_fputs( "</", fp
) == EOF
)
964 if (claws_fputs( name
, fp
) == EOF
)
966 if (claws_fputs( ">\n", fp
) == EOF
)
972 * Write XML attribute to file.
974 * \param name Attribute name.
975 * \param value Attribute value.
977 static int addrindex_write_attr( FILE *fp
, const gchar
*name
, const gchar
*value
) {
978 if (claws_fputs( " ", fp
) == EOF
)
980 if (claws_fputs( name
, fp
) == EOF
)
982 if (claws_fputs( "=\"", fp
) == EOF
)
984 if (xml_file_put_escape_str( fp
, value
) < 0)
986 if (claws_fputs( "\"", fp
) == EOF
)
991 #if !defined(USE_LDAP) || !defined(USE_JPILOT)
993 * Return DOM fragment for current XML tag from file.
994 * \param file XML file being processed.
995 * \return Fragment representing DOM fragment for configuration element.
997 static AddressIfFragment
*addrindex_read_fragment( XMLFile
*file
) {
998 AddressIfFragment
*fragment
;
999 AddressIfFragment
*child
;
1000 AddressIfAttrib
*nv
;
1009 /* g_print( "addrindex_read_fragment\n" ); */
1011 prevLevel
= file
->level
;
1013 /* Get current tag name */
1014 xtag
= xml_get_current_tag( file
);
1016 /* Create new fragment */
1017 fragment
= g_new0( AddressIfFragment
, 1 );
1018 fragment
->type
= ADBOOKTYPE_NONE
;
1019 fragment
->addressCache
= NULL
;
1020 fragment
->name
= g_strdup( xtag
->tag
);
1021 fragment
->children
= NULL
;
1022 fragment
->attributes
= NULL
;
1024 /* Read attributes */
1026 attr
= xml_get_current_tag_attr( file
);
1028 name
= ((XMLAttr
*)attr
->data
)->name
;
1029 value
= ((XMLAttr
*)attr
->data
)->value
;
1030 nv
= g_new0( AddressIfAttrib
, 1 );
1031 nv
->name
= g_strdup( name
);
1032 nv
->value
= g_strdup( value
);
1033 list
= g_list_append( list
, nv
);
1034 attr
= g_list_next( attr
);
1036 fragment
->attributes
= list
;
1038 /* Now read the children */
1040 rc
= xml_parse_next_tag( file
);
1045 if( file
->level
< prevLevel
) {
1046 /* We must be above level we start at */
1049 child
= addrindex_read_fragment( file
);
1050 fragment
->children
= g_list_append( fragment
->children
, child
);
1057 * Write DOM fragment to file.
1058 * \param fp File to write.
1059 * \param fragment DOM fragment for configuration element.
1060 * \param lvl Indent level.
1062 static int addrindex_write_fragment(
1063 FILE *fp
, const AddressIfFragment
*fragment
, const gint lvl
)
1068 if (addrindex_write_elem_s( fp
, lvl
, fragment
->name
) < 0)
1070 node
= fragment
->attributes
;
1072 AddressIfAttrib
*nv
= node
->data
;
1073 if (addrindex_write_attr( fp
, nv
->name
, nv
->value
) < 0)
1075 node
= g_list_next( node
);
1077 if( fragment
->children
) {
1078 if (claws_fputs(" >\n", fp
) == EOF
)
1081 /* Output children */
1082 node
= fragment
->children
;
1084 AddressIfFragment
*child
= node
->data
;
1085 if (addrindex_write_fragment( fp
, child
, 1+lvl
) < 0)
1087 node
= g_list_next( node
);
1090 /* Output closing tag */
1091 if (addrindex_write_elem_e( fp
, lvl
, fragment
->name
) < 0)
1095 if (claws_fputs(" />\n", fp
) == EOF
)
1104 * Read/parse address index file, creating a data source for a regular
1105 * intrinsic XML addressbook.
1106 * \param file Address index file.
1107 * \return Data source.
1109 static AddressDataSource
*addrindex_parse_book( XMLFile
*file
) {
1110 AddressDataSource
*ds
;
1111 AddressBookFile
*abf
;
1114 ds
= addrindex_create_datasource( ADDR_IF_BOOK
);
1115 abf
= addrbook_create_book();
1116 attr
= xml_get_current_tag_attr( file
);
1118 gchar
*name
= ((XMLAttr
*)attr
->data
)->name
;
1119 gchar
*value
= ((XMLAttr
*)attr
->data
)->value
;
1120 if( strcmp( name
, ATTAG_BOOK_NAME
) == 0 ) {
1121 addrbook_set_name( abf
, value
);
1123 else if( strcmp( name
, ATTAG_BOOK_FILE
) == 0) {
1124 addrbook_set_file( abf
, value
);
1126 attr
= g_list_next( attr
);
1128 ds
->rawDataSource
= abf
;
1132 static int addrindex_write_book( FILE *fp
, AddressDataSource
*ds
, gint lvl
) {
1133 AddressBookFile
*abf
= ds
->rawDataSource
;
1135 if (addrindex_write_elem_s( fp
, lvl
, TAG_DS_ADDRESS_BOOK
) < 0)
1137 if (addrindex_write_attr( fp
, ATTAG_BOOK_NAME
, addrbook_get_name( abf
) ) < 0)
1139 if (addrindex_write_attr( fp
, ATTAG_BOOK_FILE
, abf
->fileName
) < 0)
1141 if (claws_fputs( " />\n", fp
) == EOF
)
1147 static AddressDataSource
*addrindex_parse_vcard( XMLFile
*file
) {
1148 AddressDataSource
*ds
;
1152 ds
= addrindex_create_datasource( ADDR_IF_VCARD
);
1153 vcf
= vcard_create();
1154 attr
= xml_get_current_tag_attr( file
);
1156 gchar
*name
= ((XMLAttr
*)attr
->data
)->name
;
1157 gchar
*value
= ((XMLAttr
*)attr
->data
)->value
;
1158 if( strcmp( name
, ATTAG_VCARD_NAME
) == 0 ) {
1159 vcard_set_name( vcf
, value
);
1161 else if( strcmp( name
, ATTAG_VCARD_FILE
) == 0) {
1162 vcard_set_file( vcf
, value
);
1164 attr
= g_list_next( attr
);
1166 ds
->rawDataSource
= vcf
;
1170 static int addrindex_write_vcard( FILE *fp
, AddressDataSource
*ds
, gint lvl
) {
1171 VCardFile
*vcf
= ds
->rawDataSource
;
1173 if (addrindex_write_elem_s( fp
, lvl
, TAG_DS_VCARD
) < 0)
1175 if (addrindex_write_attr( fp
, ATTAG_VCARD_NAME
, vcard_get_name( vcf
) ) < 0)
1177 if (addrindex_write_attr( fp
, ATTAG_VCARD_FILE
, vcf
->path
) < 0)
1179 if (claws_fputs( " />\n", fp
) == EOF
)
1186 static AddressDataSource
*addrindex_parse_jpilot( XMLFile
*file
) {
1187 AddressDataSource
*ds
;
1191 ds
= addrindex_create_datasource( ADDR_IF_JPILOT
);
1192 jpf
= jpilot_create();
1193 attr
= xml_get_current_tag_attr( file
);
1195 gchar
*name
= ((XMLAttr
*)attr
->data
)->name
;
1196 gchar
*value
= ((XMLAttr
*)attr
->data
)->value
;
1197 if( strcmp( name
, ATTAG_JPILOT_NAME
) == 0 ) {
1198 jpilot_set_name( jpf
, value
);
1200 else if( strcmp( name
, ATTAG_JPILOT_FILE
) == 0 ) {
1201 jpilot_set_file( jpf
, value
);
1203 else if( strcmp( name
, ATTAG_JPILOT_CUSTOM_1
) == 0 ) {
1204 jpilot_add_custom_label( jpf
, value
);
1206 else if( strcmp( name
, ATTAG_JPILOT_CUSTOM_2
) == 0 ) {
1207 jpilot_add_custom_label( jpf
, value
);
1209 else if( strcmp( name
, ATTAG_JPILOT_CUSTOM_3
) == 0 ) {
1210 jpilot_add_custom_label( jpf
, value
);
1212 else if( strcmp( name
, ATTAG_JPILOT_CUSTOM_4
) == 0 ) {
1213 jpilot_add_custom_label( jpf
, value
);
1215 attr
= g_list_next( attr
);
1217 ds
->rawDataSource
= jpf
;
1221 static int addrindex_write_jpilot( FILE *fp
,AddressDataSource
*ds
, gint lvl
) {
1222 JPilotFile
*jpf
= ds
->rawDataSource
;
1226 GList
*customLbl
= jpilot_get_custom_labels( jpf
);
1227 if (addrindex_write_elem_s( fp
, lvl
, TAG_DS_JPILOT
) < 0)
1229 if (addrindex_write_attr( fp
, ATTAG_JPILOT_NAME
, jpilot_get_name( jpf
) ) < 0)
1231 if (addrindex_write_attr( fp
, ATTAG_JPILOT_FILE
, jpf
->path
) < 0)
1237 g_snprintf( name
, sizeof(name
), "%s%d",
1238 ATTAG_JPILOT_CUSTOM
, ind
);
1239 if (addrindex_write_attr( fp
, name
, node
->data
) < 0)
1242 node
= g_list_next( node
);
1244 if (claws_fputs( " />\n", fp
) == EOF
)
1252 * Just read/write DOM fragments (preserve data found in file).
1254 static AddressDataSource
*addrindex_parse_jpilot( XMLFile
*file
) {
1255 AddressDataSource
*ds
;
1257 ds
= addrindex_create_datasource( ADDR_IF_JPILOT
);
1258 ds
->rawDataSource
= addrindex_read_fragment( file
);
1262 static int addrindex_write_jpilot( FILE *fp
, AddressDataSource
*ds
, gint lvl
) {
1263 AddressIfFragment
*fragment
= ds
->rawDataSource
;
1265 if (addrindex_write_fragment( fp
, fragment
, lvl
) < 0)
1274 * Parse LDAP criteria attribute data from XML file.
1275 * \param file Index file.
1276 * \param ctl LDAP control object to populate.
1278 static void addrindex_parse_ldap_attrlist( XMLFile
*file
, LdapControl
*ctl
) {
1287 if( file
== NULL
) {
1292 prevLevel
= file
->level
;
1293 xtagPrev
= xml_get_current_tag( file
);
1295 rc
= xml_parse_next_tag( file
);
1297 /* Terminate prematurely */
1298 g_list_free_full( list
, g_free
);
1302 if( file
->level
< prevLevel
) {
1303 /* We must be above level we start at */
1307 /* Get a tag (element) */
1308 xtag
= xml_get_current_tag( file
);
1309 if( strcmp( xtag
->tag
, ELTAG_LDAP_ATTR_SRCH
) == 0 ) {
1310 /* LDAP criteria attribute */
1311 attr
= xml_get_current_tag_attr( file
);
1313 gchar
*name
= ((XMLAttr
*)attr
->data
)->name
;
1314 gchar
*value
= ((XMLAttr
*)attr
->data
)->value
;
1315 if( strcmp( name
, ATTAG_LDAP_ATTR_NAME
) == 0 ) {
1316 if( value
&& strlen( value
) > 0 ) {
1317 list
= g_list_append(
1318 list
, g_strdup( value
) );
1321 attr
= g_list_next( attr
);
1325 if( xtag
!= xtagPrev
) {
1326 /* Found a new tag */
1332 /* Build list of search attributes */
1333 ldapctl_criteria_list_clear( ctl
);
1336 ldapctl_criteria_list_add( ctl
, node
->data
);
1337 g_free( node
->data
);
1339 node
= g_list_next( node
);
1341 g_list_free( list
);
1346 void ldapsvr_set_control( LdapServer
*server
, LdapControl
*ctl
);
1348 * Parse LDAP control data from XML file.
1349 * \param file Index file.
1350 * \return Initialized data soruce object.
1352 static AddressDataSource
*addrindex_parse_ldap( XMLFile
*file
) {
1353 AddressDataSource
*ds
;
1357 gchar
*serverName
= NULL
;
1358 gchar
*criteria
= NULL
;
1359 gboolean bDynSearch
;
1360 gboolean bTLS
, bSSL
;
1362 gchar
*password
= NULL
;
1364 /* g_print( "addrindex_parse_ldap\n" ); */
1365 /* Set up some defaults */
1369 iMatch
= LDAPCTL_MATCH_BEGINWITH
;
1371 ds
= addrindex_create_datasource( ADDR_IF_LDAP
);
1372 ctl
= ldapctl_create();
1373 attr
= xml_get_current_tag_attr( file
);
1375 gchar
*name
= ((XMLAttr
*)attr
->data
)->name
;
1376 gchar
*value
= ((XMLAttr
*)attr
->data
)->value
;
1377 gint ivalue
= atoi( value
);
1379 if( strcmp( name
, ATTAG_LDAP_NAME
) == 0 ) {
1380 g_free( serverName
);
1381 serverName
= g_strdup( value
);
1383 else if( strcmp( name
, ATTAG_LDAP_HOST
) == 0 ) {
1384 ldapctl_set_host( ctl
, value
);
1386 else if( strcmp( name
, ATTAG_LDAP_PORT
) == 0 ) {
1387 ldapctl_set_port( ctl
, ivalue
);
1389 else if( strcmp( name
, ATTAG_LDAP_BASE_DN
) == 0 ) {
1390 ldapctl_set_base_dn( ctl
, value
);
1392 else if( strcmp( name
, ATTAG_LDAP_BIND_DN
) == 0 ) {
1393 ldapctl_set_bind_dn( ctl
, value
);
1395 else if( strcmp( name
, ATTAG_LDAP_BIND_PASS
) == 0 ) {
1398 else if( strcmp( name
, ATTAG_LDAP_CRITERIA
) == 0 ) {
1400 criteria
= g_strdup( value
);
1401 g_print("criteria %s\n", criteria
);
1403 else if( strcmp( name
, ATTAG_LDAP_MAX_ENTRY
) == 0 ) {
1404 ldapctl_set_max_entries( ctl
, ivalue
);
1406 else if( strcmp( name
, ATTAG_LDAP_TIMEOUT
) == 0 ) {
1407 ldapctl_set_timeout( ctl
, ivalue
);
1409 else if( strcmp( name
, ATTAG_LDAP_MAX_AGE
) == 0 ) {
1410 ldapctl_set_max_query_age( ctl
, ivalue
);
1412 else if( strcmp( name
, ATTAG_LDAP_DYN_SEARCH
) == 0 ) {
1414 if( strcmp( value
, ATVAL_BOOLEAN_YES
) == 0 ) {
1418 else if( strcmp( name
, ATTAG_LDAP_MATCH_OPT
) == 0 ) {
1419 iMatch
= LDAPCTL_MATCH_BEGINWITH
;
1420 if( strcmp( value
, ATVAL_LDAP_MATCH_CONTAINS
) == 0 ) {
1421 iMatch
= LDAPCTL_MATCH_CONTAINS
;
1424 else if( strcmp( name
, ATTAG_LDAP_ENABLE_TLS
) == 0 ) {
1426 if( strcmp( value
, ATVAL_BOOLEAN_YES
) == 0 ) {
1430 else if( strcmp( name
, ATTAG_LDAP_ENABLE_SSL
) == 0 ) {
1432 if( strcmp( value
, ATVAL_BOOLEAN_YES
) == 0 ) {
1436 attr
= g_list_next( attr
);
1439 if (password
!= NULL
)
1440 passwd_store_set(PWS_CORE
, "LDAP", ctl
->hostName
, password
, TRUE
);
1442 server
= ldapsvr_create_noctl();
1443 ldapsvr_set_name( server
, serverName
);
1444 ldapsvr_set_search_flag( server
, bDynSearch
);
1445 ldapctl_set_matching_option( ctl
, iMatch
);
1446 ldapctl_set_tls( ctl
, bTLS
);
1447 ldapctl_set_ssl( ctl
, bSSL
);
1448 g_free( serverName
);
1449 ldapsvr_set_control( server
, ctl
);
1450 ds
->rawDataSource
= server
;
1452 addrindex_parse_ldap_attrlist( file
, ctl
);
1454 * If criteria have been specified and no attributes were listed, then
1455 * convert old style criteria into an attribute list. Any criteria will
1456 * be dropped when saving data.
1459 if( ! ldapctl_get_criteria_list( ctl
) ) {
1460 ldapctl_parse_ldap_search( ctl
, criteria
);
1464 /* ldapsvr_print_data( server, stdout ); */
1469 static int addrindex_write_ldap( FILE *fp
, AddressDataSource
*ds
, gint lvl
) {
1470 LdapServer
*server
= ds
->rawDataSource
;
1471 LdapControl
*ctl
= NULL
;
1476 ctl
= server
->control
;
1478 if( ctl
== NULL
) return 0;
1480 /* Output start element with attributes */
1481 if (addrindex_write_elem_s( fp
, lvl
, TAG_DS_LDAP
) < 0)
1483 if (addrindex_write_attr( fp
, ATTAG_LDAP_NAME
, ldapsvr_get_name( server
) ) < 0)
1485 if (addrindex_write_attr( fp
, ATTAG_LDAP_HOST
, ctl
->hostName
) < 0)
1488 sprintf( value
, "%d", ctl
->port
);
1489 if (addrindex_write_attr( fp
, ATTAG_LDAP_PORT
, value
) < 0)
1492 if (addrindex_write_attr( fp
, ATTAG_LDAP_BASE_DN
, ctl
->baseDN
) < 0)
1494 if (addrindex_write_attr( fp
, ATTAG_LDAP_BIND_DN
, ctl
->bindDN
) < 0)
1497 sprintf( value
, "%d", ctl
->maxEntries
);
1498 if (addrindex_write_attr( fp
, ATTAG_LDAP_MAX_ENTRY
, value
) < 0)
1500 sprintf( value
, "%d", ctl
->timeOut
);
1501 if (addrindex_write_attr( fp
, ATTAG_LDAP_TIMEOUT
, value
) < 0)
1503 sprintf( value
, "%d", ctl
->maxQueryAge
);
1504 if (addrindex_write_attr( fp
, ATTAG_LDAP_MAX_AGE
, value
) < 0)
1507 if (addrindex_write_attr( fp
, ATTAG_LDAP_DYN_SEARCH
,
1508 server
->searchFlag
?
1509 ATVAL_BOOLEAN_YES
: ATVAL_BOOLEAN_NO
) < 0)
1512 if (addrindex_write_attr( fp
, ATTAG_LDAP_MATCH_OPT
,
1513 ( ctl
->matchingOption
== LDAPCTL_MATCH_CONTAINS
) ?
1514 ATVAL_LDAP_MATCH_CONTAINS
: ATVAL_LDAP_MATCH_BEGIN
) < 0)
1517 if (addrindex_write_attr( fp
, ATTAG_LDAP_ENABLE_TLS
,
1519 ATVAL_BOOLEAN_YES
: ATVAL_BOOLEAN_NO
) < 0)
1521 if (addrindex_write_attr( fp
, ATTAG_LDAP_ENABLE_SSL
,
1523 ATVAL_BOOLEAN_YES
: ATVAL_BOOLEAN_NO
) < 0)
1526 if (claws_fputs(" >\n", fp
) == EOF
)
1529 /* Output attributes */
1530 node
= ldapctl_get_criteria_list( ctl
);
1532 if (addrindex_write_elem_s( fp
, 1+lvl
, ELTAG_LDAP_ATTR_SRCH
) < 0)
1534 if (addrindex_write_attr( fp
, ATTAG_LDAP_ATTR_NAME
, node
->data
) < 0)
1536 if (claws_fputs(" />\n", fp
) == EOF
)
1538 node
= g_list_next( node
);
1541 /* End of element */
1542 if (addrindex_write_elem_e( fp
, lvl
, TAG_DS_LDAP
) < 0)
1550 * Just read/write DOM fragments (preserve data found in file).
1552 static AddressDataSource
*addrindex_parse_ldap( XMLFile
*file
) {
1553 AddressDataSource
*ds
;
1555 ds
= addrindex_create_datasource( ADDR_IF_LDAP
);
1556 ds
->rawDataSource
= addrindex_read_fragment( file
);
1560 static int addrindex_write_ldap( FILE *fp
, AddressDataSource
*ds
, gint lvl
) {
1561 AddressIfFragment
*fragment
= ds
->rawDataSource
;
1563 if (addrindex_write_fragment( fp
, fragment
, lvl
) < 0)
1570 /* **********************************************************************
1571 * Address index I/O functions.
1572 * ***********************************************************************
1575 * Read address index file, creating appropriate data sources for each address
1578 * \param addrIndex Address index.
1579 * \param file Address index file.
1581 static void addrindex_read_index( AddressIndex
*addrIndex
, XMLFile
*file
) {
1583 AddressInterface
*iface
= NULL
, *dsIFace
= NULL
;
1584 AddressDataSource
*ds
;
1587 addrIndex
->loadedFlag
= FALSE
;
1589 rc
= xml_parse_next_tag( file
);
1590 if( rc
< 0 || file
->level
== 0 ) return;
1592 xtag
= xml_get_current_tag( file
);
1594 iface
= addrindex_tag_get_interface( addrIndex
, xtag
->tag
, ADDR_IF_NONE
);
1596 addrIndex
->lastType
= iface
->type
;
1597 if( iface
->legacyFlag
) addrIndex
->needsConversion
= TRUE
;
1600 dsIFace
= addrindex_tag_get_datasource(
1601 addrIndex
, addrIndex
->lastType
, xtag
->tag
);
1603 /* Add data source to list */
1605 if( addrIndex
->lastType
== ADDR_IF_BOOK
) {
1606 ds
= addrindex_parse_book( file
);
1607 if( ds
->rawDataSource
) {
1608 addrbook_set_path( ds
->rawDataSource
,
1609 addrIndex
->filePath
);
1612 else if( addrIndex
->lastType
== ADDR_IF_VCARD
) {
1613 ds
= addrindex_parse_vcard( file
);
1615 else if( addrIndex
->lastType
== ADDR_IF_JPILOT
) {
1616 ds
= addrindex_parse_jpilot( file
);
1618 else if( addrIndex
->lastType
== ADDR_IF_LDAP
) {
1619 ds
= addrindex_parse_ldap( file
);
1622 ds
->interface
= dsIFace
;
1623 addrindex_hash_add_cache( addrIndex
, ds
);
1624 dsIFace
->listSource
=
1625 g_list_append( dsIFace
->listSource
, ds
);
1633 * Search order sorting comparison function for building search order list.
1635 static gint
addrindex_search_order_compare( gconstpointer ptrA
, gconstpointer ptrB
) {
1636 AddressInterface
*ifaceA
= ( AddressInterface
* ) ptrA
;
1637 AddressInterface
*ifaceB
= ( AddressInterface
* ) ptrB
;
1639 return ifaceA
->searchOrder
- ifaceB
->searchOrder
;
1643 * Build list of data sources to process.
1644 * \param addrIndex Address index object.
1646 static void addrindex_build_search_order( AddressIndex
*addrIndex
) {
1649 /* Clear existing list */
1650 g_list_free( addrIndex
->searchOrder
);
1651 addrIndex
->searchOrder
= NULL
;
1653 /* Build new list */
1654 nodeIf
= addrIndex
->interfaceList
;
1656 AddressInterface
*iface
= nodeIf
->data
;
1657 if( iface
->useInterface
) {
1658 if( iface
->searchOrder
> 0 ) {
1659 /* Add to search order list */
1660 addrIndex
->searchOrder
= g_list_insert_sorted(
1661 addrIndex
->searchOrder
, iface
,
1662 addrindex_search_order_compare
);
1665 nodeIf
= g_list_next( nodeIf
);
1669 static gint
addrindex_read_file( AddressIndex
*addrIndex
) {
1670 XMLFile
*file
= NULL
;
1671 gchar
*fileSpec
= NULL
;
1673 cm_return_val_if_fail( addrIndex
!= NULL
, -1 );
1675 fileSpec
= g_strconcat( addrIndex
->filePath
, G_DIR_SEPARATOR_S
, addrIndex
->fileName
, NULL
);
1676 addrIndex
->retVal
= MGU_NO_FILE
;
1677 file
= xml_open_file( fileSpec
);
1680 if( file
== NULL
) {
1682 g_print( " file '%s' does not exist.\n", addrIndex->fileName );
1684 return addrIndex
->retVal
;
1687 addrIndex
->retVal
= MGU_BAD_FORMAT
;
1688 if( xml_get_dtd( file
) == 0 ) {
1689 if( xml_parse_next_tag( file
) == 0 ) {
1690 if( xml_compare_tag( file
, TAG_ADDRESS_INDEX
) ) {
1691 addrindex_read_index( addrIndex
, file
);
1692 addrIndex
->retVal
= MGU_SUCCESS
;
1696 xml_close_file( file
);
1698 addrindex_build_search_order( addrIndex
);
1700 return addrIndex
->retVal
;
1703 static int addrindex_write_index( AddressIndex
*addrIndex
, FILE *fp
) {
1704 GList
*nodeIF
, *nodeDS
;
1706 gint lvlItem
= 1 + lvlList
;
1708 nodeIF
= addrIndex
->interfaceList
;
1710 AddressInterface
*iface
= nodeIF
->data
;
1711 if( ! iface
->legacyFlag
) {
1712 nodeDS
= iface
->listSource
;
1713 if (addrindex_write_elem_s( fp
, lvlList
, iface
->listTag
) < 0)
1715 if (claws_fputs( ">\n", fp
) == EOF
)
1718 AddressDataSource
*ds
= nodeDS
->data
;
1720 if( iface
->type
== ADDR_IF_BOOK
) {
1721 if (addrindex_write_book( fp
, ds
, lvlItem
) < 0)
1724 if( iface
->type
== ADDR_IF_VCARD
) {
1725 if (addrindex_write_vcard( fp
, ds
, lvlItem
) < 0)
1728 if( iface
->type
== ADDR_IF_JPILOT
) {
1729 if (addrindex_write_jpilot( fp
, ds
, lvlItem
) < 0)
1732 if( iface
->type
== ADDR_IF_LDAP
) {
1733 if (addrindex_write_ldap( fp
, ds
, lvlItem
) < 0)
1737 nodeDS
= g_list_next( nodeDS
);
1739 if (addrindex_write_elem_e( fp
, lvlList
, iface
->listTag
) < 0)
1742 nodeIF
= g_list_next( nodeIF
);
1748 * Write data to specified file.
1749 * Enter: addrIndex Address index object.
1750 * newFile New file name.
1751 * return: Status code, from addrIndex->retVal.
1752 * Note: File will be created in directory specified by addrIndex.
1754 static gint
addrindex_write_to( AddressIndex
*addrIndex
, const gchar
*newFile
) {
1757 #ifndef DEV_STANDALONE
1761 cm_return_val_if_fail( addrIndex
!= NULL
, -1 );
1763 fileSpec
= g_strconcat( addrIndex
->filePath
, G_DIR_SEPARATOR_S
, newFile
, NULL
);
1764 addrIndex
->retVal
= MGU_OPEN_FILE
;
1765 #ifdef DEV_STANDALONE
1766 fp
= claws_fopen( fileSpec
, "wb" );
1769 claws_fputs( "<?xml version=\"1.0\" ?>\n", fp
);
1771 pfile
= prefs_write_open( fileSpec
);
1775 if (fprintf( fp
, "<?xml version=\"1.0\" encoding=\"%s\" ?>\n", CS_INTERNAL
) < 0)
1778 if (addrindex_write_elem_s( fp
, 0, TAG_ADDRESS_INDEX
) < 0)
1780 if (claws_fputs( ">\n", fp
) == EOF
)
1783 if (addrindex_write_index( addrIndex
, fp
) < 0)
1785 if (addrindex_write_elem_e( fp
, 0, TAG_ADDRESS_INDEX
) < 0)
1788 addrIndex
->retVal
= MGU_SUCCESS
;
1789 #ifdef DEV_STANDALONE
1790 claws_safe_fclose( fp
);
1792 if( prefs_file_close( pfile
) < 0 ) {
1793 addrIndex
->retVal
= MGU_ERROR_WRITE
;
1799 return addrIndex
->retVal
;
1801 g_warning("error writing AB index");
1802 addrIndex
->retVal
= MGU_ERROR_WRITE
;
1804 prefs_file_close_revert( pfile
);
1805 return addrIndex
->retVal
;
1809 * Save address index data to original file.
1810 * return: Status code, from addrIndex->retVal.
1812 gint
addrindex_save_data( AddressIndex
*addrIndex
) {
1818 cm_return_val_if_fail( addrIndex
!= NULL
, -1 );
1821 nodeIf
= addrIndex
->interfaceList
;
1822 /* save LDAP interfaces */
1824 AddressInterface
*iface
= nodeIf
->data
;
1825 if( iface
->type
== ADDR_IF_LDAP
) {
1826 nodeDS
= iface
->listSource
;
1828 AddressDataSource
*ds
= nodeDS
->data
;
1829 LdapServer
*abf
= ds
->rawDataSource
;
1830 if( ldapsvr_get_read_flag( abf
) ) {
1831 if( ldapsvr_get_modified( abf
) ) {
1832 ldapsvr_update_book( abf
, NULL
);
1833 if( abf
->retVal
!= LDAPRC_SUCCESS
) {
1834 alertpanel( _("Address(es) update"),
1835 _("Update failed. Changes not written to Directory."),
1836 "window-close", _("_Close"), NULL
, NULL
,
1837 NULL
, NULL
, ALERTFOCUS_FIRST
);
1840 abf
->retVal
= MGU_SUCCESS
;
1841 ldapsvr_set_modified( abf
, FALSE
);
1845 nodeDS
= g_list_next( nodeDS
);
1849 nodeIf
= g_list_next( nodeIf
);
1852 addrIndex
->retVal
= MGU_NO_FILE
;
1853 if( addrIndex
->fileName
== NULL
|| *addrIndex
->fileName
== '\0' ) return addrIndex
->retVal
;
1854 if( addrIndex
->filePath
== NULL
|| *addrIndex
->filePath
== '\0' ) return addrIndex
->retVal
;
1856 addrindex_write_to( addrIndex
, addrIndex
->fileName
);
1857 if( addrIndex
->retVal
== MGU_SUCCESS
) {
1858 addrIndex
->dirtyFlag
= FALSE
;
1860 return addrIndex
->retVal
;
1864 * Save all address book files which may have changed.
1865 * Return: Status code, set if there was a problem saving data.
1867 gint
addrindex_save_all_books( AddressIndex
*addrIndex
) {
1868 gint retVal
= MGU_SUCCESS
;
1869 GList
*nodeIf
, *nodeDS
;
1871 nodeIf
= addrIndex
->interfaceList
;
1873 AddressInterface
*iface
= nodeIf
->data
;
1874 if( iface
->type
== ADDR_IF_BOOK
) {
1875 nodeDS
= iface
->listSource
;
1877 AddressDataSource
*ds
= nodeDS
->data
;
1878 AddressBookFile
*abf
= ds
->rawDataSource
;
1879 if( addrbook_get_dirty( abf
) ) {
1880 if( addrbook_get_read_flag( abf
) ) {
1881 addrbook_save_data( abf
);
1882 if( abf
->retVal
!= MGU_SUCCESS
) {
1883 retVal
= abf
->retVal
;
1887 nodeDS
= g_list_next( nodeDS
);
1891 nodeIf
= g_list_next( nodeIf
);
1897 /* **********************************************************************
1898 * Address book conversion to new format.
1899 * ***********************************************************************
1902 #define ELTAG_IF_OLD_FOLDER "folder"
1903 #define ELTAG_IF_OLD_GROUP "group"
1904 #define ELTAG_IF_OLD_ITEM "item"
1905 #define ELTAG_IF_OLD_NAME "name"
1906 #define ELTAG_IF_OLD_ADDRESS "address"
1907 #define ELTAG_IF_OLD_REMARKS "remarks"
1908 #define ATTAG_IF_OLD_NAME "name"
1910 #define TEMPNODE_ROOT 0
1911 #define TEMPNODE_FOLDER 1
1912 #define TEMPNODE_GROUP 2
1913 #define TEMPNODE_ADDRESS 3
1915 typedef struct _AddressCvt_Node AddressCvtNode
;
1916 struct _AddressCvt_Node
{
1925 * Parse current address item.
1927 static AddressCvtNode
*addrindex_parse_item( XMLFile
*file
) {
1932 nn
= g_new0( AddressCvtNode
, 1 );
1933 nn
->type
= TEMPNODE_ADDRESS
;
1936 level
= file
->level
;
1939 xml_parse_next_tag(file
);
1940 if (file
->level
< level
) return nn
;
1942 element
= xml_get_element( file
);
1943 if( xml_compare_tag( file
, ELTAG_IF_OLD_NAME
) ) {
1944 nn
->name
= g_strdup( element
);
1946 if( xml_compare_tag( file
, ELTAG_IF_OLD_ADDRESS
) ) {
1947 nn
->address
= g_strdup( element
);
1949 if( xml_compare_tag( file
, ELTAG_IF_OLD_REMARKS
) ) {
1950 nn
->remarks
= g_strdup( element
);
1953 xml_parse_next_tag(file
);
1958 * Create a temporary node below specified node.
1960 static AddressCvtNode
*addrindex_add_object( AddressCvtNode
*node
, gint type
, gchar
*name
, gchar
*addr
, char *rem
) {
1962 nn
= g_new0( AddressCvtNode
, 1 );
1964 nn
->name
= g_strdup( name
);
1965 nn
->remarks
= g_strdup( rem
);
1966 node
->list
= g_list_append( node
->list
, nn
);
1971 * Process current temporary node.
1973 static void addrindex_add_obj( XMLFile
*file
, AddressCvtNode
*node
) {
1976 AddressCvtNode
*newNode
= NULL
;
1981 prev_level
= file
->level
;
1982 xml_parse_next_tag( file
);
1983 if (file
->level
< prev_level
) return;
1987 if( xml_compare_tag( file
, ELTAG_IF_OLD_GROUP
) ) {
1988 attr
= xml_get_current_tag_attr(file
);
1990 name
= ((XMLAttr
*)attr
->data
)->name
;
1991 if( strcmp( name
, ATTAG_IF_OLD_NAME
) == 0 ) {
1992 value
= ((XMLAttr
*)attr
->data
)->value
;
1995 newNode
= addrindex_add_object( node
, TEMPNODE_GROUP
, value
, "", "" );
1996 addrindex_add_obj( file
, newNode
);
1999 else if( xml_compare_tag( file
, ELTAG_IF_OLD_FOLDER
) ) {
2000 attr
= xml_get_current_tag_attr(file
);
2002 name
= ((XMLAttr
*)attr
->data
)->name
;
2003 if( strcmp( name
, ATTAG_IF_OLD_NAME
) == 0 ) {
2004 value
= ((XMLAttr
*)attr
->data
)->value
;
2007 newNode
= addrindex_add_object( node
, TEMPNODE_FOLDER
, value
, "", "" );
2008 addrindex_add_obj( file
, newNode
);
2010 else if( xml_compare_tag( file
, ELTAG_IF_OLD_ITEM
) ) {
2011 newNode
= addrindex_parse_item( file
);
2012 node
->list
= g_list_append( node
->list
, newNode
);
2015 g_warning("invalid tag");
2021 * Consume all nodes below current tag.
2023 static void addrindex_consume_tree( XMLFile
*file
) {
2027 prev_level
= file
->level
;
2028 xml_parse_next_tag( file
);
2029 if (file
->level
< prev_level
)
2032 addrindex_consume_tree( file
);
2037 * Free up temporary tree.
2039 static void addrindex_free_node( AddressCvtNode
*node
) {
2040 GList
*list
= node
->list
;
2043 AddressCvtNode
*lNode
= list
->data
;
2044 list
= g_list_next( list
);
2045 addrindex_free_node( lNode
);
2047 node
->type
= TEMPNODE_ROOT
;
2048 g_free( node
->name
);
2049 g_free( node
->address
);
2050 g_free( node
->remarks
);
2051 g_list_free( node
->list
);
2056 * Process address book for specified node.
2058 static void addrindex_process_node(
2059 AddressBookFile
*abf
, AddressCvtNode
*node
, ItemFolder
*parent
,
2060 ItemGroup
*parentGrp
, ItemFolder
*folderGrp
)
2063 ItemFolder
*itemFolder
= NULL
;
2064 ItemGroup
*itemGParent
= parentGrp
;
2065 ItemFolder
*itemGFolder
= folderGrp
;
2066 AddressCache
*cache
= abf
->addressCache
;
2068 if( node
->type
== TEMPNODE_ROOT
) {
2069 itemFolder
= parent
;
2071 else if( node
->type
== TEMPNODE_FOLDER
) {
2072 itemFolder
= addritem_create_item_folder();
2073 addritem_folder_set_name( itemFolder
, node
->name
);
2074 addrcache_id_folder( cache
, itemFolder
);
2075 addrcache_folder_add_folder( cache
, parent
, itemFolder
);
2078 else if( node
->type
== TEMPNODE_GROUP
) {
2079 ItemGroup
*itemGroup
;
2082 /* Create a folder for group */
2083 fName
= g_strdup_printf( "Cvt - %s", node
->name
);
2084 itemGFolder
= addritem_create_item_folder();
2085 addritem_folder_set_name( itemGFolder
, fName
);
2086 addrcache_id_folder( cache
, itemGFolder
);
2087 addrcache_folder_add_folder( cache
, parent
, itemGFolder
);
2090 /* Add group into folder */
2091 itemGroup
= addritem_create_item_group();
2092 addritem_group_set_name( itemGroup
, node
->name
);
2093 addrcache_id_group( cache
, itemGroup
);
2094 addrcache_folder_add_group( cache
, itemGFolder
, itemGroup
);
2095 itemGParent
= itemGroup
;
2097 else if( node
->type
== TEMPNODE_ADDRESS
) {
2098 ItemPerson
*itemPerson
;
2099 ItemEMail
*itemEMail
;
2101 /* Create person and email objects */
2102 itemPerson
= addritem_create_item_person();
2103 addritem_person_set_common_name( itemPerson
, node
->name
);
2104 addrcache_id_person( cache
, itemPerson
);
2105 itemEMail
= addritem_create_item_email();
2106 addritem_email_set_address( itemEMail
, node
->address
);
2107 addritem_email_set_remarks( itemEMail
, node
->remarks
);
2108 addrcache_id_email( cache
, itemEMail
);
2109 addrcache_person_add_email( cache
, itemPerson
, itemEMail
);
2111 /* Add person into appropriate folder */
2113 addrcache_folder_add_person( cache
, itemGFolder
, itemPerson
);
2116 addrcache_folder_add_person( cache
, parent
, itemPerson
);
2119 /* Add email address only into group */
2121 addrcache_group_add_email( cache
, parentGrp
, itemEMail
);
2127 AddressCvtNode
*lNode
= list
->data
;
2128 list
= g_list_next( list
);
2129 addrindex_process_node( abf
, lNode
, itemFolder
, itemGParent
, itemGFolder
);
2134 * Process address book to specified file number.
2136 static gboolean
addrindex_process_book( AddressIndex
*addrIndex
, XMLFile
*file
, gchar
*displayName
) {
2137 gboolean retVal
= FALSE
;
2138 AddressBookFile
*abf
= NULL
;
2139 AddressCvtNode
*rootNode
= NULL
;
2140 gchar
*newFile
= NULL
;
2141 GList
*fileList
= NULL
;
2144 /* Setup root node */
2145 rootNode
= g_new0( AddressCvtNode
, 1 );
2146 rootNode
->type
= TEMPNODE_ROOT
;
2147 rootNode
->name
= g_strdup( "root" );
2148 rootNode
->list
= NULL
;
2149 addrindex_add_obj( file
, rootNode
);
2150 /* addrindex_print_node( rootNode, stdout ); */
2152 /* Create new address book */
2153 abf
= addrbook_create_book();
2154 addrbook_set_name( abf
, displayName
);
2155 addrbook_set_path( abf
, addrIndex
->filePath
);
2157 /* Determine next available file number */
2158 fileList
= addrbook_get_bookfile_list( abf
);
2160 fileNum
= 1 + abf
->maxValue
;
2162 g_list_free( fileList
);
2165 newFile
= addrbook_gen_new_file_name( fileNum
);
2167 addrbook_set_file( abf
, newFile
);
2170 addrindex_process_node( abf
, rootNode
, abf
->addressCache
->rootFolder
, NULL
, NULL
);
2172 /* addrbook_dump_book( abf, stdout ); */
2173 addrbook_save_data( abf
);
2174 addrIndex
->retVal
= abf
->retVal
;
2175 if( abf
->retVal
== MGU_SUCCESS
) retVal
= TRUE
;
2177 addrbook_free_book( abf
);
2179 addrindex_free_node( rootNode
);
2182 /* Create entries in address index */
2184 abf
= addrbook_create_book();
2185 addrbook_set_name( abf
, displayName
);
2186 addrbook_set_path( abf
, addrIndex
->filePath
);
2187 addrbook_set_file( abf
, newFile
);
2188 addrindex_index_add_datasource( addrIndex
, ADDR_IF_BOOK
, abf
);
2195 * Process tree converting data.
2197 static void addrindex_convert_tree( AddressIndex
*addrIndex
, XMLFile
*file
) {
2203 prev_level
= file
->level
;
2204 xml_parse_next_tag( file
);
2205 if (file
->level
< prev_level
) return;
2207 xtag
= xml_get_current_tag( file
);
2208 /* g_print( "tag : %d : %s\n", prev_level, xtag->tag ); */
2209 if( strcmp( xtag
->tag
, TAG_IF_OLD_COMMON
) == 0 ) {
2210 if( addrindex_process_book( addrIndex
, file
, DISP_OLD_COMMON
) ) {
2211 addrIndex
->needsConversion
= FALSE
;
2212 addrIndex
->wasConverted
= TRUE
;
2217 if( strcmp( xtag
->tag
, TAG_IF_OLD_PERSONAL
) == 0 ) {
2218 if( addrindex_process_book( addrIndex
, file
, DISP_OLD_PERSONAL
) ) {
2219 addrIndex
->needsConversion
= FALSE
;
2220 addrIndex
->wasConverted
= TRUE
;
2225 addrindex_consume_tree( file
);
2229 static gint
addrindex_convert_data( AddressIndex
*addrIndex
) {
2230 XMLFile
*file
= NULL
;
2233 fileSpec
= g_strconcat( addrIndex
->filePath
, G_DIR_SEPARATOR_S
, addrIndex
->fileName
, NULL
);
2234 addrIndex
->retVal
= MGU_NO_FILE
;
2235 file
= xml_open_file( fileSpec
);
2238 if( file
== NULL
) {
2239 /* g_print( " file '%s' does not exist.\n", addrIndex->fileName ); */
2240 return addrIndex
->retVal
;
2243 addrIndex
->retVal
= MGU_BAD_FORMAT
;
2244 if( xml_get_dtd( file
) == 0 ) {
2245 if( xml_parse_next_tag( file
) == 0 ) {
2246 if( xml_compare_tag( file
, TAG_ADDRESS_INDEX
) ) {
2247 addrindex_convert_tree( addrIndex
, file
);
2251 xml_close_file( file
);
2252 return addrIndex
->retVal
;
2256 * Create a new address book file.
2258 static gboolean
addrindex_create_new_book( AddressIndex
*addrIndex
, gchar
*displayName
) {
2259 gboolean retVal
= FALSE
;
2260 AddressBookFile
*abf
= NULL
;
2261 gchar
*newFile
= NULL
;
2262 GList
*fileList
= NULL
;
2265 /* Create new address book */
2266 abf
= addrbook_create_book();
2267 addrbook_set_name( abf
, displayName
);
2268 addrbook_set_path( abf
, addrIndex
->filePath
);
2270 /* Determine next available file number */
2271 fileList
= addrbook_get_bookfile_list( abf
);
2273 fileNum
= 1 + abf
->maxValue
;
2275 g_list_free( fileList
);
2278 newFile
= addrbook_gen_new_file_name( fileNum
);
2280 addrbook_set_file( abf
, newFile
);
2283 addrbook_save_data( abf
);
2284 addrIndex
->retVal
= abf
->retVal
;
2285 if( abf
->retVal
== MGU_SUCCESS
) retVal
= TRUE
;
2286 addrbook_free_book( abf
);
2289 /* Create entries in address index */
2291 abf
= addrbook_create_book();
2292 addrbook_set_name( abf
, displayName
);
2293 addrbook_set_path( abf
, addrIndex
->filePath
);
2294 addrbook_set_file( abf
, newFile
);
2295 addrindex_index_add_datasource( addrIndex
, ADDR_IF_BOOK
, abf
);
2302 * Read data for address index performing a conversion if necesary.
2303 * Enter: addrIndex Address index object.
2304 * return: Status code, from addrIndex->retVal.
2305 * Note: New address book files will be created in directory specified by
2306 * addrIndex. Three files will be created, for the following:
2307 * "Common addresses"
2308 * "Personal addresses"
2309 * "Gathered addresses" - a new address book.
2311 gint
addrindex_read_data( AddressIndex
*addrIndex
) {
2312 cm_return_val_if_fail( addrIndex
!= NULL
, -1 );
2314 addrIndex
->conversionError
= FALSE
;
2315 addrindex_read_file( addrIndex
);
2316 if( addrIndex
->retVal
== MGU_SUCCESS
) {
2317 if( addrIndex
->needsConversion
) {
2318 if( addrindex_convert_data( addrIndex
) == MGU_SUCCESS
)
2319 addrIndex
->conversionError
= FALSE
;
2321 addrIndex
->conversionError
= TRUE
;
2323 addrIndex
->dirtyFlag
= TRUE
;
2325 return addrIndex
->retVal
;
2329 * Create new address books for a new address index.
2330 * Enter: addrIndex Address index object.
2331 * return: Status code, from addrIndex->retVal.
2332 * Note: New address book files will be created in directory specified by
2333 * addrIndex. Three files will be created, for the following:
2334 * "Common addresses"
2335 * "Personal addresses"
2336 * "Gathered addresses" - a new address book.
2338 gint
addrindex_create_new_books( AddressIndex
*addrIndex
) {
2341 cm_return_val_if_fail( addrIndex
!= NULL
, -1 );
2343 flg
= addrindex_create_new_book( addrIndex
, DISP_NEW_COMMON
);
2345 flg
= addrindex_create_new_book( addrIndex
, DISP_NEW_PERSONAL
);
2346 addrIndex
->dirtyFlag
= TRUE
;
2348 return addrIndex
->retVal
;
2351 /* **********************************************************************
2352 * New interface stuff.
2353 * ***********************************************************************
2357 * Return modified flag for specified data source.
2359 gboolean
addrindex_ds_get_modify_flag( AddressDataSource
*ds
) {
2360 gboolean retVal
= FALSE
;
2361 AddressInterface
*iface
;
2363 if( ds
== NULL
) return retVal
;
2364 iface
= ds
->interface
;
2365 if( iface
== NULL
) return retVal
;
2366 if( iface
->getModifyFlag
) {
2367 retVal
= ( iface
->getModifyFlag
) ( ds
->rawDataSource
);
2373 * Return accessed flag for specified data source.
2375 gboolean
addrindex_ds_get_access_flag( AddressDataSource
*ds
) {
2376 gboolean retVal
= FALSE
;
2377 AddressInterface
*iface
;
2379 if( ds
== NULL
) return retVal
;
2380 iface
= ds
->interface
;
2381 if( iface
== NULL
) return retVal
;
2382 if( iface
->getAccessFlag
) {
2383 retVal
= ( iface
->getAccessFlag
) ( ds
->rawDataSource
);
2389 * Return data read flag for specified data source.
2391 gboolean
addrindex_ds_get_read_flag( AddressDataSource
*ds
) {
2392 gboolean retVal
= TRUE
;
2393 AddressInterface
*iface
;
2395 if( ds
== NULL
) return retVal
;
2396 iface
= ds
->interface
;
2397 if( iface
== NULL
) return retVal
;
2398 if( iface
->getReadFlag
) {
2399 retVal
= ( iface
->getReadFlag
) ( ds
->rawDataSource
);
2405 * Return status code for specified data source.
2407 gint
addrindex_ds_get_status_code( AddressDataSource
*ds
) {
2408 gint retVal
= MGU_SUCCESS
;
2409 AddressInterface
*iface
;
2411 if( ds
== NULL
) return retVal
;
2412 iface
= ds
->interface
;
2413 if( iface
== NULL
) return retVal
;
2414 if( iface
->getStatusCode
) {
2415 retVal
= ( iface
->getStatusCode
) ( ds
->rawDataSource
);
2421 * Return data read flag for specified data source.
2423 gint
addrindex_ds_read_data( AddressDataSource
*ds
) {
2424 gint retVal
= MGU_SUCCESS
;
2425 AddressInterface
*iface
;
2427 if( ds
== NULL
) return retVal
;
2428 iface
= ds
->interface
;
2429 if( iface
== NULL
) return retVal
;
2430 if( iface
->getReadData
) {
2432 gchar *name = ( iface->getName ) ( ds->rawDataSource );
2433 g_print( "addrindex_ds_read_data...reading:::%s:::\n", name );
2435 retVal
= ( iface
->getReadData
) ( ds
->rawDataSource
);
2441 * Return data read flag for specified data source.
2443 ItemFolder
*addrindex_ds_get_root_folder( AddressDataSource
*ds
) {
2444 ItemFolder
*retVal
= NULL
;
2445 AddressInterface
*iface
;
2447 if( ds
== NULL
) return retVal
;
2448 iface
= ds
->interface
;
2449 if( iface
== NULL
) return retVal
;
2450 if( iface
->getRootFolder
) {
2451 retVal
= ( iface
->getRootFolder
) ( ds
->rawDataSource
);
2457 * Return name for specified data source.
2459 gchar
*addrindex_ds_get_name( AddressDataSource
*ds
) {
2460 gchar
*retVal
= FALSE
;
2461 AddressInterface
*iface
;
2463 if( ds
== NULL
) return retVal
;
2464 iface
= ds
->interface
;
2465 if( iface
== NULL
) return retVal
;
2466 if( iface
->getName
) {
2467 retVal
= ( iface
->getName
) ( ds
->rawDataSource
);
2473 * Set the access flag inside the data source.
2475 void addrindex_ds_set_access_flag( AddressDataSource
*ds
, gboolean
*value
) {
2476 AddressInterface
*iface
;
2478 if( ds
== NULL
) return;
2479 iface
= ds
->interface
;
2480 if( iface
== NULL
) return;
2481 if( iface
->setAccessFlag
) {
2482 ( iface
->setAccessFlag
) ( ds
->rawDataSource
, value
);
2487 * Return read only flag for specified data source.
2489 gboolean
addrindex_ds_get_readonly( AddressDataSource
*ds
) {
2490 AddressInterface
*iface
;
2491 if( ds
== NULL
) return TRUE
;
2492 iface
= ds
->interface
;
2493 if( iface
== NULL
) return TRUE
;
2494 return iface
->readOnly
;
2498 * Return list of all persons for specified data source.
2500 static GList
*addrindex_ds_get_all_persons( AddressDataSource
*ds
) {
2501 GList
*retVal
= NULL
;
2502 AddressInterface
*iface
;
2504 if( ds
== NULL
) return retVal
;
2505 iface
= ds
->interface
;
2506 if( iface
== NULL
) return retVal
;
2507 if( iface
->getAllPersons
) {
2508 retVal
= ( iface
->getAllPersons
) ( ds
->rawDataSource
);
2514 * Return list of all groups for specified data source.
2516 static GList
*addrindex_ds_get_all_groups( AddressDataSource
*ds
) {
2517 GList
*retVal
= NULL
;
2518 AddressInterface
*iface
;
2520 if( ds
== NULL
) return retVal
;
2521 iface
= ds
->interface
;
2522 if( iface
== NULL
) return retVal
;
2523 if( iface
->getAllGroups
) {
2524 retVal
= ( iface
->getAllGroups
) ( ds
->rawDataSource
);
2529 /* **********************************************************************
2530 * Address search stuff.
2531 * ***********************************************************************
2535 * Setup or register the dynamic search that will be performed. The search
2536 * is registered with the query manager.
2538 * \param searchTerm Search term. A private copy will be made.
2539 * \param callBackEntry Callback function that should be called when
2540 * each entry is received.
2541 * \param callBackEnd Callback function that should be called when
2542 * search has finished running.
2543 * \return ID allocated to query that will be executed.
2545 gint
addrindex_setup_search(
2546 const gchar
*searchTerm
, void *callBackEnd
, void *callBackEntry
)
2551 /* Set up a dynamic address query */
2552 req
= qrymgr_add_request( searchTerm
, callBackEnd
, callBackEntry
);
2553 queryID
= req
->queryID
;
2554 qryreq_set_search_type( req
, ADDRSEARCH_DYNAMIC
);
2556 /* g_print( "***> query ID ::%d::\n", queryID ); */
2563 * Function prototypes (not in header file or circular reference errors are
2566 LdapQuery
*ldapsvr_new_dynamic_search(
2567 LdapServer
*server
, QueryRequest
*req
);
2568 LdapQuery
*ldapsvr_new_explicit_search(
2569 LdapServer
*server
, QueryRequest
*req
, ItemFolder
*folder
);
2570 void ldapsvr_execute_query( LdapServer
*server
, LdapQuery
*qry
);
2575 * Execute the previously registered dynamic search.
2577 * \param req Address query object to execute.
2578 * \return <i>TRUE</i> if search started successfully, or <i>FALSE</i> if
2581 static gboolean
addrindex_start_dynamic( QueryRequest
*req
) {
2582 AddressInterface
*iface
;
2583 AddressDataSource
*ds
;
2588 /* g_print( "addrindex_start_dynamic::%d::\n", req->queryID ); */
2589 nodeIf
= _addressIndex_
->searchOrder
;
2591 iface
= nodeIf
->data
;
2592 nodeIf
= g_list_next( nodeIf
);
2594 if( ! iface
->useInterface
) {
2597 if( ! iface
->externalQuery
) {
2602 nodeDS
= iface
->listSource
;
2605 nodeDS
= g_list_next( nodeDS
);
2607 if( type
== ADDR_IF_LDAP
) {
2611 server
= ds
->rawDataSource
;
2612 if( ! server
->searchFlag
) {
2615 if( ldapsvr_reuse_previous( server
, req
) ) {
2619 /* Start a new dynamic search */
2620 qry
= ldapsvr_new_dynamic_search( server
, req
);
2622 ldapsvr_execute_query( server
, qry
);
2632 * Stop the previously registered search.
2634 * \param queryID ID of search query to stop.
2636 void addrindex_stop_search( const gint queryID
){
2638 AddrQueryObject
*aqo
;
2641 /* g_print( "addrindex_stop_search/queryID=%d\n", queryID ); */
2642 /* If query ID does not match, search has not been setup */
2643 req
= qrymgr_find_request( queryID
);
2648 /* Stop all queries that were associated with request */
2649 node
= req
->queryList
;
2653 if( aqo
->queryType
== ADDRQUERY_LDAP
) {
2654 LdapQuery
*qry
= ( LdapQuery
* ) aqo
;
2655 ldapqry_set_stop_flag( qry
, TRUE
);
2659 node
= g_list_next( node
);
2662 /* Delete query request */
2663 qrymgr_delete_request( queryID
);
2667 * Setup or register the explicit search that will be performed. The search is
2668 * registered with the query manager.
2670 * \param ds Data source to search.
2671 * \param searchTerm Search term to locate.
2672 * \param folder Folder to receive search results; may be NULL.
2673 * \param callbackEnd Function to call when search has terminated.
2674 * \param callbackEntry Function to called for each entry processed.
2675 * \return ID allocated to query that will be executed.
2677 gint
addrindex_setup_explicit_search(
2678 AddressDataSource
*ds
, const gchar
*searchTerm
, ItemFolder
*folder
,
2679 void *callBackEnd
, void *callBackEntry
)
2686 /* Name the query */
2687 name
= g_strdup_printf( "Search '%s'", searchTerm
);
2689 /* Set up query request */
2690 if (!strcmp(searchTerm
, "*"))
2691 mySearch
= g_strdup("*@");
2693 mySearch
= g_strdup(searchTerm
);
2695 req
= qrymgr_add_request( mySearch
, callBackEnd
, callBackEntry
);
2699 qryreq_set_search_type( req
, ADDRSEARCH_EXPLICIT
);
2700 queryID
= req
->queryID
;
2702 if( ds
->type
== ADDR_IF_LDAP
) {
2706 server
= ds
->rawDataSource
;
2707 ldapsvr_new_explicit_search( server
, req
, folder
);
2711 qrymgr_delete_request( queryID
);
2720 * Execute the previously registered explicit search.
2722 * \param req Address query request object to execute.
2723 * \return <i>TRUE</i> if search started successfully, or <i>FALSE</i> if
2726 static gboolean
addrindex_start_explicit( QueryRequest
*req
) {
2728 AddrQueryObject
*aqo
;
2732 /* Note: there should only be one query in the list. */
2733 aqo
= req
->queryList
->data
;
2735 if( aqo
->queryType
== ADDRQUERY_LDAP
) {
2739 qry
= ( LdapQuery
* ) aqo
;
2740 server
= qry
->server
;
2742 /* Start the search */
2744 ldapsvr_execute_query( server
, qry
);
2751 * Start the previously registered search.
2753 * \param queryID ID of search query to be executed.
2754 * \return <i>TRUE</i> if search started successfully, or <i>FALSE</i> if
2757 gboolean
addrindex_start_search( const gint queryID
) {
2760 AddrSearchType searchType
;
2763 /* g_print( "addrindex_start_search/queryID=%d\n", queryID ); */
2764 req
= qrymgr_find_request( queryID
);
2769 searchType
= req
->searchType
;
2770 if( searchType
== ADDRSEARCH_DYNAMIC
) {
2771 retVal
= addrindex_start_dynamic( req
);
2773 else if( searchType
== ADDRSEARCH_EXPLICIT
) {
2774 retVal
= addrindex_start_explicit( req
);
2781 * Remove results (folder and data) for specified data source and folder.
2782 * \param ds Data source to process.
2783 * \param folder Results folder to remove.
2785 void addrindex_remove_results( AddressDataSource
*ds
, ItemFolder
*folder
) {
2786 AddrBookBase
*adbase
;
2789 /* g_print( "addrindex_remove_results/start\n" ); */
2791 /* Test for folder */
2792 if( folder
->folderType
!= ADDRFOLDER_QUERY_RESULTS
) return;
2793 /* g_print( "folder name ::%s::\n", ADDRITEM_NAME(folder) ); */
2794 adbase
= ( AddrBookBase
* ) ds
->rawDataSource
;
2795 if( adbase
== NULL
) return;
2797 /* Hide folder to prevent re-display */
2798 addritem_folder_set_hidden( folder
, TRUE
);
2800 if( ds
->type
== ADDR_IF_LDAP
) {
2805 qry
= ( LdapQuery
* ) folder
->folderData
;
2806 queryID
= ADDRQUERY_ID(qry
);
2807 /* g_print( "calling ldapquery_remove_results...queryID=%d\n", queryID ); */
2808 delFlag
= ldapquery_remove_results( qry
);
2810 ldapqry_free( qry
);
2812 /* g_print( "calling ldapquery_remove_results...done\n" ); */
2815 g_print( "delFlag IS-TRUE\n" );
2818 g_print( "delFlag IS-FALSE\n" );
2823 /* g_print( "addrindex_remove_results/end\n" ); */
2825 /* Delete query request */
2827 qrymgr_delete_request( queryID
);
2831 /* **********************************************************************
2832 * Address completion stuff.
2833 * ***********************************************************************
2836 static void addrindex_load_completion_load_persons(
2837 gint (*callBackFunc
) ( const gchar
*, const gchar
*,
2838 const gchar
*, const gchar
*, GList
* ),
2839 AddressDataSource
*ds
)
2841 GList
*listP
, *nodeP
;
2845 /* Read address book */
2846 if( addrindex_ds_get_modify_flag( ds
) ) {
2847 addrindex_ds_read_data( ds
);
2850 if( ! addrindex_ds_get_read_flag( ds
) ) {
2851 addrindex_ds_read_data( ds
);
2854 /* Get all groups */
2855 listP
= addrindex_ds_get_all_groups( ds
);
2858 ItemGroup
*group
= nodeP
->data
;
2859 GList
*emails
= NULL
;
2860 for (nodeM
= group
->listEMail
; nodeM
; nodeM
= g_list_next(nodeM
)) {
2861 ItemEMail
*email
= nodeM
->data
;
2863 emails
= g_list_append(emails
, email
);
2865 callBackFunc( ((AddrItemObject
*)group
)->name
, NULL
,
2866 NULL
, NULL
, emails
);
2867 nodeP
= g_list_next( nodeP
);
2870 /* Free up the list */
2871 g_list_free( listP
);
2872 /* Get all persons */
2873 listP
= addrindex_ds_get_all_persons( ds
);
2876 ItemPerson
*person
= nodeP
->data
;
2877 nodeM
= person
->listEMail
;
2879 /* Figure out name to use */
2880 sName
= ADDRITEM_NAME(person
);
2881 if( sName
== NULL
|| *sName
== '\0' ) {
2882 sName
= person
->nickName
;
2885 /* Process each E-Mail address */
2887 ItemEMail
*email
= nodeM
->data
;
2889 callBackFunc( sName
, email
->address
, person
->nickName
,
2890 ADDRITEM_NAME(email
), NULL
);
2892 nodeM
= g_list_next( nodeM
);
2894 nodeP
= g_list_next( nodeP
);
2897 /* Free up the list */
2898 g_list_free( listP
);
2902 * This function is used by the address completion function to load
2903 * addresses for all non-external address book interfaces.
2905 * \param callBackFunc Function to be called when an address is
2907 * \param folderpath Addressbook's Book/folder path to restrict to (if NULL or ""
2908 * or "Any", assume the whole addressbook
2909 * \return <i>TRUE</i> if data loaded, <i>FALSE</i> if address index not loaded.
2912 gboolean
addrindex_load_completion(
2913 gint (*callBackFunc
) ( const gchar
*, const gchar
*,
2914 const gchar
*, const gchar
*, GList
* ),
2917 GList
*nodeIf
, *nodeDS
;
2919 if( folderpath
!= NULL
) {
2920 AddressDataSource
*book
;
2923 /* split the folder path we've received, we'll try to match this path, subpath by
2924 subpath against the book/folder structure in order and restrict loading of
2925 addresses to that subpart (if matches). book/folder path must exist and
2926 folderpath must not be empty or NULL */
2928 if( ! addressbook_peek_folder_exists( folderpath
, &book
, &folder
) ) {
2929 g_warning("addrindex_load_completion: folder path '%s' doesn't exist", folderpath
);
2933 if( folder
!= NULL
) {
2940 debug_print("addrindex_load_completion: folder %p '%s'\n", folder
, folder
->obj
.name
);
2942 /* Load email addresses */
2943 items
= addritem_folder_get_person_list( folder
);
2944 for( ; items
!= NULL
; items
= g_list_next( items
) ) {
2945 person
= items
->data
;
2946 nodeM
= person
->listEMail
;
2948 /* Figure out name to use */
2949 sName
= ADDRITEM_NAME(person
);
2950 if( sName
== NULL
|| *sName
== '\0' ) {
2951 sName
= person
->nickName
;
2954 /* Process each E-Mail address */
2956 ItemEMail
*email
= nodeM
->data
;
2958 callBackFunc( sName
, email
->address
, person
->nickName
,
2959 ADDRITEM_NAME(email
), NULL
);
2961 nodeM
= g_list_next( nodeM
);
2964 /* Free up the list (but not the data inside the
2965 * individual list items) */
2966 g_list_free( items
);
2972 if( book
!= NULL
) {
2974 AddressBookFile
*abf
= book
->rawDataSource
;
2976 debug_print("addrindex_load_completion: book %p '%s'\n", book
, abf
?abf
->fileName
:"(null)");
2978 addrindex_load_completion_load_persons( callBackFunc
, book
);
2983 g_warning("addrindex_load_completion: book/folder path is valid but got no pointer");
2990 nodeIf
= addrindex_get_interface_list( _addressIndex_
);
2992 AddressInterface
*iface
= nodeIf
->data
;
2994 nodeIf
= g_list_next( nodeIf
);
2996 if( ! iface
->useInterface
|| iface
->externalQuery
)
2999 nodeDS
= iface
->listSource
;
3001 addrindex_load_completion_load_persons( callBackFunc
, nodeDS
->data
);
3002 nodeDS
= g_list_next( nodeDS
);
3011 * This function can be used to collect information about
3012 * addressbook entries that contain a specific attribute.
3014 * \param attr Name of attribute to look for
3015 * \param callBackFunc Function to be called when a matching attribute was found
3016 * \return <i>TRUE</i>
3018 gboolean
addrindex_load_person_attribute(
3020 gint (*callBackFunc
) ( ItemPerson
*, const gchar
* ) )
3022 AddressDataSource
*ds
;
3023 GList
*nodeIf
, *nodeDS
;
3024 GList
*listP
, *nodeP
;
3027 nodeIf
= addrindex_get_interface_list( _addressIndex_
);
3030 AddressInterface
*iface
= nodeIf
->data
;
3032 nodeIf
= g_list_next( nodeIf
);
3034 if( ! iface
->useInterface
|| iface
->externalQuery
)
3037 nodeDS
= iface
->listSource
;
3041 /* Read address book */
3042 if( addrindex_ds_get_modify_flag( ds
) ) {
3043 addrindex_ds_read_data( ds
);
3046 if( ! addrindex_ds_get_read_flag( ds
) ) {
3047 addrindex_ds_read_data( ds
);
3050 /* Check addressbook name */
3051 cur_bname
= addrindex_ds_get_name( ds
);
3053 /* Get all persons */
3054 listP
= addrindex_ds_get_all_persons( ds
);
3057 ItemPerson
*person
= nodeP
->data
;
3059 /* Return all ItemPerson's if attr is NULL */
3060 if( attr
== NULL
) {
3061 callBackFunc(person
, cur_bname
);
3064 /* Return ItemPerson's with specific attribute */
3066 nodeA
= person
->listAttrib
;
3067 /* Process each User Attribute */
3069 UserAttribute
*attrib
= nodeA
->data
;
3071 !strcmp( attrib
->name
,attr
) ) {
3072 callBackFunc(person
, cur_bname
);
3074 nodeA
= g_list_next( nodeA
);
3077 nodeP
= g_list_next( nodeP
);
3079 /* Free up the list */
3080 g_list_free( listP
);
3082 nodeDS
= g_list_next( nodeDS
);
3089 * This function can be used to collect information about
3090 * addressbook entries
3092 * \param callBackFunc Function to be called for each ItemPerson
3093 * \return <i>TRUE</i>
3095 gboolean
addrindex_load_person_ds( gint (*callBackFunc
)
3096 ( ItemPerson
*, AddressDataSource
* ) )
3098 AddressDataSource
*ds
;
3099 GList
*nodeIf
, *nodeDS
;
3100 GList
*listP
, *nodeP
;
3102 nodeIf
= addrindex_get_interface_list( _addressIndex_
);
3104 AddressInterface
*iface
= nodeIf
->data
;
3106 nodeIf
= g_list_next( nodeIf
);
3108 if( ! iface
->useInterface
|| iface
->externalQuery
)
3111 nodeDS
= iface
->listSource
;
3115 /* Read address book */
3116 if( addrindex_ds_get_modify_flag( ds
) ) {
3117 addrindex_ds_read_data( ds
);
3120 if( ! addrindex_ds_get_read_flag( ds
) ) {
3121 addrindex_ds_read_data( ds
);
3124 /* Get all persons */
3125 listP
= addrindex_ds_get_all_persons( ds
);
3128 ItemPerson
*person
= nodeP
->data
;
3130 callBackFunc(person
, ds
);
3131 nodeP
= g_list_next( nodeP
);
3133 /* Free up the list */
3134 g_list_free( listP
);
3136 nodeDS
= g_list_next( nodeDS
);
3142 gchar
*addrindex_get_picture_file(const gchar
*emailaddr
)
3144 AddressDataSource
*ds
;
3145 GList
*nodeIf
, *nodeDS
;
3146 GList
*listP
, *nodeP
;
3147 gboolean found
= FALSE
;
3148 gchar
*filename
= NULL
;
3149 gchar
*raw_addr
= NULL
;
3154 Xstrdup_a(raw_addr
, emailaddr
, return NULL
);
3155 extract_address(raw_addr
);
3157 nodeIf
= addrindex_get_interface_list( _addressIndex_
);
3159 AddressInterface
*iface
= nodeIf
->data
;
3161 nodeIf
= g_list_next( nodeIf
);
3163 if( ! iface
->useInterface
|| iface
->externalQuery
)
3166 nodeDS
= iface
->listSource
;
3167 while( nodeDS
&& !found
) {
3170 /* Read address book */
3171 if( addrindex_ds_get_modify_flag( ds
) ) {
3172 addrindex_ds_read_data( ds
);
3175 if( ! addrindex_ds_get_read_flag( ds
) ) {
3176 addrindex_ds_read_data( ds
);
3179 /* Get all persons */
3180 listP
= addrindex_ds_get_all_persons( ds
);
3182 while( nodeP
&& !found
) {
3184 ItemPerson
*person
= nodeP
->data
;
3185 nodeM
= person
->listEMail
;
3187 ItemEMail
*email
= nodeM
->data
;
3188 if (email
->address
&& !strcasecmp(raw_addr
, email
->address
)) {
3190 filename
= g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S
,
3191 ADDRBOOK_DIR
, G_DIR_SEPARATOR_S
,
3192 person
->picture
, ".png", NULL
);
3195 nodeM
= nodeM
->next
;
3197 nodeP
= g_list_next( nodeP
);
3199 /* Free up the list */
3200 g_list_free( listP
);
3202 nodeDS
= g_list_next( nodeDS
);
3210 GSList
*addrindex_get_password_protected_ldap_servers()
3212 AddressInterface
*iface
;
3213 AddressDataSource
*ds
;
3216 GSList
*list
= NULL
;
3220 nodeIf
= _addressIndex_
->searchOrder
;
3222 iface
= nodeIf
->data
;
3223 nodeIf
= g_list_next(nodeIf
);
3225 if (!iface
->useInterface
)
3227 if (!iface
->externalQuery
)
3229 if (iface
->type
!= ADDR_IF_LDAP
)
3232 nodeDS
= iface
->listSource
;
3235 nodeDS
= g_list_next(nodeDS
);
3236 server
= ds
->rawDataSource
;
3237 if (!server
->searchFlag
)
3240 ctl
= server
->control
;
3245 if (ctl
->bindDN
!= NULL
&& strlen(ctl
->bindDN
)) {
3246 list
= g_slist_append(list
, server
);
3253 #endif /* USE_LDAP */