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/>.
20 * General functions for accessing address index file.
25 #include "claws-features.h"
31 #include <glib/gi18n.h>
35 #include "addrcache.h"
37 #include "addressbook.h"
38 #include "addrindex.h"
40 #include "addrquery.h"
41 #include "addr_compl.h"
43 #include "alertpanel.h"
44 #include "passwordstore.h"
45 #include "file-utils.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
{
164 AddressBookType type
;
165 AddressCache
*addressCache
;
172 * Build interface with default values.
174 * \param type Interface type.
175 * \param name Interface name.
176 * \param tagIf XML tag name for interface in address index file.
177 * \param tagDS XML tag name for datasource in address index file.
178 * \return Address interface object.
180 static AddressInterface
*addrindex_create_interface(
181 gint type
, gchar
*name
, gchar
*tagIf
, gchar
*tagDS
)
183 AddressInterface
*iface
= g_new0( AddressInterface
, 1 );
185 ADDRITEM_TYPE(iface
) = ITEMTYPE_INTERFACE
;
186 ADDRITEM_ID(iface
) = NULL
;
187 ADDRITEM_NAME(iface
) = g_strdup( name
);
188 ADDRITEM_PARENT(iface
) = NULL
;
189 ADDRITEM_SUBTYPE(iface
) = type
;
191 iface
->name
= g_strdup( name
);
192 iface
->listTag
= g_strdup( tagIf
);
193 iface
->itemTag
= g_strdup( tagDS
);
194 iface
->legacyFlag
= FALSE
;
195 iface
->haveLibrary
= TRUE
;
196 iface
->useInterface
= TRUE
;
197 iface
->readOnly
= TRUE
;
199 /* Set callbacks to NULL values - override for each interface */
200 iface
->getAccessFlag
= NULL
;
201 iface
->getModifyFlag
= NULL
;
202 iface
->getReadFlag
= NULL
;
203 iface
->getStatusCode
= NULL
;
204 iface
->getReadData
= NULL
;
205 iface
->getRootFolder
= NULL
;
206 iface
->getListFolder
= NULL
;
207 iface
->getListPerson
= NULL
;
208 iface
->getAllPersons
= NULL
;
209 iface
->getAllGroups
= NULL
;
210 iface
->getName
= NULL
;
211 iface
->listSource
= NULL
;
214 iface
->externalQuery
= FALSE
;
215 iface
->searchOrder
= 0; /* Ignored */
216 iface
->startSearch
= NULL
;
217 iface
->stopSearch
= NULL
;
223 * Build table of of all address book interfaces.
224 * \param addrIndex Address index object.
226 static void addrindex_build_if_list( AddressIndex
*addrIndex
) {
227 AddressInterface
*iface
;
229 /* Create intrinsic XML address book interface */
230 iface
= addrindex_create_interface(
231 ADDR_IF_BOOK
, "Address Book", TAG_IF_ADDRESS_BOOK
,
232 TAG_DS_ADDRESS_BOOK
);
233 iface
->readOnly
= FALSE
;
234 iface
->getModifyFlag
= ( void * ) addrbook_get_modified
;
235 iface
->getAccessFlag
= ( void * ) addrbook_get_accessed
;
236 iface
->getReadFlag
= ( void * ) addrbook_get_read_flag
;
237 iface
->getStatusCode
= ( void * ) addrbook_get_status
;
238 iface
->getReadData
= ( void * ) addrbook_read_data
;
239 iface
->getRootFolder
= ( void * ) addrbook_get_root_folder
;
240 iface
->getListFolder
= ( void * ) addrbook_get_list_folder
;
241 iface
->getListPerson
= ( void * ) addrbook_get_list_person
;
242 iface
->getAllPersons
= ( void * ) addrbook_get_all_persons
;
243 iface
->getAllGroups
= ( void * ) addrbook_get_all_groups
;
244 iface
->getName
= ( void * ) addrbook_get_name
;
245 iface
->setAccessFlag
= ( void * ) addrbook_set_accessed
;
246 iface
->searchOrder
= 0;
248 /* Add to list of interfaces in address book */
249 addrIndex
->interfaceList
=
250 g_list_append( addrIndex
->interfaceList
, iface
);
251 ADDRITEM_PARENT(iface
) = ADDRITEM_OBJECT(addrIndex
);
253 /* Create vCard interface */
254 iface
= addrindex_create_interface(
255 ADDR_IF_VCARD
, "vCard", TAG_IF_VCARD
, TAG_DS_VCARD
);
256 iface
->getModifyFlag
= ( void * ) vcard_get_modified
;
257 iface
->getAccessFlag
= ( void * ) vcard_get_accessed
;
258 iface
->getReadFlag
= ( void * ) vcard_get_read_flag
;
259 iface
->getStatusCode
= ( void * ) vcard_get_status
;
260 iface
->getReadData
= ( void * ) vcard_read_data
;
261 iface
->getRootFolder
= ( void * ) vcard_get_root_folder
;
262 iface
->getListFolder
= ( void * ) vcard_get_list_folder
;
263 iface
->getListPerson
= ( void * ) vcard_get_list_person
;
264 iface
->getAllPersons
= ( void * ) vcard_get_all_persons
;
265 iface
->getName
= ( void * ) vcard_get_name
;
266 iface
->setAccessFlag
= ( void * ) vcard_set_accessed
;
267 iface
->searchOrder
= 0;
268 addrIndex
->interfaceList
=
269 g_list_append( addrIndex
->interfaceList
, iface
);
270 ADDRITEM_PARENT(iface
) = ADDRITEM_OBJECT(addrIndex
);
272 /* Create JPilot interface */
273 iface
= addrindex_create_interface(
274 ADDR_IF_JPILOT
, "J-Pilot", TAG_IF_JPILOT
,
277 iface
->haveLibrary
= jpilot_test_pilot_lib();
278 iface
->useInterface
= iface
->haveLibrary
;
279 iface
->getModifyFlag
= ( void * ) jpilot_get_modified
;
280 iface
->getAccessFlag
= ( void * ) jpilot_get_accessed
;
281 iface
->getReadFlag
= ( void * ) jpilot_get_read_flag
;
282 iface
->getStatusCode
= ( void * ) jpilot_get_status
;
283 iface
->getReadData
= ( void * ) jpilot_read_data
;
284 iface
->getRootFolder
= ( void * ) jpilot_get_root_folder
;
285 iface
->getListFolder
= ( void * ) jpilot_get_list_folder
;
286 iface
->getListPerson
= ( void * ) jpilot_get_list_person
;
287 iface
->getAllPersons
= ( void * ) jpilot_get_all_persons
;
288 iface
->getName
= ( void * ) jpilot_get_name
;
289 iface
->setAccessFlag
= ( void * ) jpilot_set_accessed
;
290 iface
->searchOrder
= 0;
292 iface
->useInterface
= FALSE
;
293 iface
->haveLibrary
= FALSE
;
295 addrIndex
->interfaceList
=
296 g_list_append( addrIndex
->interfaceList
, iface
);
297 ADDRITEM_PARENT(iface
) = ADDRITEM_OBJECT(addrIndex
);
299 /* Create LDAP interface */
300 iface
= addrindex_create_interface(
301 ADDR_IF_LDAP
, "LDAP", TAG_IF_LDAP
, TAG_DS_LDAP
);
303 iface
->readOnly
= FALSE
;
304 /* iface->haveLibrary = ldapsvr_test_ldap_lib(); */
305 iface
->haveLibrary
= ldaputil_test_ldap_lib();
306 iface
->useInterface
= iface
->haveLibrary
;
307 iface
->getModifyFlag
= ( void * ) ldapsvr_get_modified
;
308 iface
->getAccessFlag
= ( void * ) ldapsvr_get_accessed
;
309 iface
->getReadFlag
= ( void * ) ldapsvr_get_read_flag
;
310 iface
->getStatusCode
= ( void * ) ldapsvr_get_status
;
311 iface
->getReadData
= ( void * ) ldapsvr_read_data
;
312 iface
->getRootFolder
= ( void * ) ldapsvr_get_root_folder
;
313 iface
->getListFolder
= ( void * ) ldapsvr_get_list_folder
;
314 iface
->getListPerson
= ( void * ) ldapsvr_get_list_person
;
315 iface
->getName
= ( void * ) ldapsvr_get_name
;
316 iface
->setAccessFlag
= ( void * ) ldapsvr_set_accessed
;
317 iface
->externalQuery
= TRUE
;
318 iface
->searchOrder
= 1;
320 iface
->useInterface
= FALSE
;
321 iface
->haveLibrary
= FALSE
;
323 addrIndex
->interfaceList
=
324 g_list_append( addrIndex
->interfaceList
, iface
);
325 ADDRITEM_PARENT(iface
) = ADDRITEM_OBJECT(addrIndex
);
327 /* Two old legacy data sources (pre 0.7.0) */
328 iface
= addrindex_create_interface(
329 ADDR_IF_COMMON
, "Old Address - common",
330 TAG_IF_OLD_COMMON
, NULL
);
331 iface
->legacyFlag
= TRUE
;
332 addrIndex
->interfaceList
=
333 g_list_append( addrIndex
->interfaceList
, iface
);
334 ADDRITEM_PARENT(iface
) = ADDRITEM_OBJECT(addrIndex
);
336 iface
= addrindex_create_interface(
337 ADDR_IF_COMMON
, "Old Address - personal",
338 TAG_IF_OLD_PERSONAL
, NULL
);
339 iface
->legacyFlag
= TRUE
;
340 addrIndex
->interfaceList
=
341 g_list_append( addrIndex
->interfaceList
, iface
);
342 ADDRITEM_PARENT(iface
) = ADDRITEM_OBJECT(addrIndex
);
348 * \param fragment Fragment to free.
350 static void addrindex_free_fragment( AddressIfFragment
*fragment
) {
354 node
= fragment
->children
;
356 AddressIfFragment
*child
= node
->data
;
357 addrindex_free_fragment( child
);
359 node
= g_list_next( node
);
361 g_list_free( fragment
->children
);
363 /* Free attributes */
364 node
= fragment
->attributes
;
366 AddressIfAttrib
*nv
= node
->data
;
371 node
= g_list_next( node
);
373 g_list_free( fragment
->attributes
);
375 g_free( fragment
->name
);
376 fragment
->name
= NULL
;
377 fragment
->attributes
= NULL
;
378 fragment
->children
= NULL
;
384 * Create a new data source.
385 * \param ifType Interface type to create.
386 * \return Initialized data source.
388 AddressDataSource
*addrindex_create_datasource( AddressIfType ifType
) {
389 AddressDataSource
*ds
= g_new0( AddressDataSource
, 1 );
391 ADDRITEM_TYPE(ds
) = ITEMTYPE_DATASOURCE
;
392 ADDRITEM_ID(ds
) = NULL
;
393 ADDRITEM_NAME(ds
) = NULL
;
394 ADDRITEM_PARENT(ds
) = NULL
;
395 ADDRITEM_SUBTYPE(ds
) = 0;
397 ds
->rawDataSource
= NULL
;
398 ds
->interface
= NULL
;
403 * Free up data source.
404 * \param ds Data source to free.
406 void addrindex_free_datasource( AddressDataSource
*ds
) {
407 AddressInterface
*iface
;
409 cm_return_if_fail( ds
!= NULL
);
411 iface
= ds
->interface
;
412 if( ds
->rawDataSource
!= NULL
) {
413 if( iface
!= NULL
) {
414 if( iface
->useInterface
) {
415 if( iface
->type
== ADDR_IF_BOOK
) {
416 AddressBookFile
*abf
= ds
->rawDataSource
;
417 addrbook_free_book( abf
);
419 else if( iface
->type
== ADDR_IF_VCARD
) {
420 VCardFile
*vcf
= ds
->rawDataSource
;
424 else if( iface
->type
== ADDR_IF_JPILOT
) {
425 JPilotFile
*jpf
= ds
->rawDataSource
;
430 else if( iface
->type
== ADDR_IF_LDAP
) {
431 LdapServer
*server
= ds
->rawDataSource
;
432 ldapsvr_free( server
);
439 AddressIfFragment
*fragment
= ds
->rawDataSource
;
440 addrindex_free_fragment( fragment
);
445 ADDRITEM_TYPE(ds
) = ITEMTYPE_NONE
;
446 ADDRITEM_ID(ds
) = NULL
;
447 ADDRITEM_NAME(ds
) = NULL
;
448 ADDRITEM_PARENT(ds
) = NULL
;
449 ADDRITEM_SUBTYPE(ds
) = 0;
450 ds
->type
= ADDR_IF_NONE
;
451 ds
->interface
= NULL
;
452 ds
->rawDataSource
= NULL
;
458 * Free up all data sources for specified interface.
459 * \param iface Address interface to process.
461 static void addrindex_free_all_datasources( AddressInterface
*iface
) {
462 GList
*node
= iface
->listSource
;
464 AddressDataSource
*ds
= node
->data
;
465 addrindex_free_datasource( ds
);
467 node
= g_list_next( node
);
472 * Free up specified interface.
473 * \param iface Interface to process.
475 static void addrindex_free_interface( AddressInterface
*iface
) {
476 /* Free up data sources */
477 addrindex_free_all_datasources( iface
);
478 g_list_free( iface
->listSource
);
480 /* Free internal storage */
481 g_free( ADDRITEM_ID(iface
) );
482 g_free( ADDRITEM_NAME(iface
) );
483 g_free( iface
->name
);
484 g_free( iface
->listTag
);
485 g_free( iface
->itemTag
);
487 /* Clear all pointers */
488 ADDRITEM_TYPE(iface
) = ITEMTYPE_NONE
;
489 ADDRITEM_ID(iface
) = NULL
;
490 ADDRITEM_NAME(iface
) = NULL
;
491 ADDRITEM_PARENT(iface
) = NULL
;
492 ADDRITEM_SUBTYPE(iface
) = 0;
493 iface
->type
= ADDR_IF_NONE
;
495 iface
->listTag
= NULL
;
496 iface
->itemTag
= NULL
;
497 iface
->legacyFlag
= FALSE
;
498 iface
->useInterface
= FALSE
;
499 iface
->haveLibrary
= FALSE
;
500 iface
->listSource
= NULL
;
503 iface
->searchOrder
= 0;
504 iface
->startSearch
= NULL
;
505 iface
->stopSearch
= NULL
;
511 * Return cache ID for specified data source.
513 * \param addrIndex Address index.
514 * \param ds Data source.
515 * \return ID or NULL if not found. This should be <code>g_free()</code>
518 gchar
*addrindex_get_cache_id( AddressIndex
*addrIndex
, AddressDataSource
*ds
) {
519 gchar
*cacheID
= NULL
;
520 AddrBookBase
*adbase
;
523 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
524 cm_return_val_if_fail( ds
!= NULL
, NULL
);
526 adbase
= ( AddrBookBase
* ) ds
->rawDataSource
;
528 cache
= adbase
->addressCache
;
530 cacheID
= g_strdup( cache
->cacheID
);
538 * Return reference to data source for specified cacheID.
539 * \param addrIndex Address index.
541 * \return Data source, or NULL if not found.
543 static AddressDataSource
*addrindex_get_datasource(
544 AddressIndex
*addrIndex
, const gchar
*cacheID
)
546 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
547 cm_return_val_if_fail( cacheID
!= NULL
, NULL
);
548 return ( AddressDataSource
* ) g_hash_table_lookup( addrIndex
->hashCache
, cacheID
);
552 * Return reference to address cache for specified cacheID.
553 * \param addrIndex Address index.
555 * \return Address cache, or NULL if not found.
557 AddressCache
*addrindex_get_cache( AddressIndex
*addrIndex
, const gchar
*cacheID
) {
558 AddressDataSource
*ds
;
559 AddrBookBase
*adbase
;
562 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
563 cm_return_val_if_fail( cacheID
!= NULL
, NULL
);
566 ds
= addrindex_get_datasource( addrIndex
, cacheID
);
568 adbase
= ( AddrBookBase
* ) ds
->rawDataSource
;
569 cache
= adbase
->addressCache
;
575 * Add data source into hash table.
576 * \param addrIndex Address index.
577 * \param ds Data source.
579 static void addrindex_hash_add_cache(
580 AddressIndex
*addrIndex
, AddressDataSource
*ds
)
584 cacheID
= addrindex_get_cache_id( addrIndex
, ds
);
586 g_hash_table_insert( addrIndex
->hashCache
, cacheID
, ds
);
591 * Free hash table callback function.
593 static gboolean
addrindex_free_cache_cb( gpointer key
, gpointer value
, gpointer data
) {
601 * Free hash table of address cache items.
603 static void addrindex_free_cache_hash( GHashTable
*table
) {
604 g_hash_table_foreach_remove( table
, addrindex_free_cache_cb
, NULL
);
605 g_hash_table_destroy( table
);
609 * Remove data source from internal hashtable.
610 * \param addrIndex Address index.
611 * \param ds Data source to remove.
613 static void addrindex_hash_remove_cache(
614 AddressIndex
*addrIndex
, AddressDataSource
*ds
)
618 cacheID
= addrindex_get_cache_id( addrIndex
, ds
);
620 g_hash_table_remove( addrIndex
->hashCache
, cacheID
);
627 * Create a new address index. This is created as a singleton object.
628 * \return Initialized address index object.
630 AddressIndex
*addrindex_create_index( void ) {
633 if( _addressIndex_
== NULL
) {
634 index
= g_new0( AddressIndex
, 1 );
635 ADDRITEM_TYPE(index
) = ITEMTYPE_INDEX
;
636 ADDRITEM_ID(index
) = NULL
;
637 ADDRITEM_NAME(index
) = g_strdup( "Address Index" );
638 ADDRITEM_PARENT(index
) = NULL
;
639 ADDRITEM_SUBTYPE(index
) = 0;
640 index
->filePath
= NULL
;
641 index
->fileName
= NULL
;
642 index
->retVal
= MGU_SUCCESS
;
643 index
->needsConversion
= FALSE
;
644 index
->wasConverted
= FALSE
;
645 index
->conversionError
= FALSE
;
646 index
->interfaceList
= NULL
;
647 index
->lastType
= ADDR_IF_NONE
;
648 index
->dirtyFlag
= FALSE
;
649 index
->hashCache
= g_hash_table_new( g_str_hash
, g_str_equal
);
650 index
->loadedFlag
= FALSE
;
651 index
->searchOrder
= NULL
;
652 addrindex_build_if_list( index
);
653 _addressIndex_
= index
;
655 return _addressIndex_
;
659 * Property - Specify file path to address index file.
660 * \param addrIndex Address index.
661 * \param value Path to index file.
663 void addrindex_set_file_path( AddressIndex
*addrIndex
, const gchar
*value
) {
664 cm_return_if_fail( addrIndex
!= NULL
);
665 addrIndex
->filePath
= mgu_replace_string( addrIndex
->filePath
, value
);
669 * Property - Specify file name to address index file.
670 * \param addrIndex Address index.
671 * \param value File name.
673 void addrindex_set_file_name( AddressIndex
*addrIndex
, const gchar
*value
) {
674 cm_return_if_fail( addrIndex
!= NULL
);
675 addrIndex
->fileName
= mgu_replace_string( addrIndex
->fileName
, value
);
679 * Return list of address interfaces.
680 * \param addrIndex Address index.
681 * \return List of address interfaces.
683 GList
*addrindex_get_interface_list( AddressIndex
*addrIndex
) {
684 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
685 return addrIndex
->interfaceList
;
689 * Perform any other initialization of address index.
691 void addrindex_initialize( void ) {
693 addrcompl_initialize();
697 * Perform any other teardown of address index.
699 void addrindex_teardown( void ) {
700 addrcompl_teardown();
705 * Free up address index.
706 * \param addrIndex Address index.
708 void addrindex_free_index( AddressIndex
*addrIndex
) {
711 cm_return_if_fail( addrIndex
!= NULL
);
714 g_list_free( addrIndex
->searchOrder
);
715 addrIndex
->searchOrder
= NULL
;
717 /* Free internal storage */
718 g_free( ADDRITEM_ID(addrIndex
) );
719 g_free( ADDRITEM_NAME(addrIndex
) );
720 g_free( addrIndex
->filePath
);
721 g_free( addrIndex
->fileName
);
724 ADDRITEM_TYPE(addrIndex
) = ITEMTYPE_NONE
;
725 ADDRITEM_ID(addrIndex
) = NULL
;
726 ADDRITEM_NAME(addrIndex
) = NULL
;
727 ADDRITEM_PARENT(addrIndex
) = NULL
;
728 ADDRITEM_SUBTYPE(addrIndex
) = 0;
729 addrIndex
->filePath
= NULL
;
730 addrIndex
->fileName
= NULL
;
731 addrIndex
->retVal
= MGU_SUCCESS
;
732 addrIndex
->needsConversion
= FALSE
;
733 addrIndex
->wasConverted
= FALSE
;
734 addrIndex
->conversionError
= FALSE
;
735 addrIndex
->lastType
= ADDR_IF_NONE
;
736 addrIndex
->dirtyFlag
= FALSE
;
738 /* Free up interfaces */
739 node
= addrIndex
->interfaceList
;
741 AddressInterface
*iface
= node
->data
;
742 addrindex_free_interface( iface
);
743 node
= g_list_next( node
);
745 g_list_free( addrIndex
->interfaceList
);
746 addrIndex
->interfaceList
= NULL
;
748 /* Free up hash cache */
749 addrindex_free_cache_hash( addrIndex
->hashCache
);
750 addrIndex
->hashCache
= NULL
;
752 addrIndex
->loadedFlag
= FALSE
;
756 _addressIndex_
= NULL
;
760 * Print address index.
761 * \param addrIndex Address index.
762 * \parem stream Stream to print.
764 void addrindex_print_index( AddressIndex
*addrIndex
, FILE *stream
) {
765 cm_return_if_fail( addrIndex
!= NULL
);
766 fprintf( stream
, "AddressIndex:\n" );
767 fprintf( stream
, "\tfile path: '%s'\n", addrIndex
->filePath
);
768 fprintf( stream
, "\tfile name: '%s'\n", addrIndex
->fileName
);
769 fprintf( stream
, "\t status: %d\n", addrIndex
->retVal
);
770 fprintf( stream
, "\tconverted: '%s'\n",
771 addrIndex
->wasConverted
? "yes" : "no" );
772 fprintf( stream
, "\tcvt error: '%s'\n",
773 addrIndex
->conversionError
? "yes" : "no" );
774 fprintf( stream
, "\t---\n" );
778 * Retrieve reference to address interface for specified interface type.
779 * \param addrIndex Address index.
780 * \param ifType Interface type.
781 * \return Address interface, or NULL if not found.
783 static AddressInterface
*addrindex_get_interface(
784 AddressIndex
*addrIndex
, AddressIfType ifType
)
786 AddressInterface
*retVal
= NULL
;
789 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
791 node
= addrIndex
->interfaceList
;
793 AddressInterface
*iface
= node
->data
;
794 node
= g_list_next( node
);
795 if( iface
->type
== ifType
) {
804 * Add raw data source to index. The raw data object (an AddressBookFile or
805 * VCardFile object, for example) should be supplied as the raw dataSource
808 * \param addrIndex Address index.
809 * \param ifType Interface type to add.
810 * \param dataSource Actual raw data source to add.
811 * \return Data source added, or NULL if invalid interface type.
813 AddressDataSource
*addrindex_index_add_datasource(
814 AddressIndex
*addrIndex
, AddressIfType ifType
, gpointer dataSource
)
816 AddressInterface
*iface
;
817 AddressDataSource
*ds
= NULL
;
819 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
820 cm_return_val_if_fail( dataSource
!= NULL
, NULL
);
822 iface
= addrindex_get_interface( addrIndex
, ifType
);
824 ds
= addrindex_create_datasource( ifType
);
825 ADDRITEM_PARENT(ds
) = ADDRITEM_OBJECT(iface
);
827 ds
->rawDataSource
= dataSource
;
828 ds
->interface
= iface
;
829 iface
->listSource
= g_list_append( iface
->listSource
, ds
);
830 addrIndex
->dirtyFlag
= TRUE
;
832 addrindex_hash_add_cache( addrIndex
, ds
);
838 * Remove specified data source from index.
839 * \param addrIndex Address index.
840 * \param dataSource Data source to add.
841 * \return Reference to data source if removed, or NULL if data source was not
842 * found in index. Note the this object must still be freed.
844 AddressDataSource
*addrindex_index_remove_datasource(
845 AddressIndex
*addrIndex
, AddressDataSource
*dataSource
)
847 AddressDataSource
*retVal
= FALSE
;
848 AddressInterface
*iface
;
850 cm_return_val_if_fail( addrIndex
!= NULL
, NULL
);
851 cm_return_val_if_fail( dataSource
!= NULL
, NULL
);
853 iface
= addrindex_get_interface( addrIndex
, dataSource
->type
);
855 iface
->listSource
= g_list_remove( iface
->listSource
, dataSource
);
856 addrIndex
->dirtyFlag
= TRUE
;
857 dataSource
->interface
= NULL
;
859 /* Remove cache from hash table */
860 addrindex_hash_remove_cache( addrIndex
, dataSource
);
868 * Retrieve a reference to address interface for specified interface type and
869 * XML interface tag name.
870 * \param addrIndex Address index.
871 * \param tag XML interface tag name to match.
872 * \param ifType Interface type to match.
873 * \return Reference to address index, or NULL if not found in index.
875 static AddressInterface
*addrindex_tag_get_interface(
876 AddressIndex
*addrIndex
, gchar
*tag
, AddressIfType ifType
)
878 AddressInterface
*retVal
= NULL
;
879 GList
*node
= addrIndex
->interfaceList
;
882 AddressInterface
*iface
= node
->data
;
883 node
= g_list_next( node
);
885 if( strcmp( iface
->listTag
, tag
) == 0 ) {
891 if( iface
->type
== ifType
) {
901 * Retrieve a reference to address interface for specified interface type and
902 * XML datasource tag name.
903 * \param addrIndex Address index.
904 * \param ifType Interface type to match.
905 * \param tag XML datasource tag name to match.
906 * \return Reference to address index, or NULL if not found in index.
908 static AddressInterface
*addrindex_tag_get_datasource(
909 AddressIndex
*addrIndex
, AddressIfType ifType
, gchar
*tag
)
911 AddressInterface
*retVal
= NULL
;
912 GList
*node
= addrIndex
->interfaceList
;
915 AddressInterface
*iface
= node
->data
;
916 node
= g_list_next( node
);
917 if( iface
->type
== ifType
&& iface
->itemTag
) {
918 if( strcmp( iface
->itemTag
, tag
) == 0 ) {
927 /* **********************************************************************
928 * Interface XML parsing functions.
929 * ***********************************************************************
933 * Write start of XML element to file.
935 * \param lvl Indentation level.
936 * \param name Element name.
938 static int addrindex_write_elem_s( FILE *fp
, const gint lvl
, const gchar
*name
) {
940 for( i
= 0; i
< lvl
; i
++ )
941 if (claws_fputs( " ", fp
) == EOF
)
943 if (claws_fputs( "<", fp
) == EOF
)
945 if (claws_fputs( name
, fp
) == EOF
)
951 * Write end of XML element to file.
953 * \param lvl Indentation level.
954 * \param name Element name.
956 static int addrindex_write_elem_e( FILE *fp
, const gint lvl
, const gchar
*name
) {
958 for( i
= 0; i
< lvl
; i
++ )
959 if (claws_fputs( " ", fp
) == EOF
)
961 if (claws_fputs( "</", fp
) == EOF
)
963 if (claws_fputs( name
, fp
) == EOF
)
965 if (claws_fputs( ">\n", fp
) == EOF
)
971 * Write XML attribute to file.
973 * \param name Attribute name.
974 * \param value Attribute value.
976 static int addrindex_write_attr( FILE *fp
, const gchar
*name
, const gchar
*value
) {
977 if (claws_fputs( " ", fp
) == EOF
)
979 if (claws_fputs( name
, fp
) == EOF
)
981 if (claws_fputs( "=\"", fp
) == EOF
)
983 if (xml_file_put_escape_str( fp
, value
) < 0)
985 if (claws_fputs( "\"", fp
) == EOF
)
990 #if !defined(USE_LDAP) || !defined(USE_JPILOT)
992 * Return DOM fragment for current XML tag from file.
993 * \param file XML file being processed.
994 * \return Fragment representing DOM fragment for configuration element.
996 static AddressIfFragment
*addrindex_read_fragment( XMLFile
*file
) {
997 AddressIfFragment
*fragment
;
998 AddressIfFragment
*child
;
1008 /* g_print( "addrindex_read_fragment\n" ); */
1010 prevLevel
= file
->level
;
1012 /* Get current tag name */
1013 xtag
= xml_get_current_tag( file
);
1015 /* Create new fragment */
1016 fragment
= g_new0( AddressIfFragment
, 1 );
1017 fragment
->type
= ADBOOKTYPE_NONE
;
1018 fragment
->addressCache
= NULL
;
1019 fragment
->name
= g_strdup( xtag
->tag
);
1020 fragment
->children
= NULL
;
1021 fragment
->attributes
= NULL
;
1023 /* Read attributes */
1025 attr
= xml_get_current_tag_attr( file
);
1027 name
= ((XMLAttr
*)attr
->data
)->name
;
1028 value
= ((XMLAttr
*)attr
->data
)->value
;
1029 nv
= g_new0( AddressIfAttrib
, 1 );
1030 nv
->name
= g_strdup( name
);
1031 nv
->value
= g_strdup( value
);
1032 list
= g_list_append( list
, nv
);
1033 attr
= g_list_next( attr
);
1035 fragment
->attributes
= list
;
1037 /* Now read the children */
1039 rc
= xml_parse_next_tag( file
);
1044 if( file
->level
< prevLevel
) {
1045 /* We must be above level we start at */
1048 child
= addrindex_read_fragment( file
);
1049 fragment
->children
= g_list_append( fragment
->children
, child
);
1056 * Write DOM fragment to file.
1057 * \param fp File to write.
1058 * \param fragment DOM fragment for configuration element.
1059 * \param lvl Indent level.
1061 static int addrindex_write_fragment(
1062 FILE *fp
, const AddressIfFragment
*fragment
, const gint lvl
)
1067 if (addrindex_write_elem_s( fp
, lvl
, fragment
->name
) < 0)
1069 node
= fragment
->attributes
;
1071 AddressIfAttrib
*nv
= node
->data
;
1072 if (addrindex_write_attr( fp
, nv
->name
, nv
->value
) < 0)
1074 node
= g_list_next( node
);
1076 if( fragment
->children
) {
1077 if (claws_fputs(" >\n", fp
) == EOF
)
1080 /* Output children */
1081 node
= fragment
->children
;
1083 AddressIfFragment
*child
= node
->data
;
1084 if (addrindex_write_fragment( fp
, child
, 1+lvl
) < 0)
1086 node
= g_list_next( node
);
1089 /* Output closing tag */
1090 if (addrindex_write_elem_e( fp
, lvl
, fragment
->name
) < 0)
1094 if (claws_fputs(" />\n", fp
) == EOF
)
1103 * Read/parse address index file, creating a data source for a regular
1104 * intrinsic XML addressbook.
1105 * \param file Address index file.
1106 * \return Data source.
1108 static AddressDataSource
*addrindex_parse_book( XMLFile
*file
) {
1109 AddressDataSource
*ds
;
1110 AddressBookFile
*abf
;
1113 ds
= addrindex_create_datasource( ADDR_IF_BOOK
);
1114 abf
= addrbook_create_book();
1115 attr
= xml_get_current_tag_attr( file
);
1117 gchar
*name
= ((XMLAttr
*)attr
->data
)->name
;
1118 gchar
*value
= ((XMLAttr
*)attr
->data
)->value
;
1119 if( strcmp( name
, ATTAG_BOOK_NAME
) == 0 ) {
1120 addrbook_set_name( abf
, value
);
1122 else if( strcmp( name
, ATTAG_BOOK_FILE
) == 0) {
1123 addrbook_set_file( abf
, value
);
1125 attr
= g_list_next( attr
);
1127 ds
->rawDataSource
= abf
;
1131 static int addrindex_write_book( FILE *fp
, AddressDataSource
*ds
, gint lvl
) {
1132 AddressBookFile
*abf
= ds
->rawDataSource
;
1134 if (addrindex_write_elem_s( fp
, lvl
, TAG_DS_ADDRESS_BOOK
) < 0)
1136 if (addrindex_write_attr( fp
, ATTAG_BOOK_NAME
, addrbook_get_name( abf
) ) < 0)
1138 if (addrindex_write_attr( fp
, ATTAG_BOOK_FILE
, abf
->fileName
) < 0)
1140 if (claws_fputs( " />\n", fp
) == EOF
)
1146 static AddressDataSource
*addrindex_parse_vcard( XMLFile
*file
) {
1147 AddressDataSource
*ds
;
1151 ds
= addrindex_create_datasource( ADDR_IF_VCARD
);
1152 vcf
= vcard_create();
1153 attr
= xml_get_current_tag_attr( file
);
1155 gchar
*name
= ((XMLAttr
*)attr
->data
)->name
;
1156 gchar
*value
= ((XMLAttr
*)attr
->data
)->value
;
1157 if( strcmp( name
, ATTAG_VCARD_NAME
) == 0 ) {
1158 vcard_set_name( vcf
, value
);
1160 else if( strcmp( name
, ATTAG_VCARD_FILE
) == 0) {
1161 vcard_set_file( vcf
, value
);
1163 attr
= g_list_next( attr
);
1165 ds
->rawDataSource
= vcf
;
1169 static int addrindex_write_vcard( FILE *fp
, AddressDataSource
*ds
, gint lvl
) {
1170 VCardFile
*vcf
= ds
->rawDataSource
;
1172 if (addrindex_write_elem_s( fp
, lvl
, TAG_DS_VCARD
) < 0)
1174 if (addrindex_write_attr( fp
, ATTAG_VCARD_NAME
, vcard_get_name( vcf
) ) < 0)
1176 if (addrindex_write_attr( fp
, ATTAG_VCARD_FILE
, vcf
->path
) < 0)
1178 if (claws_fputs( " />\n", fp
) == EOF
)
1185 static AddressDataSource
*addrindex_parse_jpilot( XMLFile
*file
) {
1186 AddressDataSource
*ds
;
1190 ds
= addrindex_create_datasource( ADDR_IF_JPILOT
);
1191 jpf
= jpilot_create();
1192 attr
= xml_get_current_tag_attr( file
);
1194 gchar
*name
= ((XMLAttr
*)attr
->data
)->name
;
1195 gchar
*value
= ((XMLAttr
*)attr
->data
)->value
;
1196 if( strcmp( name
, ATTAG_JPILOT_NAME
) == 0 ) {
1197 jpilot_set_name( jpf
, value
);
1199 else if( strcmp( name
, ATTAG_JPILOT_FILE
) == 0 ) {
1200 jpilot_set_file( jpf
, value
);
1202 else if( strcmp( name
, ATTAG_JPILOT_CUSTOM_1
) == 0 ) {
1203 jpilot_add_custom_label( jpf
, value
);
1205 else if( strcmp( name
, ATTAG_JPILOT_CUSTOM_2
) == 0 ) {
1206 jpilot_add_custom_label( jpf
, value
);
1208 else if( strcmp( name
, ATTAG_JPILOT_CUSTOM_3
) == 0 ) {
1209 jpilot_add_custom_label( jpf
, value
);
1211 else if( strcmp( name
, ATTAG_JPILOT_CUSTOM_4
) == 0 ) {
1212 jpilot_add_custom_label( jpf
, value
);
1214 attr
= g_list_next( attr
);
1216 ds
->rawDataSource
= jpf
;
1220 static int addrindex_write_jpilot( FILE *fp
,AddressDataSource
*ds
, gint lvl
) {
1221 JPilotFile
*jpf
= ds
->rawDataSource
;
1225 GList
*customLbl
= jpilot_get_custom_labels( jpf
);
1226 if (addrindex_write_elem_s( fp
, lvl
, TAG_DS_JPILOT
) < 0)
1228 if (addrindex_write_attr( fp
, ATTAG_JPILOT_NAME
, jpilot_get_name( jpf
) ) < 0)
1230 if (addrindex_write_attr( fp
, ATTAG_JPILOT_FILE
, jpf
->path
) < 0)
1236 g_snprintf( name
, sizeof(name
), "%s%d",
1237 ATTAG_JPILOT_CUSTOM
, ind
);
1238 if (addrindex_write_attr( fp
, name
, node
->data
) < 0)
1241 node
= g_list_next( node
);
1243 if (claws_fputs( " />\n", fp
) == EOF
)
1251 * Just read/write DOM fragments (preserve data found in file).
1253 static AddressDataSource
*addrindex_parse_jpilot( XMLFile
*file
) {
1254 AddressDataSource
*ds
;
1256 ds
= addrindex_create_datasource( ADDR_IF_JPILOT
);
1257 ds
->rawDataSource
= addrindex_read_fragment( file
);
1261 static int addrindex_write_jpilot( FILE *fp
, AddressDataSource
*ds
, gint lvl
) {
1262 AddressIfFragment
*fragment
= ds
->rawDataSource
;
1264 if (addrindex_write_fragment( fp
, fragment
, lvl
) < 0)
1273 * Parse LDAP criteria attribute data from XML file.
1274 * \param file Index file.
1275 * \param ctl LDAP control object to populate.
1277 static void addrindex_parse_ldap_attrlist( XMLFile
*file
, LdapControl
*ctl
) {
1286 if( file
== NULL
) {
1291 prevLevel
= file
->level
;
1292 xtagPrev
= xml_get_current_tag( file
);
1294 rc
= xml_parse_next_tag( file
);
1296 /* Terminate prematurely */
1297 g_list_free_full( list
, g_free
);
1301 if( file
->level
< prevLevel
) {
1302 /* We must be above level we start at */
1306 /* Get a tag (element) */
1307 xtag
= xml_get_current_tag( file
);
1308 if( strcmp( xtag
->tag
, ELTAG_LDAP_ATTR_SRCH
) == 0 ) {
1309 /* LDAP criteria attribute */
1310 attr
= xml_get_current_tag_attr( file
);
1312 gchar
*name
= ((XMLAttr
*)attr
->data
)->name
;
1313 gchar
*value
= ((XMLAttr
*)attr
->data
)->value
;
1314 if( strcmp( name
, ATTAG_LDAP_ATTR_NAME
) == 0 ) {
1315 if( value
&& strlen( value
) > 0 ) {
1316 list
= g_list_append(
1317 list
, g_strdup( value
) );
1320 attr
= g_list_next( attr
);
1324 if( xtag
!= xtagPrev
) {
1325 /* Found a new tag */
1331 /* Build list of search attributes */
1332 ldapctl_criteria_list_clear( ctl
);
1335 ldapctl_criteria_list_add( ctl
, node
->data
);
1336 g_free( node
->data
);
1338 node
= g_list_next( node
);
1340 g_list_free( list
);
1345 void ldapsvr_set_control( LdapServer
*server
, LdapControl
*ctl
);
1347 * Parse LDAP control data from XML file.
1348 * \param file Index file.
1349 * \return Initialized data soruce object.
1351 static AddressDataSource
*addrindex_parse_ldap( XMLFile
*file
) {
1352 AddressDataSource
*ds
;
1356 gchar
*serverName
= NULL
;
1357 gchar
*criteria
= NULL
;
1358 gboolean bDynSearch
;
1359 gboolean bTLS
, bSSL
;
1361 gchar
*password
= NULL
;
1363 /* g_print( "addrindex_parse_ldap\n" ); */
1364 /* Set up some defaults */
1368 iMatch
= LDAPCTL_MATCH_BEGINWITH
;
1370 ds
= addrindex_create_datasource( ADDR_IF_LDAP
);
1371 ctl
= ldapctl_create();
1372 attr
= xml_get_current_tag_attr( file
);
1374 gchar
*name
= ((XMLAttr
*)attr
->data
)->name
;
1375 gchar
*value
= ((XMLAttr
*)attr
->data
)->value
;
1376 gint ivalue
= atoi( value
);
1378 if( strcmp( name
, ATTAG_LDAP_NAME
) == 0 ) {
1379 g_free( serverName
);
1380 serverName
= g_strdup( value
);
1382 else if( strcmp( name
, ATTAG_LDAP_HOST
) == 0 ) {
1383 ldapctl_set_host( ctl
, value
);
1385 else if( strcmp( name
, ATTAG_LDAP_PORT
) == 0 ) {
1386 ldapctl_set_port( ctl
, ivalue
);
1388 else if( strcmp( name
, ATTAG_LDAP_BASE_DN
) == 0 ) {
1389 ldapctl_set_base_dn( ctl
, value
);
1391 else if( strcmp( name
, ATTAG_LDAP_BIND_DN
) == 0 ) {
1392 ldapctl_set_bind_dn( ctl
, value
);
1394 else if( strcmp( name
, ATTAG_LDAP_BIND_PASS
) == 0 ) {
1397 else if( strcmp( name
, ATTAG_LDAP_CRITERIA
) == 0 ) {
1399 criteria
= g_strdup( value
);
1400 g_print("criteria %s\n", criteria
);
1402 else if( strcmp( name
, ATTAG_LDAP_MAX_ENTRY
) == 0 ) {
1403 ldapctl_set_max_entries( ctl
, ivalue
);
1405 else if( strcmp( name
, ATTAG_LDAP_TIMEOUT
) == 0 ) {
1406 ldapctl_set_timeout( ctl
, ivalue
);
1408 else if( strcmp( name
, ATTAG_LDAP_MAX_AGE
) == 0 ) {
1409 ldapctl_set_max_query_age( ctl
, ivalue
);
1411 else if( strcmp( name
, ATTAG_LDAP_DYN_SEARCH
) == 0 ) {
1413 if( strcmp( value
, ATVAL_BOOLEAN_YES
) == 0 ) {
1417 else if( strcmp( name
, ATTAG_LDAP_MATCH_OPT
) == 0 ) {
1418 iMatch
= LDAPCTL_MATCH_BEGINWITH
;
1419 if( strcmp( value
, ATVAL_LDAP_MATCH_CONTAINS
) == 0 ) {
1420 iMatch
= LDAPCTL_MATCH_CONTAINS
;
1423 else if( strcmp( name
, ATTAG_LDAP_ENABLE_TLS
) == 0 ) {
1425 if( strcmp( value
, ATVAL_BOOLEAN_YES
) == 0 ) {
1429 else if( strcmp( name
, ATTAG_LDAP_ENABLE_SSL
) == 0 ) {
1431 if( strcmp( value
, ATVAL_BOOLEAN_YES
) == 0 ) {
1435 attr
= g_list_next( attr
);
1438 if (password
!= NULL
)
1439 passwd_store_set(PWS_CORE
, "LDAP", ctl
->hostName
, password
, TRUE
);
1441 server
= ldapsvr_create_noctl();
1442 ldapsvr_set_name( server
, serverName
);
1443 ldapsvr_set_search_flag( server
, bDynSearch
);
1444 ldapctl_set_matching_option( ctl
, iMatch
);
1445 ldapctl_set_tls( ctl
, bTLS
);
1446 ldapctl_set_ssl( ctl
, bSSL
);
1447 g_free( serverName
);
1448 ldapsvr_set_control( server
, ctl
);
1449 ds
->rawDataSource
= server
;
1451 addrindex_parse_ldap_attrlist( file
, ctl
);
1453 * If criteria have been specified and no attributes were listed, then
1454 * convert old style criteria into an attribute list. Any criteria will
1455 * be dropped when saving data.
1458 if( ! ldapctl_get_criteria_list( ctl
) ) {
1459 ldapctl_parse_ldap_search( ctl
, criteria
);
1464 ldapsvr_print_data( server
, stdout
);
1470 static int addrindex_write_ldap( FILE *fp
, AddressDataSource
*ds
, gint lvl
) {
1471 LdapServer
*server
= ds
->rawDataSource
;
1472 LdapControl
*ctl
= NULL
;
1477 ctl
= server
->control
;
1479 if( ctl
== NULL
) return 0;
1481 /* Output start element with attributes */
1482 if (addrindex_write_elem_s( fp
, lvl
, TAG_DS_LDAP
) < 0)
1484 if (addrindex_write_attr( fp
, ATTAG_LDAP_NAME
, ldapsvr_get_name( server
) ) < 0)
1486 if (addrindex_write_attr( fp
, ATTAG_LDAP_HOST
, ctl
->hostName
) < 0)
1489 sprintf( value
, "%d", ctl
->port
);
1490 if (addrindex_write_attr( fp
, ATTAG_LDAP_PORT
, value
) < 0)
1493 if (addrindex_write_attr( fp
, ATTAG_LDAP_BASE_DN
, ctl
->baseDN
) < 0)
1495 if (addrindex_write_attr( fp
, ATTAG_LDAP_BIND_DN
, ctl
->bindDN
) < 0)
1498 sprintf( value
, "%d", ctl
->maxEntries
);
1499 if (addrindex_write_attr( fp
, ATTAG_LDAP_MAX_ENTRY
, value
) < 0)
1501 sprintf( value
, "%d", ctl
->timeOut
);
1502 if (addrindex_write_attr( fp
, ATTAG_LDAP_TIMEOUT
, value
) < 0)
1504 sprintf( value
, "%d", ctl
->maxQueryAge
);
1505 if (addrindex_write_attr( fp
, ATTAG_LDAP_MAX_AGE
, value
) < 0)
1508 if (addrindex_write_attr( fp
, ATTAG_LDAP_DYN_SEARCH
,
1509 server
->searchFlag
?
1510 ATVAL_BOOLEAN_YES
: ATVAL_BOOLEAN_NO
) < 0)
1513 if (addrindex_write_attr( fp
, ATTAG_LDAP_MATCH_OPT
,
1514 ( ctl
->matchingOption
== LDAPCTL_MATCH_CONTAINS
) ?
1515 ATVAL_LDAP_MATCH_CONTAINS
: ATVAL_LDAP_MATCH_BEGIN
) < 0)
1518 if (addrindex_write_attr( fp
, ATTAG_LDAP_ENABLE_TLS
,
1520 ATVAL_BOOLEAN_YES
: ATVAL_BOOLEAN_NO
) < 0)
1522 if (addrindex_write_attr( fp
, ATTAG_LDAP_ENABLE_SSL
,
1524 ATVAL_BOOLEAN_YES
: ATVAL_BOOLEAN_NO
) < 0)
1527 if (claws_fputs(" >\n", fp
) == EOF
)
1530 /* Output attributes */
1531 node
= ldapctl_get_criteria_list( ctl
);
1533 if (addrindex_write_elem_s( fp
, 1+lvl
, ELTAG_LDAP_ATTR_SRCH
) < 0)
1535 if (addrindex_write_attr( fp
, ATTAG_LDAP_ATTR_NAME
, node
->data
) < 0)
1537 if (claws_fputs(" />\n", fp
) == EOF
)
1539 node
= g_list_next( node
);
1542 /* End of element */
1543 if (addrindex_write_elem_e( fp
, lvl
, TAG_DS_LDAP
) < 0)
1551 * Just read/write DOM fragments (preserve data found in file).
1553 static AddressDataSource
*addrindex_parse_ldap( XMLFile
*file
) {
1554 AddressDataSource
*ds
;
1556 ds
= addrindex_create_datasource( ADDR_IF_LDAP
);
1557 ds
->rawDataSource
= addrindex_read_fragment( file
);
1561 static int addrindex_write_ldap( FILE *fp
, AddressDataSource
*ds
, gint lvl
) {
1562 AddressIfFragment
*fragment
= ds
->rawDataSource
;
1564 if (addrindex_write_fragment( fp
, fragment
, lvl
) < 0)
1571 /* **********************************************************************
1572 * Address index I/O functions.
1573 * ***********************************************************************
1576 * Read address index file, creating appropriate data sources for each address
1579 * \param addrIndex Address index.
1580 * \param file Address index file.
1582 static void addrindex_read_index( AddressIndex
*addrIndex
, XMLFile
*file
) {
1584 AddressInterface
*iface
= NULL
, *dsIFace
= NULL
;
1585 AddressDataSource
*ds
;
1588 addrIndex
->loadedFlag
= FALSE
;
1590 rc
= xml_parse_next_tag( file
);
1591 if( rc
< 0 || file
->level
== 0 ) return;
1593 xtag
= xml_get_current_tag( file
);
1595 iface
= addrindex_tag_get_interface( addrIndex
, xtag
->tag
, ADDR_IF_NONE
);
1597 addrIndex
->lastType
= iface
->type
;
1598 if( iface
->legacyFlag
) addrIndex
->needsConversion
= TRUE
;
1601 dsIFace
= addrindex_tag_get_datasource(
1602 addrIndex
, addrIndex
->lastType
, xtag
->tag
);
1604 /* Add data source to list */
1606 if( addrIndex
->lastType
== ADDR_IF_BOOK
) {
1607 ds
= addrindex_parse_book( file
);
1608 if( ds
->rawDataSource
) {
1609 addrbook_set_path( ds
->rawDataSource
,
1610 addrIndex
->filePath
);
1613 else if( addrIndex
->lastType
== ADDR_IF_VCARD
) {
1614 ds
= addrindex_parse_vcard( file
);
1616 else if( addrIndex
->lastType
== ADDR_IF_JPILOT
) {
1617 ds
= addrindex_parse_jpilot( file
);
1619 else if( addrIndex
->lastType
== ADDR_IF_LDAP
) {
1620 ds
= addrindex_parse_ldap( file
);
1623 ds
->interface
= dsIFace
;
1624 addrindex_hash_add_cache( addrIndex
, ds
);
1625 dsIFace
->listSource
=
1626 g_list_append( dsIFace
->listSource
, ds
);
1634 * Search order sorting comparison function for building search order list.
1636 static gint
addrindex_search_order_compare( gconstpointer ptrA
, gconstpointer ptrB
) {
1637 AddressInterface
*ifaceA
= ( AddressInterface
* ) ptrA
;
1638 AddressInterface
*ifaceB
= ( AddressInterface
* ) ptrB
;
1640 return ifaceA
->searchOrder
- ifaceB
->searchOrder
;
1644 * Build list of data sources to process.
1645 * \param addrIndex Address index object.
1647 static void addrindex_build_search_order( AddressIndex
*addrIndex
) {
1650 /* Clear existing list */
1651 g_list_free( addrIndex
->searchOrder
);
1652 addrIndex
->searchOrder
= NULL
;
1654 /* Build new list */
1655 nodeIf
= addrIndex
->interfaceList
;
1657 AddressInterface
*iface
= nodeIf
->data
;
1658 if( iface
->useInterface
) {
1659 if( iface
->searchOrder
> 0 ) {
1660 /* Add to search order list */
1661 addrIndex
->searchOrder
= g_list_insert_sorted(
1662 addrIndex
->searchOrder
, iface
,
1663 addrindex_search_order_compare
);
1666 nodeIf
= g_list_next( nodeIf
);
1670 static gint
addrindex_read_file( AddressIndex
*addrIndex
) {
1671 XMLFile
*file
= NULL
;
1672 gchar
*fileSpec
= NULL
;
1674 cm_return_val_if_fail( addrIndex
!= NULL
, -1 );
1676 fileSpec
= g_strconcat( addrIndex
->filePath
, G_DIR_SEPARATOR_S
, addrIndex
->fileName
, NULL
);
1677 addrIndex
->retVal
= MGU_NO_FILE
;
1678 file
= xml_open_file( fileSpec
);
1681 if( file
== NULL
) {
1683 g_print( " file '%s' does not exist.\n", addrIndex->fileName );
1685 return addrIndex
->retVal
;
1688 addrIndex
->retVal
= MGU_BAD_FORMAT
;
1689 if( xml_get_dtd( file
) == 0 ) {
1690 if( xml_parse_next_tag( file
) == 0 ) {
1691 if( xml_compare_tag( file
, TAG_ADDRESS_INDEX
) ) {
1692 addrindex_read_index( addrIndex
, file
);
1693 addrIndex
->retVal
= MGU_SUCCESS
;
1697 xml_close_file( file
);
1699 addrindex_build_search_order( addrIndex
);
1701 return addrIndex
->retVal
;
1704 static int addrindex_write_index( AddressIndex
*addrIndex
, FILE *fp
) {
1705 GList
*nodeIF
, *nodeDS
;
1707 gint lvlItem
= 1 + lvlList
;
1709 nodeIF
= addrIndex
->interfaceList
;
1711 AddressInterface
*iface
= nodeIF
->data
;
1712 if( ! iface
->legacyFlag
) {
1713 nodeDS
= iface
->listSource
;
1714 if (addrindex_write_elem_s( fp
, lvlList
, iface
->listTag
) < 0)
1716 if (claws_fputs( ">\n", fp
) == EOF
)
1719 AddressDataSource
*ds
= nodeDS
->data
;
1721 if( iface
->type
== ADDR_IF_BOOK
) {
1722 if (addrindex_write_book( fp
, ds
, lvlItem
) < 0)
1725 if( iface
->type
== ADDR_IF_VCARD
) {
1726 if (addrindex_write_vcard( fp
, ds
, lvlItem
) < 0)
1729 if( iface
->type
== ADDR_IF_JPILOT
) {
1730 if (addrindex_write_jpilot( fp
, ds
, lvlItem
) < 0)
1733 if( iface
->type
== ADDR_IF_LDAP
) {
1734 if (addrindex_write_ldap( fp
, ds
, lvlItem
) < 0)
1738 nodeDS
= g_list_next( nodeDS
);
1740 if (addrindex_write_elem_e( fp
, lvlList
, iface
->listTag
) < 0)
1743 nodeIF
= g_list_next( nodeIF
);
1749 * Write data to specified file.
1750 * Enter: addrIndex Address index object.
1751 * newFile New file name.
1752 * return: Status code, from addrIndex->retVal.
1753 * Note: File will be created in directory specified by addrIndex.
1755 static gint
addrindex_write_to( AddressIndex
*addrIndex
, const gchar
*newFile
) {
1758 #ifndef DEV_STANDALONE
1762 cm_return_val_if_fail( addrIndex
!= NULL
, -1 );
1764 fileSpec
= g_strconcat( addrIndex
->filePath
, G_DIR_SEPARATOR_S
, newFile
, NULL
);
1765 addrIndex
->retVal
= MGU_OPEN_FILE
;
1766 #ifdef DEV_STANDALONE
1767 fp
= claws_fopen( fileSpec
, "wb" );
1770 claws_fputs( "<?xml version=\"1.0\" ?>\n", fp
);
1772 pfile
= prefs_write_open( fileSpec
);
1776 if (fprintf( fp
, "<?xml version=\"1.0\" encoding=\"%s\" ?>\n", CS_INTERNAL
) < 0)
1779 if (addrindex_write_elem_s( fp
, 0, TAG_ADDRESS_INDEX
) < 0)
1781 if (claws_fputs( ">\n", fp
) == EOF
)
1784 if (addrindex_write_index( addrIndex
, fp
) < 0)
1786 if (addrindex_write_elem_e( fp
, 0, TAG_ADDRESS_INDEX
) < 0)
1789 addrIndex
->retVal
= MGU_SUCCESS
;
1790 #ifdef DEV_STANDALONE
1791 claws_safe_fclose( fp
);
1793 if( prefs_file_close( pfile
) < 0 ) {
1794 addrIndex
->retVal
= MGU_ERROR_WRITE
;
1800 return addrIndex
->retVal
;
1802 g_warning("error writing AB index");
1803 addrIndex
->retVal
= MGU_ERROR_WRITE
;
1805 prefs_file_close_revert( pfile
);
1806 return addrIndex
->retVal
;
1810 * Save address index data to original file.
1811 * return: Status code, from addrIndex->retVal.
1813 gint
addrindex_save_data( AddressIndex
*addrIndex
) {
1819 cm_return_val_if_fail( addrIndex
!= NULL
, -1 );
1822 nodeIf
= addrIndex
->interfaceList
;
1823 /* save LDAP interfaces */
1825 AddressInterface
*iface
= nodeIf
->data
;
1826 if( iface
->type
== ADDR_IF_LDAP
) {
1827 nodeDS
= iface
->listSource
;
1829 AddressDataSource
*ds
= nodeDS
->data
;
1830 LdapServer
*abf
= ds
->rawDataSource
;
1831 if( ldapsvr_get_read_flag( abf
) ) {
1832 if( ldapsvr_get_modified( abf
) ) {
1833 ldapsvr_update_book( abf
, NULL
);
1834 if( abf
->retVal
!= LDAPRC_SUCCESS
) {
1835 alertpanel( _("Address(es) update"),
1836 _("Update failed. Changes not written to Directory."),
1837 "window-close", _("_Close"), NULL
, NULL
,
1838 NULL
, NULL
, ALERTFOCUS_FIRST
);
1841 abf
->retVal
= MGU_SUCCESS
;
1842 ldapsvr_set_modified( abf
, FALSE
);
1846 nodeDS
= g_list_next( nodeDS
);
1850 nodeIf
= g_list_next( nodeIf
);
1853 addrIndex
->retVal
= MGU_NO_FILE
;
1854 if( addrIndex
->fileName
== NULL
|| *addrIndex
->fileName
== '\0' ) return addrIndex
->retVal
;
1855 if( addrIndex
->filePath
== NULL
|| *addrIndex
->filePath
== '\0' ) return addrIndex
->retVal
;
1857 addrindex_write_to( addrIndex
, addrIndex
->fileName
);
1858 if( addrIndex
->retVal
== MGU_SUCCESS
) {
1859 addrIndex
->dirtyFlag
= FALSE
;
1861 return addrIndex
->retVal
;
1865 * Save all address book files which may have changed.
1866 * Return: Status code, set if there was a problem saving data.
1868 gint
addrindex_save_all_books( AddressIndex
*addrIndex
) {
1869 gint retVal
= MGU_SUCCESS
;
1870 GList
*nodeIf
, *nodeDS
;
1872 nodeIf
= addrIndex
->interfaceList
;
1874 AddressInterface
*iface
= nodeIf
->data
;
1875 if( iface
->type
== ADDR_IF_BOOK
) {
1876 nodeDS
= iface
->listSource
;
1878 AddressDataSource
*ds
= nodeDS
->data
;
1879 AddressBookFile
*abf
= ds
->rawDataSource
;
1880 if( addrbook_get_dirty( abf
) ) {
1881 if( addrbook_get_read_flag( abf
) ) {
1882 addrbook_save_data( abf
);
1883 if( abf
->retVal
!= MGU_SUCCESS
) {
1884 retVal
= abf
->retVal
;
1888 nodeDS
= g_list_next( nodeDS
);
1892 nodeIf
= g_list_next( nodeIf
);
1898 /* **********************************************************************
1899 * Address book conversion to new format.
1900 * ***********************************************************************
1903 #define ELTAG_IF_OLD_FOLDER "folder"
1904 #define ELTAG_IF_OLD_GROUP "group"
1905 #define ELTAG_IF_OLD_ITEM "item"
1906 #define ELTAG_IF_OLD_NAME "name"
1907 #define ELTAG_IF_OLD_ADDRESS "address"
1908 #define ELTAG_IF_OLD_REMARKS "remarks"
1909 #define ATTAG_IF_OLD_NAME "name"
1911 #define TEMPNODE_ROOT 0
1912 #define TEMPNODE_FOLDER 1
1913 #define TEMPNODE_GROUP 2
1914 #define TEMPNODE_ADDRESS 3
1916 typedef struct _AddressCvt_Node AddressCvtNode
;
1917 struct _AddressCvt_Node
{
1926 * Parse current address item.
1928 static AddressCvtNode
*addrindex_parse_item( XMLFile
*file
) {
1933 nn
= g_new0( AddressCvtNode
, 1 );
1934 nn
->type
= TEMPNODE_ADDRESS
;
1937 level
= file
->level
;
1940 xml_parse_next_tag(file
);
1941 if (file
->level
< level
) return nn
;
1943 element
= xml_get_element( file
);
1944 if( xml_compare_tag( file
, ELTAG_IF_OLD_NAME
) ) {
1945 nn
->name
= g_strdup( element
);
1947 if( xml_compare_tag( file
, ELTAG_IF_OLD_ADDRESS
) ) {
1948 nn
->address
= g_strdup( element
);
1950 if( xml_compare_tag( file
, ELTAG_IF_OLD_REMARKS
) ) {
1951 nn
->remarks
= g_strdup( element
);
1954 xml_parse_next_tag(file
);
1959 * Create a temporary node below specified node.
1961 static AddressCvtNode
*addrindex_add_object( AddressCvtNode
*node
, gint type
, gchar
*name
, gchar
*addr
, char *rem
) {
1963 nn
= g_new0( AddressCvtNode
, 1 );
1965 nn
->name
= g_strdup( name
);
1966 nn
->remarks
= g_strdup( rem
);
1967 node
->list
= g_list_append( node
->list
, nn
);
1972 * Process current temporary node.
1974 static void addrindex_add_obj( XMLFile
*file
, AddressCvtNode
*node
) {
1977 AddressCvtNode
*newNode
= NULL
;
1982 prev_level
= file
->level
;
1983 xml_parse_next_tag( file
);
1984 if (file
->level
< prev_level
) return;
1988 if( xml_compare_tag( file
, ELTAG_IF_OLD_GROUP
) ) {
1989 attr
= xml_get_current_tag_attr(file
);
1991 name
= ((XMLAttr
*)attr
->data
)->name
;
1992 if( strcmp( name
, ATTAG_IF_OLD_NAME
) == 0 ) {
1993 value
= ((XMLAttr
*)attr
->data
)->value
;
1996 newNode
= addrindex_add_object( node
, TEMPNODE_GROUP
, value
, "", "" );
1997 addrindex_add_obj( file
, newNode
);
2000 else if( xml_compare_tag( file
, ELTAG_IF_OLD_FOLDER
) ) {
2001 attr
= xml_get_current_tag_attr(file
);
2003 name
= ((XMLAttr
*)attr
->data
)->name
;
2004 if( strcmp( name
, ATTAG_IF_OLD_NAME
) == 0 ) {
2005 value
= ((XMLAttr
*)attr
->data
)->value
;
2008 newNode
= addrindex_add_object( node
, TEMPNODE_FOLDER
, value
, "", "" );
2009 addrindex_add_obj( file
, newNode
);
2011 else if( xml_compare_tag( file
, ELTAG_IF_OLD_ITEM
) ) {
2012 newNode
= addrindex_parse_item( file
);
2013 node
->list
= g_list_append( node
->list
, newNode
);
2016 g_warning("invalid tag");
2022 * Consume all nodes below current tag.
2024 static void addrindex_consume_tree( XMLFile
*file
) {
2028 prev_level
= file
->level
;
2029 xml_parse_next_tag( file
);
2030 if (file
->level
< prev_level
)
2033 addrindex_consume_tree( file
);
2038 * Free up temporary tree.
2040 static void addrindex_free_node( AddressCvtNode
*node
) {
2041 GList
*list
= node
->list
;
2044 AddressCvtNode
*lNode
= list
->data
;
2045 list
= g_list_next( list
);
2046 addrindex_free_node( lNode
);
2048 node
->type
= TEMPNODE_ROOT
;
2049 g_free( node
->name
);
2050 g_free( node
->address
);
2051 g_free( node
->remarks
);
2052 g_list_free( node
->list
);
2057 * Process address book for specified node.
2059 static void addrindex_process_node(
2060 AddressBookFile
*abf
, AddressCvtNode
*node
, ItemFolder
*parent
,
2061 ItemGroup
*parentGrp
, ItemFolder
*folderGrp
)
2064 ItemFolder
*itemFolder
= NULL
;
2065 ItemGroup
*itemGParent
= parentGrp
;
2066 ItemFolder
*itemGFolder
= folderGrp
;
2067 AddressCache
*cache
= abf
->addressCache
;
2069 if( node
->type
== TEMPNODE_ROOT
) {
2070 itemFolder
= parent
;
2072 else if( node
->type
== TEMPNODE_FOLDER
) {
2073 itemFolder
= addritem_create_item_folder();
2074 addritem_folder_set_name( itemFolder
, node
->name
);
2075 addrcache_id_folder( cache
, itemFolder
);
2076 addrcache_folder_add_folder( cache
, parent
, itemFolder
);
2079 else if( node
->type
== TEMPNODE_GROUP
) {
2080 ItemGroup
*itemGroup
;
2083 /* Create a folder for group */
2084 fName
= g_strdup_printf( "Cvt - %s", node
->name
);
2085 itemGFolder
= addritem_create_item_folder();
2086 addritem_folder_set_name( itemGFolder
, fName
);
2087 addrcache_id_folder( cache
, itemGFolder
);
2088 addrcache_folder_add_folder( cache
, parent
, itemGFolder
);
2091 /* Add group into folder */
2092 itemGroup
= addritem_create_item_group();
2093 addritem_group_set_name( itemGroup
, node
->name
);
2094 addrcache_id_group( cache
, itemGroup
);
2095 addrcache_folder_add_group( cache
, itemGFolder
, itemGroup
);
2096 itemGParent
= itemGroup
;
2098 else if( node
->type
== TEMPNODE_ADDRESS
) {
2099 ItemPerson
*itemPerson
;
2100 ItemEMail
*itemEMail
;
2102 /* Create person and email objects */
2103 itemPerson
= addritem_create_item_person();
2104 addritem_person_set_common_name( itemPerson
, node
->name
);
2105 addrcache_id_person( cache
, itemPerson
);
2106 itemEMail
= addritem_create_item_email();
2107 addritem_email_set_address( itemEMail
, node
->address
);
2108 addritem_email_set_remarks( itemEMail
, node
->remarks
);
2109 addrcache_id_email( cache
, itemEMail
);
2110 addrcache_person_add_email( cache
, itemPerson
, itemEMail
);
2112 /* Add person into appropriate folder */
2114 addrcache_folder_add_person( cache
, itemGFolder
, itemPerson
);
2117 addrcache_folder_add_person( cache
, parent
, itemPerson
);
2120 /* Add email address only into group */
2122 addrcache_group_add_email( cache
, parentGrp
, itemEMail
);
2128 AddressCvtNode
*lNode
= list
->data
;
2129 list
= g_list_next( list
);
2130 addrindex_process_node( abf
, lNode
, itemFolder
, itemGParent
, itemGFolder
);
2135 * Process address book to specified file number.
2137 static gboolean
addrindex_process_book( AddressIndex
*addrIndex
, XMLFile
*file
, gchar
*displayName
) {
2138 gboolean retVal
= FALSE
;
2139 AddressBookFile
*abf
= NULL
;
2140 AddressCvtNode
*rootNode
= NULL
;
2141 gchar
*newFile
= NULL
;
2142 GList
*fileList
= NULL
;
2145 /* Setup root node */
2146 rootNode
= g_new0( AddressCvtNode
, 1 );
2147 rootNode
->type
= TEMPNODE_ROOT
;
2148 rootNode
->name
= g_strdup( "root" );
2149 rootNode
->list
= NULL
;
2150 addrindex_add_obj( file
, rootNode
);
2151 /* addrindex_print_node( rootNode, stdout ); */
2153 /* Create new address book */
2154 abf
= addrbook_create_book();
2155 addrbook_set_name( abf
, displayName
);
2156 addrbook_set_path( abf
, addrIndex
->filePath
);
2158 /* Determine next available file number */
2159 fileList
= addrbook_get_bookfile_list( abf
);
2161 fileNum
= 1 + abf
->maxValue
;
2163 g_list_free( fileList
);
2166 newFile
= addrbook_gen_new_file_name( fileNum
);
2168 addrbook_set_file( abf
, newFile
);
2171 addrindex_process_node( abf
, rootNode
, abf
->addressCache
->rootFolder
, NULL
, NULL
);
2173 #ifdef DEBUG_ADDRBOOK
2174 addrbook_dump_book( abf
, stdout
);
2176 addrbook_save_data( abf
);
2177 addrIndex
->retVal
= abf
->retVal
;
2178 if( abf
->retVal
== MGU_SUCCESS
) retVal
= TRUE
;
2180 addrbook_free_book( abf
);
2182 addrindex_free_node( rootNode
);
2185 /* Create entries in address index */
2187 abf
= addrbook_create_book();
2188 addrbook_set_name( abf
, displayName
);
2189 addrbook_set_path( abf
, addrIndex
->filePath
);
2190 addrbook_set_file( abf
, newFile
);
2191 addrindex_index_add_datasource( addrIndex
, ADDR_IF_BOOK
, abf
);
2198 * Process tree converting data.
2200 static void addrindex_convert_tree( AddressIndex
*addrIndex
, XMLFile
*file
) {
2206 prev_level
= file
->level
;
2207 xml_parse_next_tag( file
);
2208 if (file
->level
< prev_level
) return;
2210 xtag
= xml_get_current_tag( file
);
2211 /* g_print( "tag : %d : %s\n", prev_level, xtag->tag ); */
2212 if( strcmp( xtag
->tag
, TAG_IF_OLD_COMMON
) == 0 ) {
2213 if( addrindex_process_book( addrIndex
, file
, DISP_OLD_COMMON
) ) {
2214 addrIndex
->needsConversion
= FALSE
;
2215 addrIndex
->wasConverted
= TRUE
;
2220 if( strcmp( xtag
->tag
, TAG_IF_OLD_PERSONAL
) == 0 ) {
2221 if( addrindex_process_book( addrIndex
, file
, DISP_OLD_PERSONAL
) ) {
2222 addrIndex
->needsConversion
= FALSE
;
2223 addrIndex
->wasConverted
= TRUE
;
2228 addrindex_consume_tree( file
);
2232 static gint
addrindex_convert_data( AddressIndex
*addrIndex
) {
2233 XMLFile
*file
= NULL
;
2236 fileSpec
= g_strconcat( addrIndex
->filePath
, G_DIR_SEPARATOR_S
, addrIndex
->fileName
, NULL
);
2237 addrIndex
->retVal
= MGU_NO_FILE
;
2238 file
= xml_open_file( fileSpec
);
2241 if( file
== NULL
) {
2242 /* g_print( " file '%s' does not exist.\n", addrIndex->fileName ); */
2243 return addrIndex
->retVal
;
2246 addrIndex
->retVal
= MGU_BAD_FORMAT
;
2247 if( xml_get_dtd( file
) == 0 ) {
2248 if( xml_parse_next_tag( file
) == 0 ) {
2249 if( xml_compare_tag( file
, TAG_ADDRESS_INDEX
) ) {
2250 addrindex_convert_tree( addrIndex
, file
);
2254 xml_close_file( file
);
2255 return addrIndex
->retVal
;
2259 * Create a new address book file.
2261 static gboolean
addrindex_create_new_book( AddressIndex
*addrIndex
, gchar
*displayName
) {
2262 gboolean retVal
= FALSE
;
2263 AddressBookFile
*abf
= NULL
;
2264 gchar
*newFile
= NULL
;
2265 GList
*fileList
= NULL
;
2268 /* Create new address book */
2269 abf
= addrbook_create_book();
2270 addrbook_set_name( abf
, displayName
);
2271 addrbook_set_path( abf
, addrIndex
->filePath
);
2273 /* Determine next available file number */
2274 fileList
= addrbook_get_bookfile_list( abf
);
2276 fileNum
= 1 + abf
->maxValue
;
2278 g_list_free( fileList
);
2281 newFile
= addrbook_gen_new_file_name( fileNum
);
2283 addrbook_set_file( abf
, newFile
);
2286 addrbook_save_data( abf
);
2287 addrIndex
->retVal
= abf
->retVal
;
2288 if( abf
->retVal
== MGU_SUCCESS
) retVal
= TRUE
;
2289 addrbook_free_book( abf
);
2292 /* Create entries in address index */
2294 abf
= addrbook_create_book();
2295 addrbook_set_name( abf
, displayName
);
2296 addrbook_set_path( abf
, addrIndex
->filePath
);
2297 addrbook_set_file( abf
, newFile
);
2298 addrindex_index_add_datasource( addrIndex
, ADDR_IF_BOOK
, abf
);
2305 * Read data for address index performing a conversion if necesary.
2306 * Enter: addrIndex Address index object.
2307 * return: Status code, from addrIndex->retVal.
2308 * Note: New address book files will be created in directory specified by
2309 * addrIndex. Three files will be created, for the following:
2310 * "Common addresses"
2311 * "Personal addresses"
2312 * "Gathered addresses" - a new address book.
2314 gint
addrindex_read_data( AddressIndex
*addrIndex
) {
2315 cm_return_val_if_fail( addrIndex
!= NULL
, -1 );
2317 addrIndex
->conversionError
= FALSE
;
2318 addrindex_read_file( addrIndex
);
2319 if( addrIndex
->retVal
== MGU_SUCCESS
) {
2320 if( addrIndex
->needsConversion
) {
2321 if( addrindex_convert_data( addrIndex
) == MGU_SUCCESS
)
2322 addrIndex
->conversionError
= FALSE
;
2324 addrIndex
->conversionError
= TRUE
;
2326 addrIndex
->dirtyFlag
= TRUE
;
2328 return addrIndex
->retVal
;
2332 * Create new address books for a new address index.
2333 * Enter: addrIndex Address index object.
2334 * return: Status code, from addrIndex->retVal.
2335 * Note: New address book files will be created in directory specified by
2336 * addrIndex. Three files will be created, for the following:
2337 * "Common addresses"
2338 * "Personal addresses"
2339 * "Gathered addresses" - a new address book.
2341 gint
addrindex_create_new_books( AddressIndex
*addrIndex
) {
2344 cm_return_val_if_fail( addrIndex
!= NULL
, -1 );
2346 flg
= addrindex_create_new_book( addrIndex
, DISP_NEW_COMMON
);
2348 flg
= addrindex_create_new_book( addrIndex
, DISP_NEW_PERSONAL
);
2349 addrIndex
->dirtyFlag
= TRUE
;
2351 return addrIndex
->retVal
;
2354 /* **********************************************************************
2355 * New interface stuff.
2356 * ***********************************************************************
2360 * Return modified flag for specified data source.
2362 gboolean
addrindex_ds_get_modify_flag( AddressDataSource
*ds
) {
2363 gboolean retVal
= FALSE
;
2364 AddressInterface
*iface
;
2366 if( ds
== NULL
) return retVal
;
2367 iface
= ds
->interface
;
2368 if( iface
== NULL
) return retVal
;
2369 if( iface
->getModifyFlag
) {
2370 retVal
= ( iface
->getModifyFlag
) ( ds
->rawDataSource
);
2376 * Return accessed flag for specified data source.
2378 gboolean
addrindex_ds_get_access_flag( AddressDataSource
*ds
) {
2379 gboolean retVal
= FALSE
;
2380 AddressInterface
*iface
;
2382 if( ds
== NULL
) return retVal
;
2383 iface
= ds
->interface
;
2384 if( iface
== NULL
) return retVal
;
2385 if( iface
->getAccessFlag
) {
2386 retVal
= ( iface
->getAccessFlag
) ( ds
->rawDataSource
);
2392 * Return data read flag for specified data source.
2394 gboolean
addrindex_ds_get_read_flag( AddressDataSource
*ds
) {
2395 gboolean retVal
= TRUE
;
2396 AddressInterface
*iface
;
2398 if( ds
== NULL
) return retVal
;
2399 iface
= ds
->interface
;
2400 if( iface
== NULL
) return retVal
;
2401 if( iface
->getReadFlag
) {
2402 retVal
= ( iface
->getReadFlag
) ( ds
->rawDataSource
);
2408 * Return status code for specified data source.
2410 gint
addrindex_ds_get_status_code( AddressDataSource
*ds
) {
2411 gint retVal
= MGU_SUCCESS
;
2412 AddressInterface
*iface
;
2414 if( ds
== NULL
) return retVal
;
2415 iface
= ds
->interface
;
2416 if( iface
== NULL
) return retVal
;
2417 if( iface
->getStatusCode
) {
2418 retVal
= ( iface
->getStatusCode
) ( ds
->rawDataSource
);
2424 * Return data read flag for specified data source.
2426 gint
addrindex_ds_read_data( AddressDataSource
*ds
) {
2427 gint retVal
= MGU_SUCCESS
;
2428 AddressInterface
*iface
;
2430 if( ds
== NULL
) return retVal
;
2431 iface
= ds
->interface
;
2432 if( iface
== NULL
) return retVal
;
2433 if( iface
->getReadData
) {
2435 gchar *name = ( iface->getName ) ( ds->rawDataSource );
2436 g_print( "addrindex_ds_read_data...reading:::%s:::\n", name );
2438 retVal
= ( iface
->getReadData
) ( ds
->rawDataSource
);
2444 * Return data read flag for specified data source.
2446 ItemFolder
*addrindex_ds_get_root_folder( AddressDataSource
*ds
) {
2447 ItemFolder
*retVal
= NULL
;
2448 AddressInterface
*iface
;
2450 if( ds
== NULL
) return retVal
;
2451 iface
= ds
->interface
;
2452 if( iface
== NULL
) return retVal
;
2453 if( iface
->getRootFolder
) {
2454 retVal
= ( iface
->getRootFolder
) ( ds
->rawDataSource
);
2460 * Return name for specified data source.
2462 gchar
*addrindex_ds_get_name( AddressDataSource
*ds
) {
2463 gchar
*retVal
= FALSE
;
2464 AddressInterface
*iface
;
2466 if( ds
== NULL
) return retVal
;
2467 iface
= ds
->interface
;
2468 if( iface
== NULL
) return retVal
;
2469 if( iface
->getName
) {
2470 retVal
= ( iface
->getName
) ( ds
->rawDataSource
);
2476 * Set the access flag inside the data source.
2478 void addrindex_ds_set_access_flag( AddressDataSource
*ds
, gboolean
*value
) {
2479 AddressInterface
*iface
;
2481 if( ds
== NULL
) return;
2482 iface
= ds
->interface
;
2483 if( iface
== NULL
) return;
2484 if( iface
->setAccessFlag
) {
2485 ( iface
->setAccessFlag
) ( ds
->rawDataSource
, value
);
2490 * Return read only flag for specified data source.
2492 gboolean
addrindex_ds_get_readonly( AddressDataSource
*ds
) {
2493 AddressInterface
*iface
;
2494 if( ds
== NULL
) return TRUE
;
2495 iface
= ds
->interface
;
2496 if( iface
== NULL
) return TRUE
;
2497 return iface
->readOnly
;
2501 * Return list of all persons for specified data source.
2503 static GList
*addrindex_ds_get_all_persons( AddressDataSource
*ds
) {
2504 GList
*retVal
= NULL
;
2505 AddressInterface
*iface
;
2507 if( ds
== NULL
) return retVal
;
2508 iface
= ds
->interface
;
2509 if( iface
== NULL
) return retVal
;
2510 if( iface
->getAllPersons
) {
2511 retVal
= ( iface
->getAllPersons
) ( ds
->rawDataSource
);
2517 * Return list of all groups for specified data source.
2519 static GList
*addrindex_ds_get_all_groups( AddressDataSource
*ds
) {
2520 GList
*retVal
= NULL
;
2521 AddressInterface
*iface
;
2523 if( ds
== NULL
) return retVal
;
2524 iface
= ds
->interface
;
2525 if( iface
== NULL
) return retVal
;
2526 if( iface
->getAllGroups
) {
2527 retVal
= ( iface
->getAllGroups
) ( ds
->rawDataSource
);
2532 /* **********************************************************************
2533 * Address search stuff.
2534 * ***********************************************************************
2538 * Setup or register the dynamic search that will be performed. The search
2539 * is registered with the query manager.
2541 * \param searchTerm Search term. A private copy will be made.
2542 * \param callBackEntry Callback function that should be called when
2543 * each entry is received.
2544 * \param callBackEnd Callback function that should be called when
2545 * search has finished running.
2546 * \return ID allocated to query that will be executed.
2548 gint
addrindex_setup_search(
2549 const gchar
*searchTerm
, void *callBackEnd
, void *callBackEntry
)
2554 /* Set up a dynamic address query */
2555 req
= qrymgr_add_request( searchTerm
, callBackEnd
, callBackEntry
);
2556 queryID
= req
->queryID
;
2557 qryreq_set_search_type( req
, ADDRSEARCH_DYNAMIC
);
2559 /* g_print( "***> query ID ::%d::\n", queryID ); */
2566 * Function prototypes (not in header file or circular reference errors are
2569 LdapQuery
*ldapsvr_new_dynamic_search(
2570 LdapServer
*server
, QueryRequest
*req
);
2571 LdapQuery
*ldapsvr_new_explicit_search(
2572 LdapServer
*server
, QueryRequest
*req
, ItemFolder
*folder
);
2573 void ldapsvr_execute_query( LdapServer
*server
, LdapQuery
*qry
);
2578 * Execute the previously registered dynamic search.
2580 * \param req Address query object to execute.
2581 * \return <i>TRUE</i> if search started successfully, or <i>FALSE</i> if
2584 static gboolean
addrindex_start_dynamic( QueryRequest
*req
) {
2585 AddressInterface
*iface
;
2586 AddressDataSource
*ds
;
2591 /* g_print( "addrindex_start_dynamic::%d::\n", req->queryID ); */
2592 nodeIf
= _addressIndex_
->searchOrder
;
2594 iface
= nodeIf
->data
;
2595 nodeIf
= g_list_next( nodeIf
);
2597 if( ! iface
->useInterface
) {
2600 if( ! iface
->externalQuery
) {
2605 nodeDS
= iface
->listSource
;
2608 nodeDS
= g_list_next( nodeDS
);
2610 if( type
== ADDR_IF_LDAP
) {
2614 server
= ds
->rawDataSource
;
2615 if( ! server
->searchFlag
) {
2618 if( ldapsvr_reuse_previous( server
, req
) ) {
2622 /* Start a new dynamic search */
2623 qry
= ldapsvr_new_dynamic_search( server
, req
);
2625 ldapsvr_execute_query( server
, qry
);
2635 * Stop the previously registered search.
2637 * \param queryID ID of search query to stop.
2639 void addrindex_stop_search( const gint queryID
){
2641 AddrQueryObject
*aqo
;
2644 /* g_print( "addrindex_stop_search/queryID=%d\n", queryID ); */
2645 /* If query ID does not match, search has not been setup */
2646 req
= qrymgr_find_request( queryID
);
2651 /* Stop all queries that were associated with request */
2652 node
= req
->queryList
;
2656 if( aqo
->queryType
== ADDRQUERY_LDAP
) {
2657 LdapQuery
*qry
= ( LdapQuery
* ) aqo
;
2658 ldapqry_set_stop_flag( qry
, TRUE
);
2662 node
= g_list_next( node
);
2665 /* Delete query request */
2666 qrymgr_delete_request( queryID
);
2670 * Setup or register the explicit search that will be performed. The search is
2671 * registered with the query manager.
2673 * \param ds Data source to search.
2674 * \param searchTerm Search term to locate.
2675 * \param folder Folder to receive search results; may be NULL.
2676 * \param callbackEnd Function to call when search has terminated.
2677 * \param callbackEntry Function to called for each entry processed.
2678 * \return ID allocated to query that will be executed.
2680 gint
addrindex_setup_explicit_search(
2681 AddressDataSource
*ds
, const gchar
*searchTerm
, ItemFolder
*folder
,
2682 void *callBackEnd
, void *callBackEntry
)
2689 /* Name the query */
2690 name
= g_strdup_printf( "Search '%s'", searchTerm
);
2692 /* Set up query request */
2693 if (!strcmp(searchTerm
, "*"))
2694 mySearch
= g_strdup("*@");
2696 mySearch
= g_strdup(searchTerm
);
2698 req
= qrymgr_add_request( mySearch
, callBackEnd
, callBackEntry
);
2702 qryreq_set_search_type( req
, ADDRSEARCH_EXPLICIT
);
2703 queryID
= req
->queryID
;
2705 if( ds
->type
== ADDR_IF_LDAP
) {
2709 server
= ds
->rawDataSource
;
2710 ldapsvr_new_explicit_search( server
, req
, folder
);
2714 qrymgr_delete_request( queryID
);
2723 * Execute the previously registered explicit search.
2725 * \param req Address query request object to execute.
2726 * \return <i>TRUE</i> if search started successfully, or <i>FALSE</i> if
2729 static gboolean
addrindex_start_explicit( QueryRequest
*req
) {
2731 AddrQueryObject
*aqo
;
2735 /* Note: there should only be one query in the list. */
2736 aqo
= req
->queryList
->data
;
2738 if( aqo
->queryType
== ADDRQUERY_LDAP
) {
2742 qry
= ( LdapQuery
* ) aqo
;
2743 server
= qry
->server
;
2745 /* Start the search */
2747 ldapsvr_execute_query( server
, qry
);
2754 * Start the previously registered search.
2756 * \param queryID ID of search query to be executed.
2757 * \return <i>TRUE</i> if search started successfully, or <i>FALSE</i> if
2760 gboolean
addrindex_start_search( const gint queryID
) {
2763 AddrSearchType searchType
;
2766 /* g_print( "addrindex_start_search/queryID=%d\n", queryID ); */
2767 req
= qrymgr_find_request( queryID
);
2772 searchType
= req
->searchType
;
2773 if( searchType
== ADDRSEARCH_DYNAMIC
) {
2774 retVal
= addrindex_start_dynamic( req
);
2776 else if( searchType
== ADDRSEARCH_EXPLICIT
) {
2777 retVal
= addrindex_start_explicit( req
);
2784 * Remove results (folder and data) for specified data source and folder.
2785 * \param ds Data source to process.
2786 * \param folder Results folder to remove.
2788 void addrindex_remove_results( AddressDataSource
*ds
, ItemFolder
*folder
) {
2789 AddrBookBase
*adbase
;
2792 /* g_print( "addrindex_remove_results/start\n" ); */
2794 /* Test for folder */
2795 if( folder
->folderType
!= ADDRFOLDER_QUERY_RESULTS
) return;
2796 /* g_print( "folder name ::%s::\n", ADDRITEM_NAME(folder) ); */
2797 adbase
= ( AddrBookBase
* ) ds
->rawDataSource
;
2798 if( adbase
== NULL
) return;
2800 /* Hide folder to prevent re-display */
2801 addritem_folder_set_hidden( folder
, TRUE
);
2803 if( ds
->type
== ADDR_IF_LDAP
) {
2808 qry
= ( LdapQuery
* ) folder
->folderData
;
2809 queryID
= ADDRQUERY_ID(qry
);
2810 /* g_print( "calling ldapquery_remove_results...queryID=%d\n", queryID ); */
2811 delFlag
= ldapquery_remove_results( qry
);
2813 ldapqry_free( qry
);
2815 /* g_print( "calling ldapquery_remove_results...done\n" ); */
2818 g_print( "delFlag IS-TRUE\n" );
2821 g_print( "delFlag IS-FALSE\n" );
2826 /* g_print( "addrindex_remove_results/end\n" ); */
2828 /* Delete query request */
2830 qrymgr_delete_request( queryID
);
2834 /* **********************************************************************
2835 * Address completion stuff.
2836 * ***********************************************************************
2839 static void addrindex_load_completion_load_persons(
2840 gint (*callBackFunc
) ( const gchar
*, const gchar
*,
2841 const gchar
*, const gchar
*, GList
* ),
2842 AddressDataSource
*ds
)
2844 GList
*listP
, *nodeP
;
2848 /* Read address book */
2849 if( addrindex_ds_get_modify_flag( ds
) ) {
2850 addrindex_ds_read_data( ds
);
2853 if( ! addrindex_ds_get_read_flag( ds
) ) {
2854 addrindex_ds_read_data( ds
);
2857 /* Get all groups */
2858 listP
= addrindex_ds_get_all_groups( ds
);
2861 ItemGroup
*group
= nodeP
->data
;
2862 GList
*emails
= NULL
;
2863 for (nodeM
= group
->listEMail
; nodeM
; nodeM
= g_list_next(nodeM
)) {
2864 ItemEMail
*email
= nodeM
->data
;
2866 emails
= g_list_append(emails
, email
);
2868 callBackFunc( ((AddrItemObject
*)group
)->name
, NULL
,
2869 NULL
, NULL
, emails
);
2870 nodeP
= g_list_next( nodeP
);
2873 /* Free up the list */
2874 g_list_free( listP
);
2875 /* Get all persons */
2876 listP
= addrindex_ds_get_all_persons( ds
);
2879 ItemPerson
*person
= nodeP
->data
;
2880 nodeM
= person
->listEMail
;
2882 /* Figure out name to use */
2883 sName
= ADDRITEM_NAME(person
);
2884 if( sName
== NULL
|| *sName
== '\0' ) {
2885 sName
= person
->nickName
;
2888 /* Process each E-Mail address */
2890 ItemEMail
*email
= nodeM
->data
;
2892 callBackFunc( sName
, email
->address
, person
->nickName
,
2893 ADDRITEM_NAME(email
), NULL
);
2895 nodeM
= g_list_next( nodeM
);
2897 nodeP
= g_list_next( nodeP
);
2900 /* Free up the list */
2901 g_list_free( listP
);
2905 * This function is used by the address completion function to load
2906 * addresses for all non-external address book interfaces.
2908 * \param callBackFunc Function to be called when an address is
2910 * \param folderpath Addressbook's Book/folder path to restrict to (if NULL or ""
2911 * or "Any", assume the whole addressbook
2912 * \return <i>TRUE</i> if data loaded, <i>FALSE</i> if address index not loaded.
2915 gboolean
addrindex_load_completion(
2916 gint (*callBackFunc
) ( const gchar
*, const gchar
*,
2917 const gchar
*, const gchar
*, GList
* ),
2920 GList
*nodeIf
, *nodeDS
;
2922 if( folderpath
!= NULL
) {
2923 AddressDataSource
*book
;
2926 /* split the folder path we've received, we'll try to match this path, subpath by
2927 subpath against the book/folder structure in order and restrict loading of
2928 addresses to that subpart (if matches). book/folder path must exist and
2929 folderpath must not be empty or NULL */
2931 if( ! addressbook_peek_folder_exists( folderpath
, &book
, &folder
) ) {
2932 g_warning("addrindex_load_completion: folder path '%s' doesn't exist", folderpath
);
2936 if( folder
!= NULL
) {
2943 debug_print("addrindex_load_completion: folder %p '%s'\n", folder
, folder
->obj
.name
);
2945 /* Load email addresses */
2946 items
= addritem_folder_get_person_list( folder
);
2947 for( ; items
!= NULL
; items
= g_list_next( items
) ) {
2948 person
= items
->data
;
2949 nodeM
= person
->listEMail
;
2951 /* Figure out name to use */
2952 sName
= ADDRITEM_NAME(person
);
2953 if( sName
== NULL
|| *sName
== '\0' ) {
2954 sName
= person
->nickName
;
2957 /* Process each E-Mail address */
2959 ItemEMail
*email
= nodeM
->data
;
2961 callBackFunc( sName
, email
->address
, person
->nickName
,
2962 ADDRITEM_NAME(email
), NULL
);
2964 nodeM
= g_list_next( nodeM
);
2967 /* Free up the list (but not the data inside the
2968 * individual list items) */
2969 g_list_free( items
);
2975 if( book
!= NULL
) {
2977 AddressBookFile
*abf
= book
->rawDataSource
;
2979 debug_print("addrindex_load_completion: book %p '%s'\n", book
, abf
?abf
->fileName
:"(null)");
2981 addrindex_load_completion_load_persons( callBackFunc
, book
);
2986 g_warning("addrindex_load_completion: book/folder path is valid but got no pointer");
2993 nodeIf
= addrindex_get_interface_list( _addressIndex_
);
2995 AddressInterface
*iface
= nodeIf
->data
;
2997 nodeIf
= g_list_next( nodeIf
);
2999 if( ! iface
->useInterface
|| iface
->externalQuery
)
3002 nodeDS
= iface
->listSource
;
3004 addrindex_load_completion_load_persons( callBackFunc
, nodeDS
->data
);
3005 nodeDS
= g_list_next( nodeDS
);
3014 * This function can be used to collect information about
3015 * addressbook entries that contain a specific attribute.
3017 * \param attr Name of attribute to look for
3018 * \param callBackFunc Function to be called when a matching attribute was found
3019 * \return <i>TRUE</i>
3021 gboolean
addrindex_load_person_attribute(
3023 gint (*callBackFunc
) ( ItemPerson
*, const gchar
* ) )
3025 AddressDataSource
*ds
;
3026 GList
*nodeIf
, *nodeDS
;
3027 GList
*listP
, *nodeP
;
3030 nodeIf
= addrindex_get_interface_list( _addressIndex_
);
3033 AddressInterface
*iface
= nodeIf
->data
;
3035 nodeIf
= g_list_next( nodeIf
);
3037 if( ! iface
->useInterface
|| iface
->externalQuery
)
3040 nodeDS
= iface
->listSource
;
3044 /* Read address book */
3045 if( addrindex_ds_get_modify_flag( ds
) ) {
3046 addrindex_ds_read_data( ds
);
3049 if( ! addrindex_ds_get_read_flag( ds
) ) {
3050 addrindex_ds_read_data( ds
);
3053 /* Check addressbook name */
3054 cur_bname
= addrindex_ds_get_name( ds
);
3056 /* Get all persons */
3057 listP
= addrindex_ds_get_all_persons( ds
);
3060 ItemPerson
*person
= nodeP
->data
;
3062 /* Return all ItemPerson's if attr is NULL */
3063 if( attr
== NULL
) {
3064 callBackFunc(person
, cur_bname
);
3067 /* Return ItemPerson's with specific attribute */
3069 nodeA
= person
->listAttrib
;
3070 /* Process each User Attribute */
3072 UserAttribute
*attrib
= nodeA
->data
;
3074 !strcmp( attrib
->name
,attr
) ) {
3075 callBackFunc(person
, cur_bname
);
3077 nodeA
= g_list_next( nodeA
);
3080 nodeP
= g_list_next( nodeP
);
3082 /* Free up the list */
3083 g_list_free( listP
);
3085 nodeDS
= g_list_next( nodeDS
);
3092 * This function can be used to collect information about
3093 * addressbook entries
3095 * \param callBackFunc Function to be called for each ItemPerson
3096 * \return <i>TRUE</i>
3098 gboolean
addrindex_load_person_ds( gint (*callBackFunc
)
3099 ( ItemPerson
*, AddressDataSource
* ) )
3101 AddressDataSource
*ds
;
3102 GList
*nodeIf
, *nodeDS
;
3103 GList
*listP
, *nodeP
;
3105 nodeIf
= addrindex_get_interface_list( _addressIndex_
);
3107 AddressInterface
*iface
= nodeIf
->data
;
3109 nodeIf
= g_list_next( nodeIf
);
3111 if( ! iface
->useInterface
|| iface
->externalQuery
)
3114 nodeDS
= iface
->listSource
;
3118 /* Read address book */
3119 if( addrindex_ds_get_modify_flag( ds
) ) {
3120 addrindex_ds_read_data( ds
);
3123 if( ! addrindex_ds_get_read_flag( ds
) ) {
3124 addrindex_ds_read_data( ds
);
3127 /* Get all persons */
3128 listP
= addrindex_ds_get_all_persons( ds
);
3131 ItemPerson
*person
= nodeP
->data
;
3133 callBackFunc(person
, ds
);
3134 nodeP
= g_list_next( nodeP
);
3136 /* Free up the list */
3137 g_list_free( listP
);
3139 nodeDS
= g_list_next( nodeDS
);
3145 gchar
*addrindex_get_picture_file(const gchar
*emailaddr
)
3147 AddressDataSource
*ds
;
3148 GList
*nodeIf
, *nodeDS
;
3149 GList
*listP
, *nodeP
;
3150 gboolean found
= FALSE
;
3151 gchar
*filename
= NULL
;
3152 gchar
*raw_addr
= NULL
;
3157 Xstrdup_a(raw_addr
, emailaddr
, return NULL
);
3158 extract_address(raw_addr
);
3160 nodeIf
= addrindex_get_interface_list( _addressIndex_
);
3162 AddressInterface
*iface
= nodeIf
->data
;
3164 nodeIf
= g_list_next( nodeIf
);
3166 if( ! iface
->useInterface
|| iface
->externalQuery
)
3169 nodeDS
= iface
->listSource
;
3170 while( nodeDS
&& !found
) {
3173 /* Read address book */
3174 if( addrindex_ds_get_modify_flag( ds
) ) {
3175 addrindex_ds_read_data( ds
);
3178 if( ! addrindex_ds_get_read_flag( ds
) ) {
3179 addrindex_ds_read_data( ds
);
3182 /* Get all persons */
3183 listP
= addrindex_ds_get_all_persons( ds
);
3185 while( nodeP
&& !found
) {
3187 ItemPerson
*person
= nodeP
->data
;
3188 nodeM
= person
->listEMail
;
3190 ItemEMail
*email
= nodeM
->data
;
3191 if (email
->address
&& !strcasecmp(raw_addr
, email
->address
)) {
3193 filename
= g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S
,
3194 ADDRBOOK_DIR
, G_DIR_SEPARATOR_S
,
3195 person
->picture
, ".png", NULL
);
3198 nodeM
= nodeM
->next
;
3200 nodeP
= g_list_next( nodeP
);
3202 /* Free up the list */
3203 g_list_free( listP
);
3205 nodeDS
= g_list_next( nodeDS
);
3213 GSList
*addrindex_get_password_protected_ldap_servers()
3215 AddressInterface
*iface
;
3216 AddressDataSource
*ds
;
3219 GSList
*list
= NULL
;
3223 nodeIf
= _addressIndex_
->searchOrder
;
3225 iface
= nodeIf
->data
;
3226 nodeIf
= g_list_next(nodeIf
);
3228 if (!iface
->useInterface
)
3230 if (!iface
->externalQuery
)
3232 if (iface
->type
!= ADDR_IF_LDAP
)
3235 nodeDS
= iface
->listSource
;
3238 nodeDS
= g_list_next(nodeDS
);
3239 server
= ds
->rawDataSource
;
3240 if (!server
->searchFlag
)
3243 ctl
= server
->control
;
3248 if (ctl
->bindDN
!= NULL
&& strlen(ctl
->bindDN
)) {
3249 list
= g_slist_append(list
, server
);
3256 #endif /* USE_LDAP */