2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 2001-2002 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 2 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, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 * General functions for accessing address index file.
35 #include "addrcache.h"
37 #include "addrindex.h"
40 #ifndef DEV_STANDALONE
55 #define TAG_ADDRESS_INDEX "addressbook"
57 #define TAG_IF_ADDRESS_BOOK "book_list"
58 #define TAG_IF_VCARD "vcard_list"
59 #define TAG_IF_JPILOT "jpilot_list"
60 #define TAG_IF_LDAP "ldap_list"
62 #define TAG_DS_ADDRESS_BOOK "book"
63 #define TAG_DS_VCARD "vcard"
64 #define TAG_DS_JPILOT "jpilot"
65 #define TAG_DS_LDAP "server"
67 /* XML Attribute names */
68 #define ATTAG_BOOK_NAME "name"
69 #define ATTAG_BOOK_FILE "file"
71 #define ATTAG_VCARD_NAME "name"
72 #define ATTAG_VCARD_FILE "file"
74 #define ATTAG_JPILOT_NAME "name"
75 #define ATTAG_JPILOT_FILE "file"
76 #define ATTAG_JPILOT_CUSTOM_1 "custom-1"
77 #define ATTAG_JPILOT_CUSTOM_2 "custom-2"
78 #define ATTAG_JPILOT_CUSTOM_3 "custom-3"
79 #define ATTAG_JPILOT_CUSTOM_4 "custom-4"
80 #define ATTAG_JPILOT_CUSTOM "custom-"
82 #define ATTAG_LDAP_NAME "name"
83 #define ATTAG_LDAP_HOST "host"
84 #define ATTAG_LDAP_PORT "port"
85 #define ATTAG_LDAP_BASE_DN "base-dn"
86 #define ATTAG_LDAP_BIND_DN "bind-dn"
87 #define ATTAG_LDAP_BIND_PASS "bind-pass"
88 #define ATTAG_LDAP_CRITERIA "criteria"
89 #define ATTAG_LDAP_MAX_ENTRY "max-entry"
90 #define ATTAG_LDAP_TIMEOUT "timeout"
94 N_("Personal address")
97 #define DISP_NEW_COMMON _("Common address")
98 #define DISP_NEW_PERSONAL _("Personal address")
100 /* Old address book */
101 #define TAG_IF_OLD_COMMON "common_address"
102 #define TAG_IF_OLD_PERSONAL "personal_address"
104 #define DISP_OLD_COMMON _("Common address")
105 #define DISP_OLD_PERSONAL _("Personal address")
107 typedef struct _AddressIfAttr AddressIfAttrib;
108 struct _AddressIfAttr {
114 * Build interface with default values.
116 static AddressInterface *addrindex_create_interface( gint type, gchar *name, gchar *tagIf, gchar *tagDS ) {
117 AddressInterface *iface = g_new0( AddressInterface, 1 );
118 ADDRITEM_TYPE(iface) = ITEMTYPE_INTERFACE;
119 ADDRITEM_ID(iface) = NULL;
120 ADDRITEM_NAME(iface) = g_strdup( name );
121 ADDRITEM_PARENT(iface) = NULL;
122 ADDRITEM_SUBTYPE(iface) = type;
124 iface->name = g_strdup( name );
125 iface->listTag = g_strdup( tagIf );
126 iface->itemTag = g_strdup( tagDS );
127 iface->legacyFlag = FALSE;
128 iface->haveLibrary = TRUE;
129 iface->useInterface = TRUE;
130 iface->readOnly = TRUE;
131 iface->getAccessFlag = NULL;
132 iface->getModifyFlag = NULL;
133 iface->getReadFlag = NULL;
134 iface->getStatusCode = NULL;
135 iface->getReadData = NULL;
136 iface->getRootFolder = NULL;
137 iface->getListFolder = NULL;
138 iface->getListPerson = NULL;
139 iface->getAllPersons = NULL;
140 iface->getAllGroups = NULL;
141 iface->getName = NULL;
142 iface->listSource = NULL;
147 * Build table of interfaces.
149 static void addrindex_build_if_list( AddressIndex *addrIndex ) {
150 AddressInterface *iface;
152 iface = addrindex_create_interface( ADDR_IF_BOOK, "Address Book", TAG_IF_ADDRESS_BOOK, TAG_DS_ADDRESS_BOOK );
153 iface->readOnly = FALSE;
154 iface->getModifyFlag = ( void * ) addrbook_get_modified;
155 iface->getAccessFlag = ( void * ) addrbook_get_accessed;
156 iface->getReadFlag = ( void * ) addrbook_get_read_flag;
157 iface->getStatusCode = ( void * ) addrbook_get_status;
158 iface->getReadData = ( void * ) addrbook_read_data;
159 iface->getRootFolder = ( void * ) addrbook_get_root_folder;
160 iface->getListFolder = ( void * ) addrbook_get_list_folder;
161 iface->getListPerson = ( void * ) addrbook_get_list_person;
162 iface->getAllPersons = ( void * ) addrbook_get_all_persons;
163 iface->getName = ( void * ) addrbook_get_name;
164 iface->setAccessFlag = ( void * ) addrbook_set_accessed;
165 addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface );
166 ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex);
168 iface = addrindex_create_interface( ADDR_IF_VCARD, "vCard", TAG_IF_VCARD, TAG_DS_VCARD );
169 iface->getModifyFlag = ( void * ) vcard_get_modified;
170 iface->getAccessFlag = ( void * ) vcard_get_accessed;
171 iface->getReadFlag = ( void * ) vcard_get_read_flag;
172 iface->getStatusCode = ( void * ) vcard_get_status;
173 iface->getReadData = ( void * ) vcard_read_data;
174 iface->getRootFolder = ( void * ) vcard_get_root_folder;
175 iface->getListFolder = ( void * ) vcard_get_list_folder;
176 iface->getListPerson = ( void * ) vcard_get_list_person;
177 iface->getAllPersons = ( void * ) vcard_get_all_persons;
178 iface->getName = ( void * ) vcard_get_name;
179 iface->setAccessFlag = ( void * ) vcard_set_accessed;
180 addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface );
181 ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex);
183 iface = addrindex_create_interface( ADDR_IF_JPILOT, "J-Pilot", TAG_IF_JPILOT, TAG_DS_JPILOT );
185 iface->haveLibrary = jpilot_test_pilot_lib();
186 iface->useInterface = iface->haveLibrary;
187 iface->getModifyFlag = ( void * ) jpilot_get_modified;
188 iface->getAccessFlag = ( void * ) jpilot_get_accessed;
189 iface->getReadFlag = ( void * ) jpilot_get_read_flag;
190 iface->getStatusCode = ( void * ) jpilot_get_status;
191 iface->getReadData = ( void * ) jpilot_read_data;
192 iface->getRootFolder = ( void * ) jpilot_get_root_folder;
193 iface->getListFolder = ( void * ) jpilot_get_list_folder;
194 iface->getListPerson = ( void * ) jpilot_get_list_person;
195 iface->getAllPersons = ( void * ) jpilot_get_all_persons;
196 iface->getName = ( void * ) jpilot_get_name;
197 iface->setAccessFlag = ( void * ) jpilot_set_accessed;
199 iface->useInterface = FALSE;
200 iface->haveLibrary = FALSE;
202 addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface );
203 ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex);
205 iface = addrindex_create_interface( ADDR_IF_LDAP, "LDAP", TAG_IF_LDAP, TAG_DS_LDAP );
207 iface->haveLibrary = syldap_test_ldap_lib();
208 iface->useInterface = iface->haveLibrary;
209 iface->getAccessFlag = ( void * ) syldap_get_accessed;
210 /* iface->getModifyFlag = ( void * ) syldap_get_modified; */
211 /* iface->getReadFlag = ( void * ) syldap_get_read_flag; */
212 iface->getStatusCode = ( void * ) syldap_get_status;
213 iface->getReadData = ( void * ) syldap_read_data;
214 iface->getRootFolder = ( void * ) syldap_get_root_folder;
215 iface->getListFolder = ( void * ) syldap_get_list_folder;
216 iface->getListPerson = ( void * ) syldap_get_list_person;
217 iface->getName = ( void * ) syldap_get_name;
218 iface->setAccessFlag = ( void * ) syldap_set_accessed;
220 iface->useInterface = FALSE;
221 iface->haveLibrary = FALSE;
223 addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface );
224 ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex);
226 /* Two old legacy data sources */
227 iface = addrindex_create_interface(
228 ADDR_IF_COMMON, "Old Address - common",
229 TAG_IF_OLD_COMMON, NULL );
230 iface->legacyFlag = TRUE;
231 addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface );
232 ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex);
234 iface = addrindex_create_interface(
235 ADDR_IF_COMMON, "Old Address - personal",
236 TAG_IF_OLD_PERSONAL, NULL );
237 iface->legacyFlag = TRUE;
238 addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface );
239 ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex);
244 * Free name-value pairs.
246 static void addrindex_free_attributes( GList *list ) {
249 AddressIfAttrib *nv = node->data;
250 g_free( nv->name ); nv->name = NULL;
251 g_free( nv->value ); nv->value = NULL;
254 node = g_list_next( node );
260 * Create new data source.
261 * Enter: ifType Interface type to create.
262 * Return: Initialized data source.
264 AddressDataSource *addrindex_create_datasource( AddressIfType ifType ) {
265 AddressDataSource *ds = g_new0( AddressDataSource, 1 );
267 ds = g_new0( AddressDataSource, 1 );
268 ADDRITEM_TYPE(ds) = ITEMTYPE_DATASOURCE;
269 ADDRITEM_ID(ds) = NULL;
270 ADDRITEM_NAME(ds) = NULL;
271 ADDRITEM_PARENT(ds) = NULL;
272 ADDRITEM_SUBTYPE(ds) = 0;
274 ds->rawDataSource = NULL;
275 ds->interface = NULL;
280 * Free up data source.
282 void addrindex_free_datasource( AddressDataSource *ds ) {
283 AddressInterface *iface;
285 g_return_if_fail( ds != NULL );
287 iface = ds->interface;
288 if( iface == NULL ) return;
289 if( ds->rawDataSource != NULL ) {
290 if( iface->useInterface ) {
291 if( iface->type == ADDR_IF_BOOK ) {
292 AddressBookFile *abf = ds->rawDataSource;
293 addrbook_free_book( abf );
295 else if( iface->type == ADDR_IF_VCARD ) {
296 VCardFile *vcf = ds->rawDataSource;
300 else if( iface->type == ADDR_IF_JPILOT ) {
301 JPilotFile *jpf = ds->rawDataSource;
306 else if( iface->type == ADDR_IF_LDAP ) {
307 SyldapServer *server = ds->rawDataSource;
308 syldap_free( server );
313 GList *list = ds->rawDataSource;
314 addrindex_free_attributes( list );
318 ADDRITEM_TYPE(ds) = ITEMTYPE_NONE;
319 ADDRITEM_ID(ds) = NULL;
320 ADDRITEM_NAME(ds) = NULL;
321 ADDRITEM_PARENT(ds) = NULL;
322 ADDRITEM_SUBTYPE(ds) = 0;
323 ds->type = ADDR_IF_NONE;
324 ds->interface = NULL;
325 ds->rawDataSource = NULL;
329 static void addrindex_free_all_datasources( AddressInterface *iface ) {
330 GList *node = iface->listSource;
332 AddressDataSource *ds = node->data;
333 addrindex_free_datasource( ds );
335 node = g_list_next( node );
339 static void addrindex_free_interface( AddressInterface *iface ) {
340 addrindex_free_all_datasources( iface );
342 g_free( ADDRITEM_ID(iface) );
343 g_free( ADDRITEM_NAME(iface) );
344 g_free( iface->name );
345 g_free( iface->listTag );
346 g_free( iface->itemTag );
348 ADDRITEM_TYPE(iface) = ITEMTYPE_NONE;
349 ADDRITEM_ID(iface) = NULL;
350 ADDRITEM_NAME(iface) = NULL;
351 ADDRITEM_PARENT(iface) = NULL;
352 ADDRITEM_SUBTYPE(iface) = 0;
353 iface->type = ADDR_IF_NONE;
355 iface->listTag = NULL;
356 iface->itemTag = NULL;
357 iface->legacyFlag = FALSE;
358 iface->useInterface = FALSE;
359 iface->haveLibrary = FALSE;
361 g_list_free( iface->listSource );
362 iface->listSource = NULL;
366 * Return cache ID for specified data source.
367 * Enter: addrIndex Address index.
369 * Return: ID or NULL if not found. This can be g_free() when done.
371 gchar *addrindex_get_cache_id( AddressIndex *addrIndex, AddressDataSource *ds ) {
372 gchar *cacheID = NULL;
373 AddrBookBase *adbase;
376 g_return_val_if_fail( addrIndex != NULL, NULL );
377 g_return_val_if_fail( ds != NULL, NULL );
379 adbase = ( AddrBookBase * ) ds->rawDataSource;
381 cache = adbase->addressCache;
383 cacheID = g_strdup( cache->cacheID );
391 * Return data source for specified cacheID.
392 * Enter: addrIndex Address index.
394 * Return: Data source, or NULL if not found.
396 AddressDataSource *addrindex_get_datasource( AddressIndex *addrIndex, const gchar *cacheID ) {
397 g_return_val_if_fail( addrIndex != NULL, NULL );
398 g_return_val_if_fail( cacheID != NULL, NULL );
399 return ( AddressDataSource * ) g_hash_table_lookup( addrIndex->hashCache, cacheID );
403 * Return cache for specified cacheID.
404 * Enter: addrIndex Address index.
406 * Return: Address cache, or NULL if not found.
408 AddressCache *addrindex_get_cache( AddressIndex *addrIndex, const gchar *cacheID ) {
409 AddressDataSource *ds;
410 AddrBookBase *adbase;
413 g_return_val_if_fail( addrIndex != NULL, NULL );
414 g_return_val_if_fail( cacheID != NULL, NULL );
417 ds = addrindex_get_datasource( addrIndex, cacheID );
419 adbase = ( AddrBookBase * ) ds->rawDataSource;
420 cache = adbase->addressCache;
426 * Add data source into hash.
427 * Enter: addrIndex Address index.
430 static addrindex_hash_add_cache( AddressIndex *addrIndex, AddressDataSource *ds ) {
433 cacheID = addrindex_get_cache_id( addrIndex, ds );
435 g_hash_table_insert( addrIndex->hashCache, cacheID, ds );
440 * Free hash table callback function.
442 static gboolean addrindex_free_cache_cb( gpointer key, gpointer value, gpointer data ) {
443 printf( "free cache db: %s\n", key );
451 * Free hash table of address cache items.
453 static void addrindex_free_cache_hash( GHashTable *table ) {
454 g_hash_table_freeze( table );
455 g_hash_table_foreach_remove( table, addrindex_free_cache_cb, NULL );
456 g_hash_table_thaw( table );
457 g_hash_table_destroy( table );
461 * Remove address cache for specified data source from internal hashtable.
463 static void addrindex_hash_remove_cache( AddressIndex *addrIndex, AddressDataSource *ds ) {
466 cacheID = addrindex_get_cache_id( addrIndex, ds );
468 g_hash_table_remove( addrIndex->hashCache, cacheID );
477 AddressIndex *addrindex_create_index( void ) {
478 AddressIndex *addrIndex = g_new0( AddressIndex, 1 );
480 ADDRITEM_TYPE(addrIndex) = ITEMTYPE_INDEX;
481 ADDRITEM_ID(addrIndex) = NULL;
482 ADDRITEM_NAME(addrIndex) = g_strdup( "Address Index" );
483 ADDRITEM_PARENT(addrIndex) = NULL;
484 ADDRITEM_SUBTYPE(addrIndex) = 0;
485 addrIndex->filePath = NULL;
486 addrIndex->fileName = NULL;
487 addrIndex->retVal = MGU_SUCCESS;
488 addrIndex->needsConversion = FALSE;
489 addrIndex->wasConverted = FALSE;
490 addrIndex->conversionError = FALSE;
491 addrIndex->interfaceList = NULL;
492 addrIndex->lastType = ADDR_IF_NONE;
493 addrIndex->dirtyFlag = FALSE;
494 addrIndex->hashCache = g_hash_table_new( g_str_hash, g_str_equal );
495 addrindex_build_if_list( addrIndex );
500 * Specify file to be used.
502 void addrindex_set_file_path( AddressIndex *addrIndex, const gchar *value ) {
503 g_return_if_fail( addrIndex != NULL );
504 addrIndex->filePath = mgu_replace_string( addrIndex->filePath, value );
506 void addrindex_set_file_name( AddressIndex *addrIndex, const gchar *value ) {
507 g_return_if_fail( addrIndex != NULL );
508 addrIndex->fileName = mgu_replace_string( addrIndex->fileName, value );
510 void addrindex_set_dirty( AddressIndex *addrIndex, const gboolean value ) {
511 g_return_if_fail( addrIndex != NULL );
512 addrIndex->dirtyFlag = value;
516 * Return list of interfaces.
518 GList *addrindex_get_interface_list( AddressIndex *addrIndex ) {
519 g_return_val_if_fail( addrIndex != NULL, NULL );
520 return addrIndex->interfaceList;
526 void addrindex_free_index( AddressIndex *addrIndex ) {
529 g_return_if_fail( addrIndex != NULL );
531 g_free( ADDRITEM_ID(addrIndex) );
532 g_free( ADDRITEM_NAME(addrIndex) );
533 g_free( addrIndex->filePath );
534 g_free( addrIndex->fileName );
535 ADDRITEM_TYPE(addrIndex) = ITEMTYPE_NONE;
536 ADDRITEM_ID(addrIndex) = NULL;
537 ADDRITEM_NAME(addrIndex) = NULL;
538 ADDRITEM_PARENT(addrIndex) = NULL;
539 ADDRITEM_SUBTYPE(addrIndex) = 0;
540 addrIndex->filePath = NULL;
541 addrIndex->fileName = NULL;
542 addrIndex->retVal = MGU_SUCCESS;
543 addrIndex->needsConversion = FALSE;
544 addrIndex->wasConverted = FALSE;
545 addrIndex->conversionError = FALSE;
546 addrIndex->lastType = ADDR_IF_NONE;
547 addrIndex->dirtyFlag = FALSE;
548 node = addrIndex->interfaceList;
550 AddressInterface *iface = node->data;
551 addrindex_free_interface( iface );
552 node = g_list_next( node );
554 g_list_free( addrIndex->interfaceList );
555 addrIndex->interfaceList = NULL;
556 addrindex_free_cache_hash( addrIndex->hashCache );
557 addrIndex->hashCache = NULL;
562 * Print address index.
564 void addrindex_print_index( AddressIndex *addrIndex, FILE *stream ) {
565 g_return_if_fail( addrIndex != NULL );
566 fprintf( stream, "AddressIndex:\n" );
567 fprintf( stream, "\tfile path: '%s'\n", addrIndex->filePath );
568 fprintf( stream, "\tfile name: '%s'\n", addrIndex->fileName );
569 fprintf( stream, "\t status: %d : '%s'\n", addrIndex->retVal, mgu_error2string( addrIndex->retVal ) );
570 fprintf( stream, "\tconverted: '%s'\n", addrIndex->wasConverted ? "yes" : "no" );
571 fprintf( stream, "\tcvt error: '%s'\n", addrIndex->conversionError ? "yes" : "no" );
572 fprintf( stream, "\t---\n" );
576 * Retrieve specified interface from index.
578 AddressInterface *addrindex_get_interface(
579 AddressIndex *addrIndex, AddressIfType ifType )
581 AddressInterface *retVal = NULL;
584 g_return_val_if_fail( addrIndex != NULL, NULL );
586 node = addrIndex->interfaceList;
588 AddressInterface *iface = node->data;
589 node = g_list_next( node );
590 if( iface->type == ifType ) {
599 * Add data source to index.
600 * Enter: addrIndex Address index object.
601 * ifType Interface type to add.
602 * dataSource Actual data source to add.
603 * Return: TRUE if data source was added.
604 * Note: The raw data object (for example, AddressBookFile or VCardFile object) should be
605 * supplied as the dataSource argument.
607 AddressDataSource *addrindex_index_add_datasource(
608 AddressIndex *addrIndex, AddressIfType ifType, gpointer dataSource )
610 AddressInterface *iface;
611 AddressDataSource *ds = NULL;
613 g_return_val_if_fail( addrIndex != NULL, NULL );
614 g_return_val_if_fail( dataSource != NULL, NULL );
616 iface = addrindex_get_interface( addrIndex, ifType );
618 ds = addrindex_create_datasource( ifType );
619 ADDRITEM_PARENT(ds) = ADDRITEM_OBJECT(iface);
621 ds->rawDataSource = dataSource;
622 ds->interface = iface;
623 iface->listSource = g_list_append( iface->listSource, ds );
624 addrIndex->dirtyFlag = TRUE;
626 addrindex_hash_add_cache( addrIndex, ds );
632 * Remove data source from index.
633 * Enter: addrIndex Address index object.
634 * dataSource Data source to remove.
635 * Return: Data source if removed, or NULL if data source was not found in
636 * index. Note the this object must still be freed.
638 AddressDataSource *addrindex_index_remove_datasource(
639 AddressIndex *addrIndex, AddressDataSource *dataSource )
641 AddressDataSource *retVal = FALSE;
642 AddressInterface *iface;
644 g_return_val_if_fail( addrIndex != NULL, NULL );
645 g_return_val_if_fail( dataSource != NULL, NULL );
647 iface = addrindex_get_interface( addrIndex, dataSource->type );
649 iface->listSource = g_list_remove( iface->listSource, dataSource );
650 addrIndex->dirtyFlag = TRUE;
651 dataSource->interface = NULL;
653 /* Remove cache from hash table */
654 addrindex_hash_remove_cache( addrIndex, dataSource );
661 static AddressInterface *addrindex_tag_get_interface(
662 AddressIndex *addrIndex, gchar *tag, AddressIfType ifType )
664 AddressInterface *retVal = NULL;
665 GList *node = addrIndex->interfaceList;
668 AddressInterface *iface = node->data;
669 node = g_list_next( node );
671 if( strcmp( iface->listTag, tag ) == 0 ) {
677 if( iface->type == ifType ) {
686 static AddressInterface *addrindex_tag_get_datasource(
687 AddressIndex *addrIndex, AddressIfType ifType, gchar *tag )
689 AddressInterface *retVal = NULL;
690 GList *node = addrIndex->interfaceList;
693 AddressInterface *iface = node->data;
694 node = g_list_next( node );
695 if( iface->type == ifType && iface->itemTag ) {
696 if( strcmp( iface->itemTag, tag ) == 0 ) {
705 /* **********************************************************************
706 * Interface XML parsing functions.
707 * ***********************************************************************
710 static void show_attribs( GList *attr ) {
712 gchar *name = ((XMLAttr *)attr->data)->name;
713 gchar *value = ((XMLAttr *)attr->data)->value;
714 printf( "\tattr value : %s :%s:\n", name, value );
715 attr = g_list_next( attr );
721 static void addrindex_write_elem_s( FILE *fp, gint lvl, gchar *name ) {
723 for( i = 0; i < lvl; i++ ) fputs( " ", fp );
728 static void addrindex_write_elem_e( FILE *fp, gint lvl, gchar *name ) {
730 for( i = 0; i < lvl; i++ ) fputs( " ", fp );
736 static void addrindex_write_attr( FILE *fp, gchar *name, gchar *value ) {
740 xml_file_put_escape_str( fp, value );
745 * Return list of name-value pairs.
747 static GList *addrindex_read_attributes( XMLFile *file ) {
754 attr = xml_get_current_tag_attr( file );
756 name = ((XMLAttr *)attr->data)->name;
757 value = ((XMLAttr *)attr->data)->value;
758 nv = g_new0( AddressIfAttrib, 1 );
759 nv->name = g_strdup( name );
760 nv->value = g_strdup( value );
761 list = g_list_append( list, nv );
762 attr = g_list_next( attr );
768 * Output name-value pairs.
770 static void addrindex_write_attributes( FILE *fp, gchar *tag, GList *list, gint lvl ) {
774 addrindex_write_elem_s( fp, lvl, tag );
778 addrindex_write_attr( fp, nv->name, nv->value );
779 node = g_list_next( node );
786 static void addrindex_print_attributes( GList *list, FILE *stream ) {
789 AddressIfAttrib *nv = node->data;
790 fprintf( stream, "%s : %s\n", nv->name, nv->value );
791 node = g_list_next( node );
796 static AddressDataSource *addrindex_parse_book( XMLFile *file ) {
797 AddressDataSource *ds;
798 AddressBookFile *abf;
801 ds = addrindex_create_datasource( ADDR_IF_BOOK );
802 abf = addrbook_create_book();
803 attr = xml_get_current_tag_attr( file );
805 gchar *name = ((XMLAttr *)attr->data)->name;
806 gchar *value = ((XMLAttr *)attr->data)->value;
807 if( strcmp( name, ATTAG_BOOK_NAME ) == 0 ) {
808 addrbook_set_name( abf, value );
810 else if( strcmp( name, ATTAG_BOOK_FILE ) == 0) {
811 addrbook_set_file( abf, value );
813 attr = g_list_next( attr );
815 ds->rawDataSource = abf;
819 static void addrindex_write_book( FILE *fp, AddressDataSource *ds, gint lvl ) {
820 AddressBookFile *abf = ds->rawDataSource;
822 addrindex_write_elem_s( fp, lvl, TAG_DS_ADDRESS_BOOK );
823 addrindex_write_attr( fp, ATTAG_BOOK_NAME, addrbook_get_name( abf ) );
824 addrindex_write_attr( fp, ATTAG_BOOK_FILE, abf->fileName );
825 fputs( " />\n", fp );
829 static AddressDataSource *addrindex_parse_vcard( XMLFile *file ) {
830 AddressDataSource *ds;
834 ds = addrindex_create_datasource( ADDR_IF_VCARD );
835 vcf = vcard_create();
836 attr = xml_get_current_tag_attr( file );
838 gchar *name = ((XMLAttr *)attr->data)->name;
839 gchar *value = ((XMLAttr *)attr->data)->value;
840 if( strcmp( name, ATTAG_VCARD_NAME ) == 0 ) {
841 vcard_set_name( vcf, value );
843 else if( strcmp( name, ATTAG_VCARD_FILE ) == 0) {
844 vcard_set_file( vcf, value );
846 attr = g_list_next( attr );
848 ds->rawDataSource = vcf;
852 static void addrindex_write_vcard( FILE *fp, AddressDataSource *ds, gint lvl ) {
853 VCardFile *vcf = ds->rawDataSource;
855 addrindex_write_elem_s( fp, lvl, TAG_DS_VCARD );
856 addrindex_write_attr( fp, ATTAG_VCARD_NAME, vcard_get_name( vcf ) );
857 addrindex_write_attr( fp, ATTAG_VCARD_FILE, vcf->path );
858 fputs( " />\n", fp );
863 static AddressDataSource *addrindex_parse_jpilot( XMLFile *file ) {
864 AddressDataSource *ds;
868 ds = addrindex_create_datasource( ADDR_IF_JPILOT );
869 jpf = jpilot_create();
870 attr = xml_get_current_tag_attr( file );
872 gchar *name = ((XMLAttr *)attr->data)->name;
873 gchar *value = ((XMLAttr *)attr->data)->value;
874 if( strcmp( name, ATTAG_JPILOT_NAME ) == 0 ) {
875 jpilot_set_name( jpf, value );
877 else if( strcmp( name, ATTAG_JPILOT_FILE ) == 0 ) {
878 jpilot_set_file( jpf, value );
880 else if( strcmp( name, ATTAG_JPILOT_CUSTOM_1 ) == 0 ) {
881 jpilot_add_custom_label( jpf, value );
883 else if( strcmp( name, ATTAG_JPILOT_CUSTOM_2 ) == 0 ) {
884 jpilot_add_custom_label( jpf, value );
886 else if( strcmp( name, ATTAG_JPILOT_CUSTOM_3 ) == 0 ) {
887 jpilot_add_custom_label( jpf, value );
889 else if( strcmp( name, ATTAG_JPILOT_CUSTOM_4 ) == 0 ) {
890 jpilot_add_custom_label( jpf, value );
892 attr = g_list_next( attr );
894 ds->rawDataSource = jpf;
898 static void addrindex_write_jpilot( FILE *fp,AddressDataSource *ds, gint lvl ) {
899 JPilotFile *jpf = ds->rawDataSource;
903 GList *customLbl = jpilot_get_custom_labels( jpf );
904 addrindex_write_elem_s( fp, lvl, TAG_DS_JPILOT );
905 addrindex_write_attr( fp, ATTAG_JPILOT_NAME, jpilot_get_name( jpf ) );
906 addrindex_write_attr( fp, ATTAG_JPILOT_FILE, jpf->path );
911 sprintf( name, "%s%d", ATTAG_JPILOT_CUSTOM, ind );
912 addrindex_write_attr( fp, name, node->data );
914 node = g_list_next( node );
916 fputs( " />\n", fp );
920 /* Just read/write name-value pairs (preserve data found in file) */
921 static AddressDataSource *addrindex_parse_jpilot( XMLFile *file ) {
922 AddressDataSource *ds;
924 ds = addrindex_create_datasource( ADDR_IF_JPILOT );
925 ds->rawDataSource = addrindex_read_attributes( file );
929 static void addrindex_write_jpilot( FILE *fp, AddressDataSource *ds, gint lvl ) {
930 GList *list = ds->rawDataSource;
932 addrindex_write_attributes( fp, TAG_DS_JPILOT, list, lvl );
938 static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
939 AddressDataSource *ds;
940 SyldapServer *server;
943 ds = addrindex_create_datasource( ADDR_IF_LDAP );
944 server = syldap_create();
945 attr = xml_get_current_tag_attr( file );
947 gchar *name = ((XMLAttr *)attr->data)->name;
948 gchar *value = ((XMLAttr *)attr->data)->value;
949 gint ivalue = atoi( value );
950 if( strcmp( name, ATTAG_LDAP_NAME ) == 0 ) {
951 syldap_set_name( server, value );
953 else if( strcmp( name, ATTAG_LDAP_HOST ) == 0 ) {
954 syldap_set_host( server, value );
956 else if( strcmp( name, ATTAG_LDAP_PORT ) == 0 ) {
957 syldap_set_port( server, ivalue );
959 else if( strcmp( name, ATTAG_LDAP_BASE_DN ) == 0 ) {
960 syldap_set_base_dn( server, value );
962 else if( strcmp( name, ATTAG_LDAP_BIND_DN ) == 0 ) {
963 syldap_set_bind_dn( server, value );
965 else if( strcmp( name, ATTAG_LDAP_BIND_PASS ) == 0 ) {
966 syldap_set_bind_password( server, value );
968 else if( strcmp( name, ATTAG_LDAP_CRITERIA ) == 0 ) {
969 syldap_set_search_criteria( server, value );
971 else if( strcmp( name, ATTAG_LDAP_MAX_ENTRY ) == 0 ) {
972 syldap_set_max_entries( server, ivalue );
974 else if( strcmp( name, ATTAG_LDAP_TIMEOUT ) == 0 ) {
975 syldap_set_timeout( server, ivalue );
977 attr = g_list_next( attr );
980 ds->rawDataSource = server;
984 static void addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) {
985 SyldapServer *server = ds->rawDataSource;
989 addrindex_write_elem_s( fp, lvl, TAG_DS_LDAP );
990 addrindex_write_attr( fp, ATTAG_LDAP_NAME, syldap_get_name( server ) );
991 addrindex_write_attr( fp, ATTAG_LDAP_HOST, server->hostName );
993 sprintf( value, "%d", server->port );
994 addrindex_write_attr( fp, ATTAG_LDAP_PORT, value );
996 addrindex_write_attr( fp, ATTAG_LDAP_BASE_DN, server->baseDN );
997 addrindex_write_attr( fp, ATTAG_LDAP_BIND_DN, server->bindDN );
998 addrindex_write_attr( fp, ATTAG_LDAP_BIND_PASS, server->bindPass );
999 addrindex_write_attr( fp, ATTAG_LDAP_CRITERIA, server->searchCriteria );
1001 sprintf( value, "%d", server->maxEntries );
1002 addrindex_write_attr( fp, ATTAG_LDAP_MAX_ENTRY, value );
1003 sprintf( value, "%d", server->timeOut );
1004 addrindex_write_attr( fp, ATTAG_LDAP_TIMEOUT, value );
1010 /* Just read/write name-value pairs (preserve data found in file) */
1011 static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
1012 AddressDataSource *ds;
1014 ds = addrindex_create_datasource( ADDR_IF_LDAP );
1015 ds->rawDataSource = addrindex_read_attributes( file );
1019 static void addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) {
1020 GList *list = ds->rawDataSource;
1022 addrindex_write_attributes( fp, TAG_DS_LDAP, list, lvl );
1027 /* **********************************************************************
1028 * Address index I/O functions.
1029 * ***********************************************************************
1031 static void addrindex_read_index( AddressIndex *addrIndex, XMLFile *file ) {
1034 AddressInterface *iface = NULL, *dsIFace = NULL;
1035 AddressDataSource *ds;
1038 prev_level = file->level;
1039 xml_parse_next_tag( file );
1040 if( file->level < prev_level ) return;
1042 xtag = xml_get_current_tag( file );
1044 iface = addrindex_tag_get_interface( addrIndex, xtag->tag, ADDR_IF_NONE );
1046 addrIndex->lastType = iface->type;
1047 if( iface->legacyFlag ) addrIndex->needsConversion = TRUE;
1050 dsIFace = addrindex_tag_get_datasource(
1051 addrIndex, addrIndex->lastType, xtag->tag );
1053 /* Add data source to list */
1055 if( addrIndex->lastType == ADDR_IF_BOOK ) {
1056 ds = addrindex_parse_book( file );
1057 if( ds->rawDataSource ) {
1058 addrbook_set_path( ds->rawDataSource,
1059 addrIndex->filePath );
1062 else if( addrIndex->lastType == ADDR_IF_VCARD ) {
1063 ds = addrindex_parse_vcard( file );
1065 else if( addrIndex->lastType == ADDR_IF_JPILOT ) {
1066 ds = addrindex_parse_jpilot( file );
1068 else if( addrIndex->lastType == ADDR_IF_LDAP ) {
1069 ds = addrindex_parse_ldap( file );
1072 ds->interface = dsIFace;
1073 addrindex_hash_add_cache( addrIndex, ds );
1074 dsIFace->listSource =
1075 g_list_append( dsIFace->listSource, ds );
1079 addrindex_read_index( addrIndex, file );
1083 static gint addrindex_read_file( AddressIndex *addrIndex ) {
1084 XMLFile *file = NULL;
1085 gchar *fileSpec = NULL;
1087 g_return_val_if_fail( addrIndex != NULL, -1 );
1089 fileSpec = g_strconcat( addrIndex->filePath, G_DIR_SEPARATOR_S, addrIndex->fileName, NULL );
1090 addrIndex->retVal = MGU_NO_FILE;
1091 file = xml_open_file( fileSpec );
1094 if( file == NULL ) {
1095 /* fprintf( stdout, " file '%s' does not exist.\n", addrIndex->fileName ); */
1096 return addrIndex->retVal;
1099 addrIndex->retVal = MGU_BAD_FORMAT;
1100 if( xml_get_dtd( file ) == 0 ) {
1101 if( xml_parse_next_tag( file ) == 0 ) {
1102 if( xml_compare_tag( file, TAG_ADDRESS_INDEX ) ) {
1103 addrindex_read_index( addrIndex, file );
1104 addrIndex->retVal = MGU_SUCCESS;
1108 xml_close_file( file );
1110 return addrIndex->retVal;
1113 static void addrindex_write_index( AddressIndex *addrIndex, FILE *fp ) {
1114 GList *nodeIF, *nodeDS;
1116 gint lvlItem = 1 + lvlList;
1118 nodeIF = addrIndex->interfaceList;
1120 AddressInterface *iface = nodeIF->data;
1121 if( ! iface->legacyFlag ) {
1122 nodeDS = iface->listSource;
1123 addrindex_write_elem_s( fp, lvlList, iface->listTag );
1126 AddressDataSource *ds = nodeDS->data;
1128 if( iface->type == ADDR_IF_BOOK ) {
1129 addrindex_write_book( fp, ds, lvlItem );
1131 if( iface->type == ADDR_IF_VCARD ) {
1132 addrindex_write_vcard( fp, ds, lvlItem );
1134 if( iface->type == ADDR_IF_JPILOT ) {
1135 addrindex_write_jpilot( fp, ds, lvlItem );
1137 if( iface->type == ADDR_IF_LDAP ) {
1138 addrindex_write_ldap( fp, ds, lvlItem );
1141 nodeDS = g_list_next( nodeDS );
1143 addrindex_write_elem_e( fp, lvlList, iface->listTag );
1145 nodeIF = g_list_next( nodeIF );
1150 * Write data to specified file.
1151 * Enter: addrIndex Address index object.
1152 * newFile New file name.
1153 * return: Status code, from addrIndex->retVal.
1154 * Note: File will be created in directory specified by addrIndex.
1156 gint addrindex_write_to( AddressIndex *addrIndex, const gchar *newFile ) {
1159 #ifndef DEV_STANDALONE
1163 g_return_val_if_fail( addrIndex != NULL, -1 );
1165 fileSpec = g_strconcat( addrIndex->filePath, G_DIR_SEPARATOR_S, newFile, NULL );
1166 addrIndex->retVal = MGU_OPEN_FILE;
1167 #ifdef DEV_STANDALONE
1168 fp = fopen( fileSpec, "w" );
1171 fputs( "<?xml version=\"1.0\" ?>\n", fp );
1173 pfile = prefs_write_open( fileSpec );
1177 fprintf( fp, "<?xml version=\"1.0\" encoding=\"%s\" ?>\n",
1178 conv_get_current_charset_str() );
1180 addrindex_write_elem_s( fp, 0, TAG_ADDRESS_INDEX );
1183 addrindex_write_index( addrIndex, fp );
1184 addrindex_write_elem_e( fp, 0, TAG_ADDRESS_INDEX );
1186 addrIndex->retVal = MGU_SUCCESS;
1187 #ifdef DEV_STANDALONE
1190 if( prefs_write_close( pfile ) < 0 ) {
1191 addrIndex->retVal = MGU_ERROR_WRITE;
1197 return addrIndex->retVal;
1201 * Save address index data to original file.
1202 * return: Status code, from addrIndex->retVal.
1204 gint addrindex_save_data( AddressIndex *addrIndex ) {
1205 g_return_val_if_fail( addrIndex != NULL, -1 );
1207 addrIndex->retVal = MGU_NO_FILE;
1208 if( addrIndex->fileName == NULL || *addrIndex->fileName == '\0' ) return addrIndex->retVal;
1209 if( addrIndex->filePath == NULL || *addrIndex->filePath == '\0' ) return addrIndex->retVal;
1211 addrindex_write_to( addrIndex, addrIndex->fileName );
1212 if( addrIndex->retVal == MGU_SUCCESS ) {
1213 addrIndex->dirtyFlag = FALSE;
1215 return addrIndex->retVal;
1219 * Save all address book files which may have changed.
1220 * Return: Status code, set if there was a problem saving data.
1222 gint addrindex_save_all_books( AddressIndex *addrIndex ) {
1223 gint retVal = MGU_SUCCESS;
1224 GList *nodeIf, *nodeDS;
1226 nodeIf = addrIndex->interfaceList;
1228 AddressInterface *iface = nodeIf->data;
1229 if( iface->type == ADDR_IF_BOOK ) {
1230 nodeDS = iface->listSource;
1232 AddressDataSource *ds = nodeDS->data;
1233 AddressBookFile *abf = ds->rawDataSource;
1234 if( addrbook_get_dirty( abf ) ) {
1235 if( abf->readFlag ) {
1236 addrbook_save_data( abf );
1237 if( abf->retVal != MGU_SUCCESS ) {
1238 retVal = abf->retVal;
1242 nodeDS = g_list_next( nodeDS );
1246 nodeIf = g_list_next( nodeIf );
1252 /* **********************************************************************
1253 * Address book conversion to new format.
1254 * ***********************************************************************
1257 #define ELTAG_IF_OLD_FOLDER "folder"
1258 #define ELTAG_IF_OLD_GROUP "group"
1259 #define ELTAG_IF_OLD_ITEM "item"
1260 #define ELTAG_IF_OLD_NAME "name"
1261 #define ELTAG_IF_OLD_ADDRESS "address"
1262 #define ELTAG_IF_OLD_REMARKS "remarks"
1263 #define ATTAG_IF_OLD_NAME "name"
1265 #define TEMPNODE_ROOT 0
1266 #define TEMPNODE_FOLDER 1
1267 #define TEMPNODE_GROUP 2
1268 #define TEMPNODE_ADDRESS 3
1270 typedef struct _AddressCvt_Node AddressCvtNode;
1271 struct _AddressCvt_Node {
1280 * Parse current address item.
1282 static AddressCvtNode *addrindex_parse_item( XMLFile *file ) {
1287 nn = g_new0( AddressCvtNode, 1 );
1288 nn->type = TEMPNODE_ADDRESS;
1291 level = file->level;
1294 xml_parse_next_tag(file);
1295 if (file->level < level) return nn;
1297 element = xml_get_element( file );
1298 if( xml_compare_tag( file, ELTAG_IF_OLD_NAME ) ) {
1299 nn->name = g_strdup( element );
1301 if( xml_compare_tag( file, ELTAG_IF_OLD_ADDRESS ) ) {
1302 nn->address = g_strdup( element );
1304 if( xml_compare_tag( file, ELTAG_IF_OLD_REMARKS ) ) {
1305 nn->remarks = g_strdup( element );
1307 xml_parse_next_tag(file);
1312 * Create a temporary node below specified node.
1314 static AddressCvtNode *addrindex_add_object( AddressCvtNode *node, gint type, gchar *name, gchar *addr, char *rem ) {
1316 nn = g_new0( AddressCvtNode, 1 );
1318 nn->name = g_strdup( name );
1319 nn->remarks = g_strdup( rem );
1320 node->list = g_list_append( node->list, nn );
1325 * Process current temporary node.
1327 static void addrindex_add_obj( XMLFile *file, AddressCvtNode *node ) {
1330 AddressCvtNode *newNode = NULL;
1335 prev_level = file->level;
1336 xml_parse_next_tag( file );
1337 if (file->level < prev_level) return;
1341 if( xml_compare_tag( file, ELTAG_IF_OLD_GROUP ) ) {
1342 attr = xml_get_current_tag_attr(file);
1344 name = ((XMLAttr *)attr->data)->name;
1345 if( strcmp( name, ATTAG_IF_OLD_NAME ) == 0 ) {
1346 value = ((XMLAttr *)attr->data)->value;
1349 newNode = addrindex_add_object( node, TEMPNODE_GROUP, value, "", "" );
1350 addrindex_add_obj( file, newNode );
1353 else if( xml_compare_tag( file, ELTAG_IF_OLD_FOLDER ) ) {
1354 attr = xml_get_current_tag_attr(file);
1356 name = ((XMLAttr *)attr->data)->name;
1357 if( strcmp( name, ATTAG_IF_OLD_NAME ) == 0 ) {
1358 value = ((XMLAttr *)attr->data)->value;
1361 newNode = addrindex_add_object( node, TEMPNODE_FOLDER, value, "", "" );
1362 addrindex_add_obj( file, newNode );
1364 else if( xml_compare_tag( file, ELTAG_IF_OLD_ITEM ) ) {
1365 newNode = addrindex_parse_item( file );
1366 node->list = g_list_append( node->list, newNode );
1369 /* printf( "invalid: !!! \n" ); */
1370 attr = xml_get_current_tag_attr( file );
1376 * Consume all nodes below current tag.
1378 static void addrindex_consume_tree( XMLFile *file ) {
1385 prev_level = file->level;
1386 xml_parse_next_tag( file );
1387 if (file->level < prev_level) return;
1389 xtag = xml_get_current_tag( file );
1390 /* printf( "tag : %s\n", xtag->tag ); */
1391 element = xml_get_element( file );
1392 attr = xml_get_current_tag_attr( file );
1393 /* show_attribs( attr ); */
1394 /* printf( "\ttag value : %s :\n", element ); */
1395 addrindex_consume_tree( file );
1400 * Print temporary tree.
1402 static void addrindex_print_node( AddressCvtNode *node, FILE *stream ) {
1405 fprintf( stream, "Node:\ttype :%d:\n", node->type );
1406 fprintf( stream, "\tname :%s:\n", node->name );
1407 fprintf( stream, "\taddr :%s:\n", node->address );
1408 fprintf( stream, "\trems :%s:\n", node->remarks );
1410 fprintf( stream, "\t--list----\n" );
1414 AddressCvtNode *lNode = list->data;
1415 list = g_list_next( list );
1416 addrindex_print_node( lNode, stream );
1418 fprintf( stream, "\t==list-%d==\n", node->type );
1422 * Free up temporary tree.
1424 static void addrindex_free_node( AddressCvtNode *node ) {
1425 GList *list = node->list;
1428 AddressCvtNode *lNode = list->data;
1429 list = g_list_next( list );
1430 addrindex_free_node( lNode );
1432 node->type = TEMPNODE_ROOT;
1433 g_free( node->name );
1434 g_free( node->address );
1435 g_free( node->remarks );
1436 g_list_free( node->list );
1441 * Process address book for specified node.
1443 static void addrindex_process_node(
1444 AddressBookFile *abf, AddressCvtNode *node, ItemFolder *parent,
1445 ItemGroup *parentGrp, ItemFolder *folderGrp )
1448 ItemFolder *itemFolder = NULL;
1449 ItemGroup *itemGParent = parentGrp;
1450 ItemFolder *itemGFolder = folderGrp;
1451 AddressCache *cache = abf->addressCache;
1453 if( node->type == TEMPNODE_ROOT ) {
1454 itemFolder = parent;
1456 else if( node->type == TEMPNODE_FOLDER ) {
1457 itemFolder = addritem_create_item_folder();
1458 addritem_folder_set_name( itemFolder, node->name );
1459 addrcache_id_folder( cache, itemFolder );
1460 addrcache_folder_add_folder( cache, parent, itemFolder );
1463 else if( node->type == TEMPNODE_GROUP ) {
1464 ItemGroup *itemGroup;
1467 /* Create a folder for group */
1468 fName = g_strdup_printf( "Cvt - %s", node->name );
1469 itemGFolder = addritem_create_item_folder();
1470 addritem_folder_set_name( itemGFolder, fName );
1471 addrcache_id_folder( cache, itemGFolder );
1472 addrcache_folder_add_folder( cache, parent, itemGFolder );
1475 /* Add group into folder */
1476 itemGroup = addritem_create_item_group();
1477 addritem_group_set_name( itemGroup, node->name );
1478 addrcache_id_group( cache, itemGroup );
1479 addrcache_folder_add_group( cache, itemGFolder, itemGroup );
1480 itemGParent = itemGroup;
1482 else if( node->type == TEMPNODE_ADDRESS ) {
1483 ItemPerson *itemPerson;
1484 ItemEMail *itemEMail;
1486 /* Create person and email objects */
1487 itemPerson = addritem_create_item_person();
1488 addritem_person_set_common_name( itemPerson, node->name );
1489 addrcache_id_person( cache, itemPerson );
1490 itemEMail = addritem_create_item_email();
1491 addritem_email_set_address( itemEMail, node->address );
1492 addritem_email_set_remarks( itemEMail, node->remarks );
1493 addrcache_id_email( cache, itemEMail );
1494 addrcache_person_add_email( cache, itemPerson, itemEMail );
1496 /* Add person into appropriate folder */
1498 addrcache_folder_add_person( cache, itemGFolder, itemPerson );
1501 addrcache_folder_add_person( cache, parent, itemPerson );
1504 /* Add email address only into group */
1506 addrcache_group_add_email( cache, parentGrp, itemEMail );
1512 AddressCvtNode *lNode = list->data;
1513 list = g_list_next( list );
1514 addrindex_process_node( abf, lNode, itemFolder, itemGParent, itemGFolder );
1519 * Process address book to specified file number.
1521 static gboolean addrindex_process_book( AddressIndex *addrIndex, XMLFile *file, gchar *displayName ) {
1522 gboolean retVal = FALSE;
1523 AddressBookFile *abf = NULL;
1524 AddressCvtNode *rootNode = NULL;
1525 gchar *newFile = NULL;
1526 GList *fileList = NULL;
1529 /* Setup root node */
1530 rootNode = g_new0( AddressCvtNode, 1 );
1531 rootNode->type = TEMPNODE_ROOT;
1532 rootNode->name = g_strdup( "root" );
1533 rootNode->list = NULL;
1534 addrindex_add_obj( file, rootNode );
1535 /* addrindex_print_node( rootNode, stdout ); */
1537 /* Create new address book */
1538 abf = addrbook_create_book();
1539 addrbook_set_name( abf, displayName );
1540 addrbook_set_path( abf, addrIndex->filePath );
1542 /* Determine next available file number */
1543 fileList = addrbook_get_bookfile_list( abf );
1545 fileNum = 1 + abf->maxValue;
1547 g_list_free( fileList );
1550 newFile = addrbook_gen_new_file_name( fileNum );
1552 addrbook_set_file( abf, newFile );
1555 addrindex_process_node( abf, rootNode, abf->addressCache->rootFolder, NULL, NULL );
1557 /* addrbook_dump_book( abf, stdout ); */
1558 addrbook_save_data( abf );
1559 addrIndex->retVal = abf->retVal;
1560 if( abf->retVal == MGU_SUCCESS ) retVal = TRUE;
1562 addrbook_free_book( abf );
1564 addrindex_free_node( rootNode );
1567 /* Create entries in address index */
1569 abf = addrbook_create_book();
1570 addrbook_set_name( abf, displayName );
1571 addrbook_set_path( abf, addrIndex->filePath );
1572 addrbook_set_file( abf, newFile );
1573 addrindex_index_add_datasource( addrIndex, ADDR_IF_BOOK, abf );
1580 * Process tree converting data.
1582 static void addrindex_convert_tree( AddressIndex *addrIndex, XMLFile *file ) {
1590 prev_level = file->level;
1591 xml_parse_next_tag( file );
1592 if (file->level < prev_level) return;
1594 xtag = xml_get_current_tag( file );
1595 /* printf( "tag : %d : %s\n", prev_level, xtag->tag ); */
1596 if( strcmp( xtag->tag, TAG_IF_OLD_COMMON ) == 0 ) {
1597 if( addrindex_process_book( addrIndex, file, DISP_OLD_COMMON ) ) {
1598 addrIndex->needsConversion = FALSE;
1599 addrIndex->wasConverted = TRUE;
1604 if( strcmp( xtag->tag, TAG_IF_OLD_PERSONAL ) == 0 ) {
1605 if( addrindex_process_book( addrIndex, file, DISP_OLD_PERSONAL ) ) {
1606 addrIndex->needsConversion = FALSE;
1607 addrIndex->wasConverted = TRUE;
1612 element = xml_get_element( file );
1613 attr = xml_get_current_tag_attr( file );
1614 /* show_attribs( attr ); */
1615 /* printf( "\ttag value : %s :\n", element ); */
1616 addrindex_consume_tree( file );
1620 static gint addrindex_convert_data( AddressIndex *addrIndex ) {
1621 XMLFile *file = NULL;
1624 fileSpec = g_strconcat( addrIndex->filePath, G_DIR_SEPARATOR_S, addrIndex->fileName, NULL );
1625 addrIndex->retVal = MGU_NO_FILE;
1626 file = xml_open_file( fileSpec );
1629 if( file == NULL ) {
1630 /* fprintf( stdout, " file '%s' does not exist.\n", addrIndex->fileName ); */
1631 return addrIndex->retVal;
1634 addrIndex->retVal = MGU_BAD_FORMAT;
1635 if( xml_get_dtd( file ) == 0 ) {
1636 if( xml_parse_next_tag( file ) == 0 ) {
1637 if( xml_compare_tag( file, TAG_ADDRESS_INDEX ) ) {
1638 addrindex_convert_tree( addrIndex, file );
1642 xml_close_file( file );
1643 return addrIndex->retVal;
1647 * Create a new address book file.
1649 static gboolean addrindex_create_new_book( AddressIndex *addrIndex, gchar *displayName ) {
1650 gboolean retVal = FALSE;
1651 AddressBookFile *abf = NULL;
1652 gchar *newFile = NULL;
1653 GList *fileList = NULL;
1656 /* Create new address book */
1657 abf = addrbook_create_book();
1658 addrbook_set_name( abf, displayName );
1659 addrbook_set_path( abf, addrIndex->filePath );
1661 /* Determine next available file number */
1662 fileList = addrbook_get_bookfile_list( abf );
1664 fileNum = 1 + abf->maxValue;
1666 g_list_free( fileList );
1669 newFile = addrbook_gen_new_file_name( fileNum );
1671 addrbook_set_file( abf, newFile );
1674 addrbook_save_data( abf );
1675 addrIndex->retVal = abf->retVal;
1676 if( abf->retVal == MGU_SUCCESS ) retVal = TRUE;
1677 addrbook_free_book( abf );
1680 /* Create entries in address index */
1682 abf = addrbook_create_book();
1683 addrbook_set_name( abf, displayName );
1684 addrbook_set_path( abf, addrIndex->filePath );
1685 addrbook_set_file( abf, newFile );
1686 addrindex_index_add_datasource( addrIndex, ADDR_IF_BOOK, abf );
1693 * Read data for address index performing a conversion if necesary.
1694 * Enter: addrIndex Address index object.
1695 * return: Status code, from addrIndex->retVal.
1696 * Note: New address book files will be created in directory specified by
1697 * addrIndex. Three files will be created, for the following:
1698 * "Common addresses"
1699 * "Personal addresses"
1700 * "Gathered addresses" - a new address book.
1702 gint addrindex_read_data( AddressIndex *addrIndex ) {
1703 g_return_val_if_fail( addrIndex != NULL, -1 );
1705 addrIndex->conversionError = FALSE;
1706 addrindex_read_file( addrIndex );
1707 if( addrIndex->retVal == MGU_SUCCESS ) {
1708 if( addrIndex->needsConversion ) {
1709 if( addrindex_convert_data( addrIndex ) == MGU_SUCCESS ) {
1710 addrIndex->conversionError = TRUE;
1713 addrIndex->conversionError = TRUE;
1716 addrIndex->dirtyFlag = TRUE;
1718 return addrIndex->retVal;
1722 * Create new address books for a new address index.
1723 * Enter: addrIndex Address index object.
1724 * return: Status code, from addrIndex->retVal.
1725 * Note: New address book files will be created in directory specified by
1726 * addrIndex. Three files will be created, for the following:
1727 * "Common addresses"
1728 * "Personal addresses"
1729 * "Gathered addresses" - a new address book.
1731 gint addrindex_create_new_books( AddressIndex *addrIndex ) {
1734 g_return_val_if_fail( addrIndex != NULL, -1 );
1736 flg = addrindex_create_new_book( addrIndex, DISP_NEW_COMMON );
1738 flg = addrindex_create_new_book( addrIndex, DISP_NEW_PERSONAL );
1739 addrIndex->dirtyFlag = TRUE;
1741 return addrIndex->retVal;
1744 /* **********************************************************************
1745 * New interface stuff.
1746 * ***********************************************************************
1750 * Return modified flag for specified data source.
1752 gboolean addrindex_ds_get_modify_flag( AddressDataSource *ds ) {
1753 gboolean retVal = FALSE;
1754 AddressInterface *iface;
1756 if( ds == NULL ) return retVal;
1757 iface = ds->interface;
1758 if( iface == NULL ) return retVal;
1759 if( iface->getModifyFlag ) {
1760 retVal = ( iface->getModifyFlag ) ( ds->rawDataSource );
1766 * Return accessed flag for specified data source.
1768 gboolean addrindex_ds_get_access_flag( AddressDataSource *ds ) {
1769 gboolean retVal = FALSE;
1770 AddressInterface *iface;
1772 if( ds == NULL ) return retVal;
1773 iface = ds->interface;
1774 if( iface == NULL ) return retVal;
1775 if( iface->getAccessFlag ) {
1776 retVal = ( iface->getAccessFlag ) ( ds->rawDataSource );
1782 * Return data read flag for specified data source.
1784 gboolean addrindex_ds_get_read_flag( AddressDataSource *ds ) {
1785 gboolean retVal = TRUE;
1786 AddressInterface *iface;
1788 if( ds == NULL ) return retVal;
1789 iface = ds->interface;
1790 if( iface == NULL ) return retVal;
1791 if( iface->getReadFlag ) {
1792 retVal = ( iface->getReadFlag ) ( ds->rawDataSource );
1798 * Return status code for specified data source.
1800 gint addrindex_ds_get_status_code( AddressDataSource *ds ) {
1801 gint retVal = MGU_SUCCESS;
1802 AddressInterface *iface;
1804 if( ds == NULL ) return retVal;
1805 iface = ds->interface;
1806 if( iface == NULL ) return retVal;
1807 if( iface->getStatusCode ) {
1808 retVal = ( iface->getStatusCode ) ( ds->rawDataSource );
1814 * Return data read flag for specified data source.
1816 gint addrindex_ds_read_data( AddressDataSource *ds ) {
1817 gint retVal = MGU_SUCCESS;
1818 AddressInterface *iface;
1820 if( ds == NULL ) return retVal;
1821 iface = ds->interface;
1822 if( iface == NULL ) return retVal;
1823 if( iface->getReadData ) {
1824 retVal = ( iface->getReadData ) ( ds->rawDataSource );
1830 * Return data read flag for specified data source.
1832 ItemFolder *addrindex_ds_get_root_folder( AddressDataSource *ds ) {
1833 ItemFolder *retVal = NULL;
1834 AddressInterface *iface;
1836 if( ds == NULL ) return retVal;
1837 iface = ds->interface;
1838 if( iface == NULL ) return retVal;
1839 if( iface->getRootFolder ) {
1840 retVal = ( iface->getRootFolder ) ( ds->rawDataSource );
1846 * Return list of folders for specified data source.
1848 GList *addrindex_ds_get_list_folder( AddressDataSource *ds ) {
1849 GList *retVal = FALSE;
1850 AddressInterface *iface;
1852 if( ds == NULL ) return retVal;
1853 iface = ds->interface;
1854 if( iface == NULL ) return retVal;
1855 if( iface->getListFolder ) {
1856 retVal = ( iface->getListFolder ) ( ds->rawDataSource );
1862 * Return list of persons in root folder for specified data source.
1864 GList *addrindex_ds_get_list_person( AddressDataSource *ds ) {
1865 GList *retVal = FALSE;
1866 AddressInterface *iface;
1868 if( ds == NULL ) return retVal;
1869 iface = ds->interface;
1870 if( iface == NULL ) return retVal;
1871 if( iface->getListPerson ) {
1872 retVal = ( iface->getListPerson ) ( ds->rawDataSource );
1878 * Return name for specified data source.
1880 gchar *addrindex_ds_get_name( AddressDataSource *ds ) {
1881 gchar *retVal = FALSE;
1882 AddressInterface *iface;
1884 if( ds == NULL ) return retVal;
1885 iface = ds->interface;
1886 if( iface == NULL ) return retVal;
1887 if( iface->getName ) {
1888 retVal = ( iface->getName ) ( ds->rawDataSource );
1894 * Set the access flag inside the data source.
1896 void addrindex_ds_set_access_flag( AddressDataSource *ds, gboolean *value ) {
1897 AddressInterface *iface;
1899 if( ds == NULL ) return;
1900 iface = ds->interface;
1901 if( iface == NULL ) return;
1902 if( iface->setAccessFlag ) {
1903 ( iface->setAccessFlag ) ( ds->rawDataSource, value );
1908 * Return read only flag for specified data source.
1910 gboolean addrindex_ds_get_readonly( AddressDataSource *ds ) {
1911 AddressInterface *iface;
1912 if( ds == NULL ) return TRUE;
1913 iface = ds->interface;
1914 if( iface == NULL ) return TRUE;
1915 return iface->readOnly;
1919 * Return list of all persons for specified data source.
1921 GList *addrindex_ds_get_all_persons( AddressDataSource *ds ) {
1922 GList *retVal = NULL;
1923 AddressInterface *iface;
1925 if( ds == NULL ) return retVal;
1926 iface = ds->interface;
1927 if( iface == NULL ) return retVal;
1928 if( iface->getAllPersons ) {
1929 retVal = ( iface->getAllPersons ) ( ds->rawDataSource );
1935 * Return list of all groups for specified data source.
1937 GList *addrindex_ds_get_all_groups( AddressDataSource *ds ) {
1938 GList *retVal = NULL;
1939 AddressInterface *iface;
1941 if( ds == NULL ) return retVal;
1942 iface = ds->interface;
1943 if( iface == NULL ) return retVal;
1944 if( iface->getAllGroups ) {
1945 retVal = ( iface->getAllGroups ) ( ds->rawDataSource );