2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 2001-2003 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
41 #include "prefs_gtk.h"
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 );
119 ADDRITEM_TYPE(iface) = ITEMTYPE_INTERFACE;
120 ADDRITEM_ID(iface) = NULL;
121 ADDRITEM_NAME(iface) = g_strdup( name );
122 ADDRITEM_PARENT(iface) = NULL;
123 ADDRITEM_SUBTYPE(iface) = type;
125 iface->name = g_strdup( name );
126 iface->listTag = g_strdup( tagIf );
127 iface->itemTag = g_strdup( tagDS );
128 iface->legacyFlag = FALSE;
129 iface->haveLibrary = TRUE;
130 iface->useInterface = TRUE;
131 iface->readOnly = TRUE;
132 iface->getAccessFlag = NULL;
133 iface->getModifyFlag = NULL;
134 iface->getReadFlag = NULL;
135 iface->getStatusCode = NULL;
136 iface->getReadData = NULL;
137 iface->getRootFolder = NULL;
138 iface->getListFolder = NULL;
139 iface->getListPerson = NULL;
140 iface->getAllPersons = NULL;
141 iface->getAllGroups = NULL;
142 iface->getName = NULL;
143 iface->listSource = NULL;
148 * Build table of interfaces.
150 static void addrindex_build_if_list( AddressIndex *addrIndex ) {
151 AddressInterface *iface;
153 iface = addrindex_create_interface( ADDR_IF_BOOK, "Address Book", TAG_IF_ADDRESS_BOOK, TAG_DS_ADDRESS_BOOK );
154 iface->readOnly = FALSE;
155 iface->getModifyFlag = ( void * ) addrbook_get_modified;
156 iface->getAccessFlag = ( void * ) addrbook_get_accessed;
157 iface->getReadFlag = ( void * ) addrbook_get_read_flag;
158 iface->getStatusCode = ( void * ) addrbook_get_status;
159 iface->getReadData = ( void * ) addrbook_read_data;
160 iface->getRootFolder = ( void * ) addrbook_get_root_folder;
161 iface->getListFolder = ( void * ) addrbook_get_list_folder;
162 iface->getListPerson = ( void * ) addrbook_get_list_person;
163 iface->getAllPersons = ( void * ) addrbook_get_all_persons;
164 iface->getName = ( void * ) addrbook_get_name;
165 iface->setAccessFlag = ( void * ) addrbook_set_accessed;
166 addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface );
167 ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex);
169 iface = addrindex_create_interface( ADDR_IF_VCARD, "vCard", TAG_IF_VCARD, TAG_DS_VCARD );
170 iface->getModifyFlag = ( void * ) vcard_get_modified;
171 iface->getAccessFlag = ( void * ) vcard_get_accessed;
172 iface->getReadFlag = ( void * ) vcard_get_read_flag;
173 iface->getStatusCode = ( void * ) vcard_get_status;
174 iface->getReadData = ( void * ) vcard_read_data;
175 iface->getRootFolder = ( void * ) vcard_get_root_folder;
176 iface->getListFolder = ( void * ) vcard_get_list_folder;
177 iface->getListPerson = ( void * ) vcard_get_list_person;
178 iface->getAllPersons = ( void * ) vcard_get_all_persons;
179 iface->getName = ( void * ) vcard_get_name;
180 iface->setAccessFlag = ( void * ) vcard_set_accessed;
181 addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface );
182 ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex);
184 iface = addrindex_create_interface( ADDR_IF_JPILOT, "J-Pilot", TAG_IF_JPILOT, TAG_DS_JPILOT );
186 iface->haveLibrary = jpilot_test_pilot_lib();
187 iface->useInterface = iface->haveLibrary;
188 iface->getModifyFlag = ( void * ) jpilot_get_modified;
189 iface->getAccessFlag = ( void * ) jpilot_get_accessed;
190 iface->getReadFlag = ( void * ) jpilot_get_read_flag;
191 iface->getStatusCode = ( void * ) jpilot_get_status;
192 iface->getReadData = ( void * ) jpilot_read_data;
193 iface->getRootFolder = ( void * ) jpilot_get_root_folder;
194 iface->getListFolder = ( void * ) jpilot_get_list_folder;
195 iface->getListPerson = ( void * ) jpilot_get_list_person;
196 iface->getAllPersons = ( void * ) jpilot_get_all_persons;
197 iface->getName = ( void * ) jpilot_get_name;
198 iface->setAccessFlag = ( void * ) jpilot_set_accessed;
200 iface->useInterface = FALSE;
201 iface->haveLibrary = FALSE;
203 addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface );
204 ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex);
206 iface = addrindex_create_interface( ADDR_IF_LDAP, "LDAP", TAG_IF_LDAP, TAG_DS_LDAP );
208 iface->haveLibrary = syldap_test_ldap_lib();
209 iface->useInterface = iface->haveLibrary;
210 iface->getAccessFlag = ( void * ) syldap_get_accessed;
211 /* iface->getModifyFlag = ( void * ) syldap_get_modified; */
212 /* iface->getReadFlag = ( void * ) syldap_get_read_flag; */
213 iface->getStatusCode = ( void * ) syldap_get_status;
214 iface->getReadData = ( void * ) syldap_read_data;
215 iface->getRootFolder = ( void * ) syldap_get_root_folder;
216 iface->getListFolder = ( void * ) syldap_get_list_folder;
217 iface->getListPerson = ( void * ) syldap_get_list_person;
218 iface->getName = ( void * ) syldap_get_name;
219 iface->setAccessFlag = ( void * ) syldap_set_accessed;
221 iface->useInterface = FALSE;
222 iface->haveLibrary = FALSE;
224 addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface );
225 ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex);
227 /* Two old legacy data sources */
228 iface = addrindex_create_interface(
229 ADDR_IF_COMMON, "Old Address - common",
230 TAG_IF_OLD_COMMON, NULL );
231 iface->legacyFlag = TRUE;
232 addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface );
233 ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex);
235 iface = addrindex_create_interface(
236 ADDR_IF_COMMON, "Old Address - personal",
237 TAG_IF_OLD_PERSONAL, NULL );
238 iface->legacyFlag = TRUE;
239 addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface );
240 ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex);
245 * Free name-value pairs.
247 static void addrindex_free_attributes( GList *list ) {
250 AddressIfAttrib *nv = node->data;
251 g_free( nv->name ); nv->name = NULL;
252 g_free( nv->value ); nv->value = NULL;
255 node = g_list_next( node );
261 * Create new data source.
262 * Enter: ifType Interface type to create.
263 * Return: Initialized data source.
265 AddressDataSource *addrindex_create_datasource( AddressIfType ifType ) {
266 AddressDataSource *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( ds->rawDataSource != NULL ) {
289 if( iface != 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 );
315 GList *list = ds->rawDataSource;
316 addrindex_free_attributes( list );
321 ADDRITEM_TYPE(ds) = ITEMTYPE_NONE;
322 ADDRITEM_ID(ds) = NULL;
323 ADDRITEM_NAME(ds) = NULL;
324 ADDRITEM_PARENT(ds) = NULL;
325 ADDRITEM_SUBTYPE(ds) = 0;
326 ds->type = ADDR_IF_NONE;
327 ds->interface = NULL;
328 ds->rawDataSource = NULL;
332 static void addrindex_free_all_datasources( AddressInterface *iface ) {
333 GList *node = iface->listSource;
335 AddressDataSource *ds = node->data;
336 addrindex_free_datasource( ds );
338 node = g_list_next( node );
342 static void addrindex_free_interface( AddressInterface *iface ) {
343 /* Free up data sources */
344 addrindex_free_all_datasources( iface );
345 g_list_free( iface->listSource );
347 /* Free internal storage */
348 g_free( ADDRITEM_ID(iface) );
349 g_free( ADDRITEM_NAME(iface) );
350 g_free( iface->name );
351 g_free( iface->listTag );
352 g_free( iface->itemTag );
354 /* Clear all pointers */
355 ADDRITEM_TYPE(iface) = ITEMTYPE_NONE;
356 ADDRITEM_ID(iface) = NULL;
357 ADDRITEM_NAME(iface) = NULL;
358 ADDRITEM_PARENT(iface) = NULL;
359 ADDRITEM_SUBTYPE(iface) = 0;
360 iface->type = ADDR_IF_NONE;
362 iface->listTag = NULL;
363 iface->itemTag = NULL;
364 iface->legacyFlag = FALSE;
365 iface->useInterface = FALSE;
366 iface->haveLibrary = FALSE;
367 iface->listSource = NULL;
373 * Return cache ID for specified data source.
374 * Enter: addrIndex Address index.
376 * Return: ID or NULL if not found. This can be g_free() when done.
378 gchar *addrindex_get_cache_id( AddressIndex *addrIndex, AddressDataSource *ds ) {
379 gchar *cacheID = NULL;
380 AddrBookBase *adbase;
383 g_return_val_if_fail( addrIndex != NULL, NULL );
384 g_return_val_if_fail( ds != NULL, NULL );
386 adbase = ( AddrBookBase * ) ds->rawDataSource;
388 cache = adbase->addressCache;
390 cacheID = g_strdup( cache->cacheID );
398 * Return data source for specified cacheID.
399 * Enter: addrIndex Address index.
401 * Return: Data source, or NULL if not found.
403 AddressDataSource *addrindex_get_datasource( AddressIndex *addrIndex, const gchar *cacheID ) {
404 g_return_val_if_fail( addrIndex != NULL, NULL );
405 g_return_val_if_fail( cacheID != NULL, NULL );
406 return ( AddressDataSource * ) g_hash_table_lookup( addrIndex->hashCache, cacheID );
410 * Return cache for specified cacheID.
411 * Enter: addrIndex Address index.
413 * Return: Address cache, or NULL if not found.
415 AddressCache *addrindex_get_cache( AddressIndex *addrIndex, const gchar *cacheID ) {
416 AddressDataSource *ds;
417 AddrBookBase *adbase;
420 g_return_val_if_fail( addrIndex != NULL, NULL );
421 g_return_val_if_fail( cacheID != NULL, NULL );
424 ds = addrindex_get_datasource( addrIndex, cacheID );
426 adbase = ( AddrBookBase * ) ds->rawDataSource;
427 cache = adbase->addressCache;
433 * Add data source into hash.
434 * Enter: addrIndex Address index.
437 static void addrindex_hash_add_cache( AddressIndex *addrIndex, AddressDataSource *ds ) {
440 cacheID = addrindex_get_cache_id( addrIndex, ds );
442 g_hash_table_insert( addrIndex->hashCache, cacheID, ds );
447 * Free hash table callback function.
449 static gboolean addrindex_free_cache_cb( gpointer key, gpointer value, gpointer data ) {
457 * Free hash table of address cache items.
459 static void addrindex_free_cache_hash( GHashTable *table ) {
460 g_hash_table_freeze( table );
461 g_hash_table_foreach_remove( table, addrindex_free_cache_cb, NULL );
462 g_hash_table_thaw( table );
463 g_hash_table_destroy( table );
467 * Remove address cache for specified data source from internal hashtable.
469 static void addrindex_hash_remove_cache( AddressIndex *addrIndex, AddressDataSource *ds ) {
472 cacheID = addrindex_get_cache_id( addrIndex, ds );
474 g_hash_table_remove( addrIndex->hashCache, cacheID );
483 AddressIndex *addrindex_create_index( void ) {
484 AddressIndex *addrIndex = g_new0( AddressIndex, 1 );
486 ADDRITEM_TYPE(addrIndex) = ITEMTYPE_INDEX;
487 ADDRITEM_ID(addrIndex) = NULL;
488 ADDRITEM_NAME(addrIndex) = g_strdup( "Address Index" );
489 ADDRITEM_PARENT(addrIndex) = NULL;
490 ADDRITEM_SUBTYPE(addrIndex) = 0;
491 addrIndex->filePath = NULL;
492 addrIndex->fileName = NULL;
493 addrIndex->retVal = MGU_SUCCESS;
494 addrIndex->needsConversion = FALSE;
495 addrIndex->wasConverted = FALSE;
496 addrIndex->conversionError = FALSE;
497 addrIndex->interfaceList = NULL;
498 addrIndex->lastType = ADDR_IF_NONE;
499 addrIndex->dirtyFlag = FALSE;
500 addrIndex->hashCache = g_hash_table_new( g_str_hash, g_str_equal );
501 addrindex_build_if_list( addrIndex );
506 * Specify file to be used.
508 void addrindex_set_file_path( AddressIndex *addrIndex, const gchar *value ) {
509 g_return_if_fail( addrIndex != NULL );
510 addrIndex->filePath = mgu_replace_string( addrIndex->filePath, value );
512 void addrindex_set_file_name( AddressIndex *addrIndex, const gchar *value ) {
513 g_return_if_fail( addrIndex != NULL );
514 addrIndex->fileName = mgu_replace_string( addrIndex->fileName, value );
516 void addrindex_set_dirty( AddressIndex *addrIndex, const gboolean value ) {
517 g_return_if_fail( addrIndex != NULL );
518 addrIndex->dirtyFlag = value;
522 * Return list of interfaces.
524 GList *addrindex_get_interface_list( AddressIndex *addrIndex ) {
525 g_return_val_if_fail( addrIndex != NULL, NULL );
526 return addrIndex->interfaceList;
532 void addrindex_free_index( AddressIndex *addrIndex ) {
535 g_return_if_fail( addrIndex != NULL );
537 g_free( ADDRITEM_ID(addrIndex) );
538 g_free( ADDRITEM_NAME(addrIndex) );
539 g_free( addrIndex->filePath );
540 g_free( addrIndex->fileName );
541 ADDRITEM_TYPE(addrIndex) = ITEMTYPE_NONE;
542 ADDRITEM_ID(addrIndex) = NULL;
543 ADDRITEM_NAME(addrIndex) = NULL;
544 ADDRITEM_PARENT(addrIndex) = NULL;
545 ADDRITEM_SUBTYPE(addrIndex) = 0;
546 addrIndex->filePath = NULL;
547 addrIndex->fileName = NULL;
548 addrIndex->retVal = MGU_SUCCESS;
549 addrIndex->needsConversion = FALSE;
550 addrIndex->wasConverted = FALSE;
551 addrIndex->conversionError = FALSE;
552 addrIndex->lastType = ADDR_IF_NONE;
553 addrIndex->dirtyFlag = FALSE;
554 node = addrIndex->interfaceList;
556 AddressInterface *iface = node->data;
557 addrindex_free_interface( iface );
558 node = g_list_next( node );
560 g_list_free( addrIndex->interfaceList );
561 addrIndex->interfaceList = NULL;
562 addrindex_free_cache_hash( addrIndex->hashCache );
563 addrIndex->hashCache = NULL;
568 * Print address index.
570 void addrindex_print_index( AddressIndex *addrIndex, FILE *stream ) {
571 g_return_if_fail( addrIndex != NULL );
572 fprintf( stream, "AddressIndex:\n" );
573 fprintf( stream, "\tfile path: '%s'\n", addrIndex->filePath );
574 fprintf( stream, "\tfile name: '%s'\n", addrIndex->fileName );
575 fprintf( stream, "\t status: %d : '%s'\n", addrIndex->retVal, mgu_error2string( addrIndex->retVal ) );
576 fprintf( stream, "\tconverted: '%s'\n", addrIndex->wasConverted ? "yes" : "no" );
577 fprintf( stream, "\tcvt error: '%s'\n", addrIndex->conversionError ? "yes" : "no" );
578 fprintf( stream, "\t---\n" );
582 * Retrieve specified interface from index.
584 AddressInterface *addrindex_get_interface(
585 AddressIndex *addrIndex, AddressIfType ifType )
587 AddressInterface *retVal = NULL;
590 g_return_val_if_fail( addrIndex != NULL, NULL );
592 node = addrIndex->interfaceList;
594 AddressInterface *iface = node->data;
595 node = g_list_next( node );
596 if( iface->type == ifType ) {
605 * Add data source to index.
606 * Enter: addrIndex Address index object.
607 * ifType Interface type to add.
608 * dataSource Actual data source to add.
609 * Return: TRUE if data source was added.
610 * Note: The raw data object (for example, AddressBookFile or VCardFile object) should be
611 * supplied as the dataSource argument.
613 AddressDataSource *addrindex_index_add_datasource(
614 AddressIndex *addrIndex, AddressIfType ifType, gpointer dataSource )
616 AddressInterface *iface;
617 AddressDataSource *ds = NULL;
619 g_return_val_if_fail( addrIndex != NULL, NULL );
620 g_return_val_if_fail( dataSource != NULL, NULL );
622 iface = addrindex_get_interface( addrIndex, ifType );
624 ds = addrindex_create_datasource( ifType );
625 ADDRITEM_PARENT(ds) = ADDRITEM_OBJECT(iface);
627 ds->rawDataSource = dataSource;
628 ds->interface = iface;
629 iface->listSource = g_list_append( iface->listSource, ds );
630 addrIndex->dirtyFlag = TRUE;
632 addrindex_hash_add_cache( addrIndex, ds );
638 * Remove data source from index.
639 * Enter: addrIndex Address index object.
640 * dataSource Data source to remove.
641 * Return: Data source if removed, or NULL if data source was not found in
642 * index. Note the this object must still be freed.
644 AddressDataSource *addrindex_index_remove_datasource(
645 AddressIndex *addrIndex, AddressDataSource *dataSource )
647 AddressDataSource *retVal = FALSE;
648 AddressInterface *iface;
650 g_return_val_if_fail( addrIndex != NULL, NULL );
651 g_return_val_if_fail( dataSource != NULL, NULL );
653 iface = addrindex_get_interface( addrIndex, dataSource->type );
655 iface->listSource = g_list_remove( iface->listSource, dataSource );
656 addrIndex->dirtyFlag = TRUE;
657 dataSource->interface = NULL;
659 /* Remove cache from hash table */
660 addrindex_hash_remove_cache( addrIndex, dataSource );
667 static AddressInterface *addrindex_tag_get_interface(
668 AddressIndex *addrIndex, gchar *tag, AddressIfType ifType )
670 AddressInterface *retVal = NULL;
671 GList *node = addrIndex->interfaceList;
674 AddressInterface *iface = node->data;
675 node = g_list_next( node );
677 if( strcmp( iface->listTag, tag ) == 0 ) {
683 if( iface->type == ifType ) {
692 static AddressInterface *addrindex_tag_get_datasource(
693 AddressIndex *addrIndex, AddressIfType ifType, gchar *tag )
695 AddressInterface *retVal = NULL;
696 GList *node = addrIndex->interfaceList;
699 AddressInterface *iface = node->data;
700 node = g_list_next( node );
701 if( iface->type == ifType && iface->itemTag ) {
702 if( strcmp( iface->itemTag, tag ) == 0 ) {
711 /* **********************************************************************
712 * Interface XML parsing functions.
713 * ***********************************************************************
716 static void show_attribs( GList *attr ) {
718 gchar *name = ((XMLAttr *)attr->data)->name;
719 gchar *value = ((XMLAttr *)attr->data)->value;
720 printf( "\tattr value : %s :%s:\n", name, value );
721 attr = g_list_next( attr );
727 static void addrindex_write_elem_s( FILE *fp, gint lvl, gchar *name ) {
729 for( i = 0; i < lvl; i++ ) fputs( " ", fp );
734 static void addrindex_write_elem_e( FILE *fp, gint lvl, gchar *name ) {
736 for( i = 0; i < lvl; i++ ) fputs( " ", fp );
742 static void addrindex_write_attr( FILE *fp, gchar *name, gchar *value ) {
746 xml_file_put_escape_str( fp, value );
751 * Return list of name-value pairs.
753 static GList *addrindex_read_attributes( XMLFile *file ) {
760 attr = xml_get_current_tag_attr( file );
762 name = ((XMLAttr *)attr->data)->name;
763 value = ((XMLAttr *)attr->data)->value;
764 nv = g_new0( AddressIfAttrib, 1 );
765 nv->name = g_strdup( name );
766 nv->value = g_strdup( value );
767 list = g_list_append( list, nv );
768 attr = g_list_next( attr );
774 * Output name-value pairs.
776 static void addrindex_write_attributes( FILE *fp, gchar *tag, GList *list, gint lvl ) {
780 addrindex_write_elem_s( fp, lvl, tag );
784 addrindex_write_attr( fp, nv->name, nv->value );
785 node = g_list_next( node );
792 static void addrindex_print_attributes( GList *list, FILE *stream ) {
795 AddressIfAttrib *nv = node->data;
796 fprintf( stream, "%s : %s\n", nv->name, nv->value );
797 node = g_list_next( node );
802 static AddressDataSource *addrindex_parse_book( XMLFile *file ) {
803 AddressDataSource *ds;
804 AddressBookFile *abf;
807 ds = addrindex_create_datasource( ADDR_IF_BOOK );
808 abf = addrbook_create_book();
809 attr = xml_get_current_tag_attr( file );
811 gchar *name = ((XMLAttr *)attr->data)->name;
812 gchar *value = ((XMLAttr *)attr->data)->value;
813 if( strcmp( name, ATTAG_BOOK_NAME ) == 0 ) {
814 addrbook_set_name( abf, value );
816 else if( strcmp( name, ATTAG_BOOK_FILE ) == 0) {
817 addrbook_set_file( abf, value );
819 attr = g_list_next( attr );
821 ds->rawDataSource = abf;
825 static void addrindex_write_book( FILE *fp, AddressDataSource *ds, gint lvl ) {
826 AddressBookFile *abf = ds->rawDataSource;
828 addrindex_write_elem_s( fp, lvl, TAG_DS_ADDRESS_BOOK );
829 addrindex_write_attr( fp, ATTAG_BOOK_NAME, addrbook_get_name( abf ) );
830 addrindex_write_attr( fp, ATTAG_BOOK_FILE, abf->fileName );
831 fputs( " />\n", fp );
835 static AddressDataSource *addrindex_parse_vcard( XMLFile *file ) {
836 AddressDataSource *ds;
840 ds = addrindex_create_datasource( ADDR_IF_VCARD );
841 vcf = vcard_create();
842 attr = xml_get_current_tag_attr( file );
844 gchar *name = ((XMLAttr *)attr->data)->name;
845 gchar *value = ((XMLAttr *)attr->data)->value;
846 if( strcmp( name, ATTAG_VCARD_NAME ) == 0 ) {
847 vcard_set_name( vcf, value );
849 else if( strcmp( name, ATTAG_VCARD_FILE ) == 0) {
850 vcard_set_file( vcf, value );
852 attr = g_list_next( attr );
854 ds->rawDataSource = vcf;
858 static void addrindex_write_vcard( FILE *fp, AddressDataSource *ds, gint lvl ) {
859 VCardFile *vcf = ds->rawDataSource;
861 addrindex_write_elem_s( fp, lvl, TAG_DS_VCARD );
862 addrindex_write_attr( fp, ATTAG_VCARD_NAME, vcard_get_name( vcf ) );
863 addrindex_write_attr( fp, ATTAG_VCARD_FILE, vcf->path );
864 fputs( " />\n", fp );
869 static AddressDataSource *addrindex_parse_jpilot( XMLFile *file ) {
870 AddressDataSource *ds;
874 ds = addrindex_create_datasource( ADDR_IF_JPILOT );
875 jpf = jpilot_create();
876 attr = xml_get_current_tag_attr( file );
878 gchar *name = ((XMLAttr *)attr->data)->name;
879 gchar *value = ((XMLAttr *)attr->data)->value;
880 if( strcmp( name, ATTAG_JPILOT_NAME ) == 0 ) {
881 jpilot_set_name( jpf, value );
883 else if( strcmp( name, ATTAG_JPILOT_FILE ) == 0 ) {
884 jpilot_set_file( jpf, value );
886 else if( strcmp( name, ATTAG_JPILOT_CUSTOM_1 ) == 0 ) {
887 jpilot_add_custom_label( jpf, value );
889 else if( strcmp( name, ATTAG_JPILOT_CUSTOM_2 ) == 0 ) {
890 jpilot_add_custom_label( jpf, value );
892 else if( strcmp( name, ATTAG_JPILOT_CUSTOM_3 ) == 0 ) {
893 jpilot_add_custom_label( jpf, value );
895 else if( strcmp( name, ATTAG_JPILOT_CUSTOM_4 ) == 0 ) {
896 jpilot_add_custom_label( jpf, value );
898 attr = g_list_next( attr );
900 ds->rawDataSource = jpf;
904 static void addrindex_write_jpilot( FILE *fp,AddressDataSource *ds, gint lvl ) {
905 JPilotFile *jpf = ds->rawDataSource;
909 GList *customLbl = jpilot_get_custom_labels( jpf );
910 addrindex_write_elem_s( fp, lvl, TAG_DS_JPILOT );
911 addrindex_write_attr( fp, ATTAG_JPILOT_NAME, jpilot_get_name( jpf ) );
912 addrindex_write_attr( fp, ATTAG_JPILOT_FILE, jpf->path );
917 g_snprintf( name, sizeof(name), "%s%d",
918 ATTAG_JPILOT_CUSTOM, ind );
919 addrindex_write_attr( fp, name, node->data );
921 node = g_list_next( node );
923 fputs( " />\n", fp );
927 /* Just read/write name-value pairs (preserve data found in file) */
928 static AddressDataSource *addrindex_parse_jpilot( XMLFile *file ) {
929 AddressDataSource *ds;
931 ds = addrindex_create_datasource( ADDR_IF_JPILOT );
932 ds->rawDataSource = addrindex_read_attributes( file );
936 static void addrindex_write_jpilot( FILE *fp, AddressDataSource *ds, gint lvl ) {
937 GList *list = ds->rawDataSource;
939 addrindex_write_attributes( fp, TAG_DS_JPILOT, list, lvl );
945 static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
946 AddressDataSource *ds;
947 SyldapServer *server;
950 ds = addrindex_create_datasource( ADDR_IF_LDAP );
951 server = syldap_create();
952 attr = xml_get_current_tag_attr( file );
954 gchar *name = ((XMLAttr *)attr->data)->name;
955 gchar *value = ((XMLAttr *)attr->data)->value;
956 gint ivalue = atoi( value );
957 if( strcmp( name, ATTAG_LDAP_NAME ) == 0 ) {
958 syldap_set_name( server, value );
960 else if( strcmp( name, ATTAG_LDAP_HOST ) == 0 ) {
961 syldap_set_host( server, value );
963 else if( strcmp( name, ATTAG_LDAP_PORT ) == 0 ) {
964 syldap_set_port( server, ivalue );
966 else if( strcmp( name, ATTAG_LDAP_BASE_DN ) == 0 ) {
967 syldap_set_base_dn( server, value );
969 else if( strcmp( name, ATTAG_LDAP_BIND_DN ) == 0 ) {
970 syldap_set_bind_dn( server, value );
972 else if( strcmp( name, ATTAG_LDAP_BIND_PASS ) == 0 ) {
973 syldap_set_bind_password( server, value );
975 else if( strcmp( name, ATTAG_LDAP_CRITERIA ) == 0 ) {
976 syldap_set_search_criteria( server, value );
978 else if( strcmp( name, ATTAG_LDAP_MAX_ENTRY ) == 0 ) {
979 syldap_set_max_entries( server, ivalue );
981 else if( strcmp( name, ATTAG_LDAP_TIMEOUT ) == 0 ) {
982 syldap_set_timeout( server, ivalue );
984 attr = g_list_next( attr );
987 ds->rawDataSource = server;
991 static void addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) {
992 SyldapServer *server = ds->rawDataSource;
996 addrindex_write_elem_s( fp, lvl, TAG_DS_LDAP );
997 addrindex_write_attr( fp, ATTAG_LDAP_NAME, syldap_get_name( server ) );
998 addrindex_write_attr( fp, ATTAG_LDAP_HOST, server->hostName );
1000 sprintf( value, "%d", server->port );
1001 addrindex_write_attr( fp, ATTAG_LDAP_PORT, value );
1003 addrindex_write_attr( fp, ATTAG_LDAP_BASE_DN, server->baseDN );
1004 addrindex_write_attr( fp, ATTAG_LDAP_BIND_DN, server->bindDN );
1005 addrindex_write_attr( fp, ATTAG_LDAP_BIND_PASS, server->bindPass );
1006 addrindex_write_attr( fp, ATTAG_LDAP_CRITERIA, server->searchCriteria );
1008 sprintf( value, "%d", server->maxEntries );
1009 addrindex_write_attr( fp, ATTAG_LDAP_MAX_ENTRY, value );
1010 sprintf( value, "%d", server->timeOut );
1011 addrindex_write_attr( fp, ATTAG_LDAP_TIMEOUT, value );
1017 /* Just read/write name-value pairs (preserve data found in file) */
1018 static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
1019 AddressDataSource *ds;
1021 ds = addrindex_create_datasource( ADDR_IF_LDAP );
1022 ds->rawDataSource = addrindex_read_attributes( file );
1026 static void addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) {
1027 GList *list = ds->rawDataSource;
1029 addrindex_write_attributes( fp, TAG_DS_LDAP, list, lvl );
1034 /* **********************************************************************
1035 * Address index I/O functions.
1036 * ***********************************************************************
1038 static void addrindex_read_index( AddressIndex *addrIndex, XMLFile *file ) {
1041 AddressInterface *iface = NULL, *dsIFace = NULL;
1042 AddressDataSource *ds;
1045 prev_level = file->level;
1046 xml_parse_next_tag( file );
1047 if( file->level < prev_level ) return;
1049 xtag = xml_get_current_tag( file );
1051 iface = addrindex_tag_get_interface( addrIndex, xtag->tag, ADDR_IF_NONE );
1053 addrIndex->lastType = iface->type;
1054 if( iface->legacyFlag ) addrIndex->needsConversion = TRUE;
1057 dsIFace = addrindex_tag_get_datasource(
1058 addrIndex, addrIndex->lastType, xtag->tag );
1060 /* Add data source to list */
1062 if( addrIndex->lastType == ADDR_IF_BOOK ) {
1063 ds = addrindex_parse_book( file );
1064 if( ds->rawDataSource ) {
1065 addrbook_set_path( ds->rawDataSource,
1066 addrIndex->filePath );
1069 else if( addrIndex->lastType == ADDR_IF_VCARD ) {
1070 ds = addrindex_parse_vcard( file );
1072 else if( addrIndex->lastType == ADDR_IF_JPILOT ) {
1073 ds = addrindex_parse_jpilot( file );
1075 else if( addrIndex->lastType == ADDR_IF_LDAP ) {
1076 ds = addrindex_parse_ldap( file );
1079 ds->interface = dsIFace;
1080 addrindex_hash_add_cache( addrIndex, ds );
1081 dsIFace->listSource =
1082 g_list_append( dsIFace->listSource, ds );
1086 addrindex_read_index( addrIndex, file );
1090 static gint addrindex_read_file( AddressIndex *addrIndex ) {
1091 XMLFile *file = NULL;
1092 gchar *fileSpec = NULL;
1094 g_return_val_if_fail( addrIndex != NULL, -1 );
1096 fileSpec = g_strconcat( addrIndex->filePath, G_DIR_SEPARATOR_S, addrIndex->fileName, NULL );
1097 addrIndex->retVal = MGU_NO_FILE;
1098 file = xml_open_file( fileSpec );
1101 if( file == NULL ) {
1102 /* fprintf( stdout, " file '%s' does not exist.\n", addrIndex->fileName ); */
1103 return addrIndex->retVal;
1106 addrIndex->retVal = MGU_BAD_FORMAT;
1107 if( xml_get_dtd( file ) == 0 ) {
1108 if( xml_parse_next_tag( file ) == 0 ) {
1109 if( xml_compare_tag( file, TAG_ADDRESS_INDEX ) ) {
1110 addrindex_read_index( addrIndex, file );
1111 addrIndex->retVal = MGU_SUCCESS;
1115 xml_close_file( file );
1117 return addrIndex->retVal;
1120 static void addrindex_write_index( AddressIndex *addrIndex, FILE *fp ) {
1121 GList *nodeIF, *nodeDS;
1123 gint lvlItem = 1 + lvlList;
1125 nodeIF = addrIndex->interfaceList;
1127 AddressInterface *iface = nodeIF->data;
1128 if( ! iface->legacyFlag ) {
1129 nodeDS = iface->listSource;
1130 addrindex_write_elem_s( fp, lvlList, iface->listTag );
1133 AddressDataSource *ds = nodeDS->data;
1135 if( iface->type == ADDR_IF_BOOK ) {
1136 addrindex_write_book( fp, ds, lvlItem );
1138 if( iface->type == ADDR_IF_VCARD ) {
1139 addrindex_write_vcard( fp, ds, lvlItem );
1141 if( iface->type == ADDR_IF_JPILOT ) {
1142 addrindex_write_jpilot( fp, ds, lvlItem );
1144 if( iface->type == ADDR_IF_LDAP ) {
1145 addrindex_write_ldap( fp, ds, lvlItem );
1148 nodeDS = g_list_next( nodeDS );
1150 addrindex_write_elem_e( fp, lvlList, iface->listTag );
1152 nodeIF = g_list_next( nodeIF );
1157 * Write data to specified file.
1158 * Enter: addrIndex Address index object.
1159 * newFile New file name.
1160 * return: Status code, from addrIndex->retVal.
1161 * Note: File will be created in directory specified by addrIndex.
1163 gint addrindex_write_to( AddressIndex *addrIndex, const gchar *newFile ) {
1166 #ifndef DEV_STANDALONE
1170 g_return_val_if_fail( addrIndex != NULL, -1 );
1172 fileSpec = g_strconcat( addrIndex->filePath, G_DIR_SEPARATOR_S, newFile, NULL );
1173 addrIndex->retVal = MGU_OPEN_FILE;
1174 #ifdef DEV_STANDALONE
1175 fp = fopen( fileSpec, "wb" );
1178 fputs( "<?xml version=\"1.0\" ?>\n", fp );
1180 pfile = prefs_write_open( fileSpec );
1184 fprintf( fp, "<?xml version=\"1.0\" encoding=\"%s\" ?>\n",
1185 conv_get_current_charset_str() );
1187 addrindex_write_elem_s( fp, 0, TAG_ADDRESS_INDEX );
1190 addrindex_write_index( addrIndex, fp );
1191 addrindex_write_elem_e( fp, 0, TAG_ADDRESS_INDEX );
1193 addrIndex->retVal = MGU_SUCCESS;
1194 #ifdef DEV_STANDALONE
1197 if( prefs_file_close( pfile ) < 0 ) {
1198 addrIndex->retVal = MGU_ERROR_WRITE;
1204 return addrIndex->retVal;
1208 * Save address index data to original file.
1209 * return: Status code, from addrIndex->retVal.
1211 gint addrindex_save_data( AddressIndex *addrIndex ) {
1212 g_return_val_if_fail( addrIndex != NULL, -1 );
1214 addrIndex->retVal = MGU_NO_FILE;
1215 if( addrIndex->fileName == NULL || *addrIndex->fileName == '\0' ) return addrIndex->retVal;
1216 if( addrIndex->filePath == NULL || *addrIndex->filePath == '\0' ) return addrIndex->retVal;
1218 addrindex_write_to( addrIndex, addrIndex->fileName );
1219 if( addrIndex->retVal == MGU_SUCCESS ) {
1220 addrIndex->dirtyFlag = FALSE;
1222 return addrIndex->retVal;
1226 * Save all address book files which may have changed.
1227 * Return: Status code, set if there was a problem saving data.
1229 gint addrindex_save_all_books( AddressIndex *addrIndex ) {
1230 gint retVal = MGU_SUCCESS;
1231 GList *nodeIf, *nodeDS;
1233 nodeIf = addrIndex->interfaceList;
1235 AddressInterface *iface = nodeIf->data;
1236 if( iface->type == ADDR_IF_BOOK ) {
1237 nodeDS = iface->listSource;
1239 AddressDataSource *ds = nodeDS->data;
1240 AddressBookFile *abf = ds->rawDataSource;
1241 if( addrbook_get_dirty( abf ) ) {
1242 if( addrbook_get_read_flag( abf ) ) {
1243 addrbook_save_data( abf );
1244 if( abf->retVal != MGU_SUCCESS ) {
1245 retVal = abf->retVal;
1249 nodeDS = g_list_next( nodeDS );
1253 nodeIf = g_list_next( nodeIf );
1259 /* **********************************************************************
1260 * Address book conversion to new format.
1261 * ***********************************************************************
1264 #define ELTAG_IF_OLD_FOLDER "folder"
1265 #define ELTAG_IF_OLD_GROUP "group"
1266 #define ELTAG_IF_OLD_ITEM "item"
1267 #define ELTAG_IF_OLD_NAME "name"
1268 #define ELTAG_IF_OLD_ADDRESS "address"
1269 #define ELTAG_IF_OLD_REMARKS "remarks"
1270 #define ATTAG_IF_OLD_NAME "name"
1272 #define TEMPNODE_ROOT 0
1273 #define TEMPNODE_FOLDER 1
1274 #define TEMPNODE_GROUP 2
1275 #define TEMPNODE_ADDRESS 3
1277 typedef struct _AddressCvt_Node AddressCvtNode;
1278 struct _AddressCvt_Node {
1287 * Parse current address item.
1289 static AddressCvtNode *addrindex_parse_item( XMLFile *file ) {
1294 nn = g_new0( AddressCvtNode, 1 );
1295 nn->type = TEMPNODE_ADDRESS;
1298 level = file->level;
1301 xml_parse_next_tag(file);
1302 if (file->level < level) return nn;
1304 element = xml_get_element( file );
1305 if( xml_compare_tag( file, ELTAG_IF_OLD_NAME ) ) {
1306 nn->name = g_strdup( element );
1308 if( xml_compare_tag( file, ELTAG_IF_OLD_ADDRESS ) ) {
1309 nn->address = g_strdup( element );
1311 if( xml_compare_tag( file, ELTAG_IF_OLD_REMARKS ) ) {
1312 nn->remarks = g_strdup( element );
1314 xml_parse_next_tag(file);
1319 * Create a temporary node below specified node.
1321 static AddressCvtNode *addrindex_add_object( AddressCvtNode *node, gint type, gchar *name, gchar *addr, char *rem ) {
1323 nn = g_new0( AddressCvtNode, 1 );
1325 nn->name = g_strdup( name );
1326 nn->remarks = g_strdup( rem );
1327 node->list = g_list_append( node->list, nn );
1332 * Process current temporary node.
1334 static void addrindex_add_obj( XMLFile *file, AddressCvtNode *node ) {
1337 AddressCvtNode *newNode = NULL;
1342 prev_level = file->level;
1343 xml_parse_next_tag( file );
1344 if (file->level < prev_level) return;
1348 if( xml_compare_tag( file, ELTAG_IF_OLD_GROUP ) ) {
1349 attr = xml_get_current_tag_attr(file);
1351 name = ((XMLAttr *)attr->data)->name;
1352 if( strcmp( name, ATTAG_IF_OLD_NAME ) == 0 ) {
1353 value = ((XMLAttr *)attr->data)->value;
1356 newNode = addrindex_add_object( node, TEMPNODE_GROUP, value, "", "" );
1357 addrindex_add_obj( file, newNode );
1360 else if( xml_compare_tag( file, ELTAG_IF_OLD_FOLDER ) ) {
1361 attr = xml_get_current_tag_attr(file);
1363 name = ((XMLAttr *)attr->data)->name;
1364 if( strcmp( name, ATTAG_IF_OLD_NAME ) == 0 ) {
1365 value = ((XMLAttr *)attr->data)->value;
1368 newNode = addrindex_add_object( node, TEMPNODE_FOLDER, value, "", "" );
1369 addrindex_add_obj( file, newNode );
1371 else if( xml_compare_tag( file, ELTAG_IF_OLD_ITEM ) ) {
1372 newNode = addrindex_parse_item( file );
1373 node->list = g_list_append( node->list, newNode );
1376 /* printf( "invalid: !!! \n" ); */
1377 attr = xml_get_current_tag_attr( file );
1383 * Consume all nodes below current tag.
1385 static void addrindex_consume_tree( XMLFile *file ) {
1392 prev_level = file->level;
1393 xml_parse_next_tag( file );
1394 if (file->level < prev_level) return;
1396 xtag = xml_get_current_tag( file );
1397 /* printf( "tag : %s\n", xtag->tag ); */
1398 element = xml_get_element( file );
1399 attr = xml_get_current_tag_attr( file );
1400 /* show_attribs( attr ); */
1401 /* printf( "\ttag value : %s :\n", element ); */
1402 addrindex_consume_tree( file );
1407 * Print temporary tree.
1409 static void addrindex_print_node( AddressCvtNode *node, FILE *stream ) {
1412 fprintf( stream, "Node:\ttype :%d:\n", node->type );
1413 fprintf( stream, "\tname :%s:\n", node->name );
1414 fprintf( stream, "\taddr :%s:\n", node->address );
1415 fprintf( stream, "\trems :%s:\n", node->remarks );
1417 fprintf( stream, "\t--list----\n" );
1421 AddressCvtNode *lNode = list->data;
1422 list = g_list_next( list );
1423 addrindex_print_node( lNode, stream );
1425 fprintf( stream, "\t==list-%d==\n", node->type );
1429 * Free up temporary tree.
1431 static void addrindex_free_node( AddressCvtNode *node ) {
1432 GList *list = node->list;
1435 AddressCvtNode *lNode = list->data;
1436 list = g_list_next( list );
1437 addrindex_free_node( lNode );
1439 node->type = TEMPNODE_ROOT;
1440 g_free( node->name );
1441 g_free( node->address );
1442 g_free( node->remarks );
1443 g_list_free( node->list );
1448 * Process address book for specified node.
1450 static void addrindex_process_node(
1451 AddressBookFile *abf, AddressCvtNode *node, ItemFolder *parent,
1452 ItemGroup *parentGrp, ItemFolder *folderGrp )
1455 ItemFolder *itemFolder = NULL;
1456 ItemGroup *itemGParent = parentGrp;
1457 ItemFolder *itemGFolder = folderGrp;
1458 AddressCache *cache = abf->addressCache;
1460 if( node->type == TEMPNODE_ROOT ) {
1461 itemFolder = parent;
1463 else if( node->type == TEMPNODE_FOLDER ) {
1464 itemFolder = addritem_create_item_folder();
1465 addritem_folder_set_name( itemFolder, node->name );
1466 addrcache_id_folder( cache, itemFolder );
1467 addrcache_folder_add_folder( cache, parent, itemFolder );
1470 else if( node->type == TEMPNODE_GROUP ) {
1471 ItemGroup *itemGroup;
1474 /* Create a folder for group */
1475 fName = g_strdup_printf( "Cvt - %s", node->name );
1476 itemGFolder = addritem_create_item_folder();
1477 addritem_folder_set_name( itemGFolder, fName );
1478 addrcache_id_folder( cache, itemGFolder );
1479 addrcache_folder_add_folder( cache, parent, itemGFolder );
1482 /* Add group into folder */
1483 itemGroup = addritem_create_item_group();
1484 addritem_group_set_name( itemGroup, node->name );
1485 addrcache_id_group( cache, itemGroup );
1486 addrcache_folder_add_group( cache, itemGFolder, itemGroup );
1487 itemGParent = itemGroup;
1489 else if( node->type == TEMPNODE_ADDRESS ) {
1490 ItemPerson *itemPerson;
1491 ItemEMail *itemEMail;
1493 /* Create person and email objects */
1494 itemPerson = addritem_create_item_person();
1495 addritem_person_set_common_name( itemPerson, node->name );
1496 addrcache_id_person( cache, itemPerson );
1497 itemEMail = addritem_create_item_email();
1498 addritem_email_set_address( itemEMail, node->address );
1499 addritem_email_set_remarks( itemEMail, node->remarks );
1500 addrcache_id_email( cache, itemEMail );
1501 addrcache_person_add_email( cache, itemPerson, itemEMail );
1503 /* Add person into appropriate folder */
1505 addrcache_folder_add_person( cache, itemGFolder, itemPerson );
1508 addrcache_folder_add_person( cache, parent, itemPerson );
1511 /* Add email address only into group */
1513 addrcache_group_add_email( cache, parentGrp, itemEMail );
1519 AddressCvtNode *lNode = list->data;
1520 list = g_list_next( list );
1521 addrindex_process_node( abf, lNode, itemFolder, itemGParent, itemGFolder );
1526 * Process address book to specified file number.
1528 static gboolean addrindex_process_book( AddressIndex *addrIndex, XMLFile *file, gchar *displayName ) {
1529 gboolean retVal = FALSE;
1530 AddressBookFile *abf = NULL;
1531 AddressCvtNode *rootNode = NULL;
1532 gchar *newFile = NULL;
1533 GList *fileList = NULL;
1536 /* Setup root node */
1537 rootNode = g_new0( AddressCvtNode, 1 );
1538 rootNode->type = TEMPNODE_ROOT;
1539 rootNode->name = g_strdup( "root" );
1540 rootNode->list = NULL;
1541 addrindex_add_obj( file, rootNode );
1542 /* addrindex_print_node( rootNode, stdout ); */
1544 /* Create new address book */
1545 abf = addrbook_create_book();
1546 addrbook_set_name( abf, displayName );
1547 addrbook_set_path( abf, addrIndex->filePath );
1549 /* Determine next available file number */
1550 fileList = addrbook_get_bookfile_list( abf );
1552 fileNum = 1 + abf->maxValue;
1554 g_list_free( fileList );
1557 newFile = addrbook_gen_new_file_name( fileNum );
1559 addrbook_set_file( abf, newFile );
1562 addrindex_process_node( abf, rootNode, abf->addressCache->rootFolder, NULL, NULL );
1564 /* addrbook_dump_book( abf, stdout ); */
1565 addrbook_save_data( abf );
1566 addrIndex->retVal = abf->retVal;
1567 if( abf->retVal == MGU_SUCCESS ) retVal = TRUE;
1569 addrbook_free_book( abf );
1571 addrindex_free_node( rootNode );
1574 /* Create entries in address index */
1576 abf = addrbook_create_book();
1577 addrbook_set_name( abf, displayName );
1578 addrbook_set_path( abf, addrIndex->filePath );
1579 addrbook_set_file( abf, newFile );
1580 addrindex_index_add_datasource( addrIndex, ADDR_IF_BOOK, abf );
1587 * Process tree converting data.
1589 static void addrindex_convert_tree( AddressIndex *addrIndex, XMLFile *file ) {
1597 prev_level = file->level;
1598 xml_parse_next_tag( file );
1599 if (file->level < prev_level) return;
1601 xtag = xml_get_current_tag( file );
1602 /* printf( "tag : %d : %s\n", prev_level, xtag->tag ); */
1603 if( strcmp( xtag->tag, TAG_IF_OLD_COMMON ) == 0 ) {
1604 if( addrindex_process_book( addrIndex, file, DISP_OLD_COMMON ) ) {
1605 addrIndex->needsConversion = FALSE;
1606 addrIndex->wasConverted = TRUE;
1611 if( strcmp( xtag->tag, TAG_IF_OLD_PERSONAL ) == 0 ) {
1612 if( addrindex_process_book( addrIndex, file, DISP_OLD_PERSONAL ) ) {
1613 addrIndex->needsConversion = FALSE;
1614 addrIndex->wasConverted = TRUE;
1619 element = xml_get_element( file );
1620 attr = xml_get_current_tag_attr( file );
1621 /* show_attribs( attr ); */
1622 /* printf( "\ttag value : %s :\n", element ); */
1623 addrindex_consume_tree( file );
1627 static gint addrindex_convert_data( AddressIndex *addrIndex ) {
1628 XMLFile *file = NULL;
1631 fileSpec = g_strconcat( addrIndex->filePath, G_DIR_SEPARATOR_S, addrIndex->fileName, NULL );
1632 addrIndex->retVal = MGU_NO_FILE;
1633 file = xml_open_file( fileSpec );
1636 if( file == NULL ) {
1637 /* fprintf( stdout, " file '%s' does not exist.\n", addrIndex->fileName ); */
1638 return addrIndex->retVal;
1641 addrIndex->retVal = MGU_BAD_FORMAT;
1642 if( xml_get_dtd( file ) == 0 ) {
1643 if( xml_parse_next_tag( file ) == 0 ) {
1644 if( xml_compare_tag( file, TAG_ADDRESS_INDEX ) ) {
1645 addrindex_convert_tree( addrIndex, file );
1649 xml_close_file( file );
1650 return addrIndex->retVal;
1654 * Create a new address book file.
1656 static gboolean addrindex_create_new_book( AddressIndex *addrIndex, gchar *displayName ) {
1657 gboolean retVal = FALSE;
1658 AddressBookFile *abf = NULL;
1659 gchar *newFile = NULL;
1660 GList *fileList = NULL;
1663 /* Create new address book */
1664 abf = addrbook_create_book();
1665 addrbook_set_name( abf, displayName );
1666 addrbook_set_path( abf, addrIndex->filePath );
1668 /* Determine next available file number */
1669 fileList = addrbook_get_bookfile_list( abf );
1671 fileNum = 1 + abf->maxValue;
1673 g_list_free( fileList );
1676 newFile = addrbook_gen_new_file_name( fileNum );
1678 addrbook_set_file( abf, newFile );
1681 addrbook_save_data( abf );
1682 addrIndex->retVal = abf->retVal;
1683 if( abf->retVal == MGU_SUCCESS ) retVal = TRUE;
1684 addrbook_free_book( abf );
1687 /* Create entries in address index */
1689 abf = addrbook_create_book();
1690 addrbook_set_name( abf, displayName );
1691 addrbook_set_path( abf, addrIndex->filePath );
1692 addrbook_set_file( abf, newFile );
1693 addrindex_index_add_datasource( addrIndex, ADDR_IF_BOOK, abf );
1700 * Read data for address index performing a conversion if necesary.
1701 * Enter: addrIndex Address index object.
1702 * return: Status code, from addrIndex->retVal.
1703 * Note: New address book files will be created in directory specified by
1704 * addrIndex. Three files will be created, for the following:
1705 * "Common addresses"
1706 * "Personal addresses"
1707 * "Gathered addresses" - a new address book.
1709 gint addrindex_read_data( AddressIndex *addrIndex ) {
1710 g_return_val_if_fail( addrIndex != NULL, -1 );
1712 addrIndex->conversionError = FALSE;
1713 addrindex_read_file( addrIndex );
1714 if( addrIndex->retVal == MGU_SUCCESS ) {
1715 if( addrIndex->needsConversion ) {
1716 if( addrindex_convert_data( addrIndex ) == MGU_SUCCESS ) {
1717 addrIndex->conversionError = TRUE;
1720 addrIndex->conversionError = TRUE;
1723 addrIndex->dirtyFlag = TRUE;
1725 return addrIndex->retVal;
1729 * Create new address books for a new address index.
1730 * Enter: addrIndex Address index object.
1731 * return: Status code, from addrIndex->retVal.
1732 * Note: New address book files will be created in directory specified by
1733 * addrIndex. Three files will be created, for the following:
1734 * "Common addresses"
1735 * "Personal addresses"
1736 * "Gathered addresses" - a new address book.
1738 gint addrindex_create_new_books( AddressIndex *addrIndex ) {
1741 g_return_val_if_fail( addrIndex != NULL, -1 );
1743 flg = addrindex_create_new_book( addrIndex, DISP_NEW_COMMON );
1745 flg = addrindex_create_new_book( addrIndex, DISP_NEW_PERSONAL );
1746 addrIndex->dirtyFlag = TRUE;
1748 return addrIndex->retVal;
1751 /* **********************************************************************
1752 * New interface stuff.
1753 * ***********************************************************************
1757 * Return modified flag for specified data source.
1759 gboolean addrindex_ds_get_modify_flag( AddressDataSource *ds ) {
1760 gboolean retVal = FALSE;
1761 AddressInterface *iface;
1763 if( ds == NULL ) return retVal;
1764 iface = ds->interface;
1765 if( iface == NULL ) return retVal;
1766 if( iface->getModifyFlag ) {
1767 retVal = ( iface->getModifyFlag ) ( ds->rawDataSource );
1773 * Return accessed flag for specified data source.
1775 gboolean addrindex_ds_get_access_flag( AddressDataSource *ds ) {
1776 gboolean retVal = FALSE;
1777 AddressInterface *iface;
1779 if( ds == NULL ) return retVal;
1780 iface = ds->interface;
1781 if( iface == NULL ) return retVal;
1782 if( iface->getAccessFlag ) {
1783 retVal = ( iface->getAccessFlag ) ( ds->rawDataSource );
1789 * Return data read flag for specified data source.
1791 gboolean addrindex_ds_get_read_flag( AddressDataSource *ds ) {
1792 gboolean retVal = TRUE;
1793 AddressInterface *iface;
1795 if( ds == NULL ) return retVal;
1796 iface = ds->interface;
1797 if( iface == NULL ) return retVal;
1798 if( iface->getReadFlag ) {
1799 retVal = ( iface->getReadFlag ) ( ds->rawDataSource );
1805 * Return status code for specified data source.
1807 gint addrindex_ds_get_status_code( AddressDataSource *ds ) {
1808 gint retVal = MGU_SUCCESS;
1809 AddressInterface *iface;
1811 if( ds == NULL ) return retVal;
1812 iface = ds->interface;
1813 if( iface == NULL ) return retVal;
1814 if( iface->getStatusCode ) {
1815 retVal = ( iface->getStatusCode ) ( ds->rawDataSource );
1821 * Return data read flag for specified data source.
1823 gint addrindex_ds_read_data( AddressDataSource *ds ) {
1824 gint retVal = MGU_SUCCESS;
1825 AddressInterface *iface;
1827 if( ds == NULL ) return retVal;
1828 iface = ds->interface;
1829 if( iface == NULL ) return retVal;
1830 if( iface->getReadData ) {
1831 retVal = ( iface->getReadData ) ( ds->rawDataSource );
1837 * Return data read flag for specified data source.
1839 ItemFolder *addrindex_ds_get_root_folder( AddressDataSource *ds ) {
1840 ItemFolder *retVal = NULL;
1841 AddressInterface *iface;
1843 if( ds == NULL ) return retVal;
1844 iface = ds->interface;
1845 if( iface == NULL ) return retVal;
1846 if( iface->getRootFolder ) {
1847 retVal = ( iface->getRootFolder ) ( ds->rawDataSource );
1853 * Return list of folders for specified data source.
1855 GList *addrindex_ds_get_list_folder( AddressDataSource *ds ) {
1856 GList *retVal = FALSE;
1857 AddressInterface *iface;
1859 if( ds == NULL ) return retVal;
1860 iface = ds->interface;
1861 if( iface == NULL ) return retVal;
1862 if( iface->getListFolder ) {
1863 retVal = ( iface->getListFolder ) ( ds->rawDataSource );
1869 * Return list of persons in root folder for specified data source.
1871 GList *addrindex_ds_get_list_person( AddressDataSource *ds ) {
1872 GList *retVal = FALSE;
1873 AddressInterface *iface;
1875 if( ds == NULL ) return retVal;
1876 iface = ds->interface;
1877 if( iface == NULL ) return retVal;
1878 if( iface->getListPerson ) {
1879 retVal = ( iface->getListPerson ) ( ds->rawDataSource );
1885 * Return name for specified data source.
1887 gchar *addrindex_ds_get_name( AddressDataSource *ds ) {
1888 gchar *retVal = FALSE;
1889 AddressInterface *iface;
1891 if( ds == NULL ) return retVal;
1892 iface = ds->interface;
1893 if( iface == NULL ) return retVal;
1894 if( iface->getName ) {
1895 retVal = ( iface->getName ) ( ds->rawDataSource );
1901 * Set the access flag inside the data source.
1903 void addrindex_ds_set_access_flag( AddressDataSource *ds, gboolean *value ) {
1904 AddressInterface *iface;
1906 if( ds == NULL ) return;
1907 iface = ds->interface;
1908 if( iface == NULL ) return;
1909 if( iface->setAccessFlag ) {
1910 ( iface->setAccessFlag ) ( ds->rawDataSource, value );
1915 * Return read only flag for specified data source.
1917 gboolean addrindex_ds_get_readonly( AddressDataSource *ds ) {
1918 AddressInterface *iface;
1919 if( ds == NULL ) return TRUE;
1920 iface = ds->interface;
1921 if( iface == NULL ) return TRUE;
1922 return iface->readOnly;
1926 * Return list of all persons for specified data source.
1928 GList *addrindex_ds_get_all_persons( AddressDataSource *ds ) {
1929 GList *retVal = NULL;
1930 AddressInterface *iface;
1932 if( ds == NULL ) return retVal;
1933 iface = ds->interface;
1934 if( iface == NULL ) return retVal;
1935 if( iface->getAllPersons ) {
1936 retVal = ( iface->getAllPersons ) ( ds->rawDataSource );
1942 * Return list of all groups for specified data source.
1944 GList *addrindex_ds_get_all_groups( AddressDataSource *ds ) {
1945 GList *retVal = NULL;
1946 AddressInterface *iface;
1948 if( ds == NULL ) return retVal;
1949 iface = ds->interface;
1950 if( iface == NULL ) return retVal;
1951 if( iface->getAllGroups ) {
1952 retVal = ( iface->getAllGroups ) ( ds->rawDataSource );