diff options
Diffstat (limited to 'src/addrindex.c')
-rw-r--r-- | src/addrindex.c | 1892 |
1 files changed, 1892 insertions, 0 deletions
diff --git a/src/addrindex.c b/src/addrindex.c new file mode 100644 index 00000000..07d57711 --- /dev/null +++ b/src/addrindex.c @@ -0,0 +1,1892 @@ +/* + * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client + * Copyright (C) 2001 Match Grun + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * General functions for accessing address index file. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "defs.h" + +#include <glib.h> +#include <stdlib.h> + +#include "intl.h" +#include "mgutils.h" +#include "addritem.h" +#include "addrcache.h" +#include "addrbook.h" +#include "addrindex.h" +#include "xml.h" + +#ifndef DEV_STANDALONE +#include "prefs.h" +#include "codeconv.h" +#endif + +#include "vcard.h" + +#ifdef USE_JPILOT +#include "jpilot.h" +#endif + +#ifdef USE_LDAP +#include "syldap.h" +#endif + +#define TAG_ADDRESS_INDEX "addressbook" + +#define TAG_IF_ADDRESS_BOOK "book_list" +#define TAG_IF_VCARD "vcard_list" +#define TAG_IF_JPILOT "jpilot_list" +#define TAG_IF_LDAP "ldap_list" + +#define TAG_DS_ADDRESS_BOOK "book" +#define TAG_DS_VCARD "vcard" +#define TAG_DS_JPILOT "jpilot" +#define TAG_DS_LDAP "server" + +/* XML Attribute names */ +#define ATTAG_BOOK_NAME "name" +#define ATTAG_BOOK_FILE "file" + +#define ATTAG_VCARD_NAME "name" +#define ATTAG_VCARD_FILE "file" + +#define ATTAG_JPILOT_NAME "name" +#define ATTAG_JPILOT_FILE "file" +#define ATTAG_JPILOT_CUSTOM_1 "custom-1" +#define ATTAG_JPILOT_CUSTOM_2 "custom-2" +#define ATTAG_JPILOT_CUSTOM_3 "custom-3" +#define ATTAG_JPILOT_CUSTOM_4 "custom-4" +#define ATTAG_JPILOT_CUSTOM "custom-" + +#define ATTAG_LDAP_NAME "name" +#define ATTAG_LDAP_HOST "host" +#define ATTAG_LDAP_PORT "port" +#define ATTAG_LDAP_BASE_DN "base-dn" +#define ATTAG_LDAP_BIND_DN "bind-dn" +#define ATTAG_LDAP_BIND_PASS "bind-pass" +#define ATTAG_LDAP_CRITERIA "criteria" +#define ATTAG_LDAP_MAX_ENTRY "max-entry" +#define ATTAG_LDAP_TIMEOUT "timeout" + +#if 0 +N_("Common address") +N_("Personal address") +#endif + +#define DISP_NEW_COMMON _("Common address") +#define DISP_NEW_PERSONAL _("Personal address") + +/* Old address book */ +#define TAG_IF_OLD_COMMON "common_address" +#define TAG_IF_OLD_PERSONAL "personal_address" + +#define DISP_OLD_COMMON _("Common address") +#define DISP_OLD_PERSONAL _("Personal address") + +typedef struct _AddressIfAttr AddressIfAttrib; +struct _AddressIfAttr { + gchar *name; + gchar *value; +}; + +/* +* Build interface with default values. +*/ +static AddressInterface *addrindex_create_interface( gint type, gchar *name, gchar *tagIf, gchar *tagDS ) { + AddressInterface *iface = g_new0( AddressInterface, 1 ); + ADDRITEM_TYPE(iface) = ITEMTYPE_INTERFACE; + ADDRITEM_ID(iface) = NULL; + ADDRITEM_NAME(iface) = g_strdup( name ); + ADDRITEM_PARENT(iface) = NULL; + ADDRITEM_SUBTYPE(iface) = type; + iface->type = type; + iface->name = g_strdup( name ); + iface->listTag = g_strdup( tagIf ); + iface->itemTag = g_strdup( tagDS ); + iface->legacyFlag = FALSE; + iface->haveLibrary = TRUE; + iface->useInterface = TRUE; + iface->readOnly = TRUE; + iface->getAccessFlag = NULL; + iface->getModifyFlag = NULL; + iface->getReadFlag = NULL; + iface->getStatusCode = NULL; + iface->getReadData = NULL; + iface->getRootFolder = NULL; + iface->getListFolder = NULL; + iface->getListPerson = NULL; + iface->getAllPersons = NULL; + iface->getAllGroups = NULL; + iface->getName = NULL; + iface->listSource = NULL; + return iface; +} + +/* +* Build table of interfaces. +*/ +static void addrindex_build_if_list( AddressIndex *addrIndex ) { + AddressInterface *iface; + + iface = addrindex_create_interface( ADDR_IF_BOOK, "Address Book", TAG_IF_ADDRESS_BOOK, TAG_DS_ADDRESS_BOOK ); + iface->readOnly = FALSE; + iface->getModifyFlag = ( void * ) addrbook_get_modified; + iface->getAccessFlag = ( void * ) addrbook_get_accessed; + iface->getReadFlag = ( void * ) addrbook_get_read_flag; + iface->getStatusCode = ( void * ) addrbook_get_status; + iface->getReadData = ( void * ) addrbook_read_data; + iface->getRootFolder = ( void * ) addrbook_get_root_folder; + iface->getListFolder = ( void * ) addrbook_get_list_folder; + iface->getListPerson = ( void * ) addrbook_get_list_person; + iface->getAllPersons = ( void * ) addrbook_get_all_persons; + iface->getName = ( void * ) addrbook_get_name; + iface->setAccessFlag = ( void * ) addrbook_set_accessed; + addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface ); + ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex); + + iface = addrindex_create_interface( ADDR_IF_VCARD, "vCard", TAG_IF_VCARD, TAG_DS_VCARD ); + iface->getModifyFlag = ( void * ) vcard_get_modified; + iface->getAccessFlag = ( void * ) vcard_get_accessed; + iface->getReadFlag = ( void * ) vcard_get_read_flag; + iface->getStatusCode = ( void * ) vcard_get_status; + iface->getReadData = ( void * ) vcard_read_data; + iface->getRootFolder = ( void * ) vcard_get_root_folder; + iface->getListFolder = ( void * ) vcard_get_list_folder; + iface->getListPerson = ( void * ) vcard_get_list_person; + iface->getAllPersons = ( void * ) vcard_get_all_persons; + iface->getName = ( void * ) vcard_get_name; + iface->setAccessFlag = ( void * ) vcard_set_accessed; + addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface ); + ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex); + + iface = addrindex_create_interface( ADDR_IF_JPILOT, "JPilot", TAG_IF_JPILOT, TAG_DS_JPILOT ); +#ifdef USE_JPILOT + /* iface->haveLibrary = jpilot_test_pilot_lib(); */ + iface->haveLibrary = TRUE; + iface->useInterface = iface->haveLibrary; + iface->getModifyFlag = ( void * ) jpilot_get_modified; + iface->getAccessFlag = ( void * ) jpilot_get_accessed; + iface->getReadFlag = ( void * ) jpilot_get_read_flag; + iface->getStatusCode = ( void * ) jpilot_get_status; + iface->getReadData = ( void * ) jpilot_read_data; + iface->getRootFolder = ( void * ) jpilot_get_root_folder; + iface->getListFolder = ( void * ) jpilot_get_list_folder; + iface->getListPerson = ( void * ) jpilot_get_list_person; + iface->getAllPersons = ( void * ) jpilot_get_all_persons; + iface->getName = ( void * ) jpilot_get_name; + iface->setAccessFlag = ( void * ) jpilot_set_accessed; +#else + iface->useInterface = FALSE; + iface->haveLibrary = FALSE; +#endif + addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface ); + ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex); + + iface = addrindex_create_interface( ADDR_IF_LDAP, "LDAP", TAG_IF_LDAP, TAG_DS_LDAP ); +#ifdef USE_LDAP + /* iface->haveLibrary = syldap_test_ldap_lib(); */ + iface->haveLibrary = TRUE; + iface->useInterface = iface->haveLibrary; + iface->getAccessFlag = ( void * ) syldap_get_accessed; + /* iface->getModifyFlag = ( void * ) syldap_get_modified; */ + /* iface->getReadFlag = ( void * ) syldap_get_read_flag; */ + iface->getStatusCode = ( void * ) syldap_get_status; + iface->getReadData = ( void * ) syldap_read_data; + iface->getRootFolder = ( void * ) syldap_get_root_folder; + iface->getListFolder = ( void * ) syldap_get_list_folder; + iface->getListPerson = ( void * ) syldap_get_list_person; + iface->getName = ( void * ) syldap_get_name; + iface->setAccessFlag = ( void * ) syldap_set_accessed; +#else + iface->useInterface = FALSE; + iface->haveLibrary = FALSE; +#endif + addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface ); + ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex); + + /* Two old legacy data sources */ + iface = addrindex_create_interface( ADDR_IF_COMMON, "Old Address - common", TAG_IF_OLD_COMMON, NULL ); + iface->legacyFlag = TRUE; + addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface ); + ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex); + + iface = addrindex_create_interface( ADDR_IF_COMMON, "Old Address - personal", TAG_IF_OLD_PERSONAL, NULL ); + iface->legacyFlag = TRUE; + addrIndex->interfaceList = g_list_append( addrIndex->interfaceList, iface ); + ADDRITEM_PARENT(iface) = ADDRITEM_OBJECT(addrIndex); + +} + +/* +* Free name-value pairs. +*/ +static void addrindex_free_attributes( GList *list ) { + GList *node = list; + while( node ) { + AddressIfAttrib *nv = node->data; + g_free( nv->name ); nv->name = NULL; + g_free( nv->value ); nv->value = NULL; + g_free( nv ); + node->data = NULL; + node = g_list_next( node ); + } + g_list_free( list ); +} + +/* +* Free up data source. +*/ +void addrindex_free_datasource( AddressIndex *addrIndex, AddressDataSource *ds ) { + AddressInterface *iface = NULL; + g_return_if_fail( addrIndex != NULL ); + g_return_if_fail( ds != NULL ); + + if( ds->interface == NULL ) { + iface = addrindex_get_interface( addrIndex, ds->type ); + } + if( iface == NULL ) return; + + if( iface->useInterface ) { + if( iface->type == ADDR_IF_BOOK ) { + AddressBookFile *abf = ds->rawDataSource; + if( abf ) { + addrbook_free_book( abf ); + } + } + else if( iface->type == ADDR_IF_VCARD ) { + VCardFile *vcf = ds->rawDataSource; + if( vcf ) { + vcard_free( vcf ); + } + } +#ifdef USE_JPILOT + else if( iface->type == ADDR_IF_JPILOT ) { + JPilotFile *jpf = ds->rawDataSource; + if( jpf ) { + jpilot_free( jpf ); + } + } +#endif +#ifdef USE_LDAP + else if( iface->type == ADDR_IF_LDAP ) { + SyldapServer *server = ds->rawDataSource; + if( server ) { + syldap_free( server ); + } + } +#endif + } + else { + GList *list = ds->rawDataSource; + addrindex_free_attributes( list ); + } + + g_free( ADDRITEM_ID(addrIndex) ); + g_free( ADDRITEM_NAME(addrIndex) ); + + ADDRITEM_TYPE(addrIndex) = ITEMTYPE_NONE; + ADDRITEM_ID(addrIndex) = NULL; + ADDRITEM_NAME(addrIndex) = NULL; + ADDRITEM_PARENT(addrIndex) = NULL; + ADDRITEM_SUBTYPE(addrIndex) = 0; + ds->type = ADDR_IF_NONE; + ds->rawDataSource = NULL; + ds->interface = NULL; + + ds->type = ADDR_IF_NONE; + ds->rawDataSource = NULL; + ds->interface = NULL; + g_free( ds ); +} + +static void addrindex_free_all_datasources( AddressInterface *iface ) { + GList *node = iface->listSource; + while( node ) { + AddressDataSource *ds = node->data; + if( iface->useInterface ) { + if( iface->type == ADDR_IF_BOOK ) { + AddressBookFile *abf = ds->rawDataSource; + if( abf ) { + addrbook_free_book( abf ); + } + } + else if( iface->type == ADDR_IF_VCARD ) { + VCardFile *vcf = ds->rawDataSource; + if( vcf ) { + vcard_free( vcf ); + } + } +#ifdef USE_JPILOT + else if( iface->type == ADDR_IF_JPILOT ) { + JPilotFile *jpf = ds->rawDataSource; + if( jpf ) { + jpilot_free( jpf ); + } + } +#endif +#ifdef USE_LDAP + else if( iface->type == ADDR_IF_LDAP ) { + SyldapServer *server = ds->rawDataSource; + if( server ) { + syldap_free( server ); + } + } +#endif + } + else { + GList *list = ds->rawDataSource; + addrindex_free_attributes( list ); + } + + ds->type = ADDR_IF_NONE; + ds->rawDataSource = NULL; + ds->interface = NULL; + g_free( ds ); + node->data = NULL; + node = g_list_next( node ); + } +} + +static void addrindex_free_interface( AddressInterface *iface ) { + addrindex_free_all_datasources( iface ); + + g_free( ADDRITEM_ID(iface) ); + g_free( ADDRITEM_NAME(iface) ); + g_free( iface->name ); + g_free( iface->listTag ); + g_free( iface->itemTag ); + + ADDRITEM_TYPE(iface) = ITEMTYPE_NONE; + ADDRITEM_ID(iface) = NULL; + ADDRITEM_NAME(iface) = NULL; + ADDRITEM_PARENT(iface) = NULL; + ADDRITEM_SUBTYPE(iface) = 0; + iface->type = ADDR_IF_NONE; + iface->name = NULL; + iface->listTag = NULL; + iface->itemTag = NULL; + iface->legacyFlag = FALSE; + iface->useInterface = FALSE; + iface->haveLibrary = FALSE; + + g_list_free( iface->listSource ); + iface->listSource = NULL; +} + +/* +* Create new object. +*/ +AddressIndex *addrindex_create_index() { + AddressIndex *addrIndex = g_new0( AddressIndex, 1 ); + + ADDRITEM_TYPE(addrIndex) = ITEMTYPE_INDEX; + ADDRITEM_ID(addrIndex) = NULL; + ADDRITEM_NAME(addrIndex) = g_strdup( "Address Index" ); + ADDRITEM_PARENT(addrIndex) = NULL; + ADDRITEM_SUBTYPE(addrIndex) = 0; + addrIndex->filePath = NULL; + addrIndex->fileName = NULL; + addrIndex->retVal = MGU_SUCCESS; + addrIndex->needsConversion = FALSE; + addrIndex->wasConverted = FALSE; + addrIndex->conversionError = FALSE; + addrIndex->interfaceList = NULL; + addrIndex->lastType = ADDR_IF_NONE; + addrIndex->dirtyFlag = FALSE; + addrindex_build_if_list( addrIndex ); + return addrIndex; +} + +/* +* Specify file to be used. +*/ +void addrindex_set_file_path( AddressIndex *addrIndex, const gchar *value ) { + g_return_if_fail( addrIndex != NULL ); + addrIndex->filePath = mgu_replace_string( addrIndex->filePath, value ); +} +void addrindex_set_file_name( AddressIndex *addrIndex, const gchar *value ) { + g_return_if_fail( addrIndex != NULL ); + addrIndex->fileName = mgu_replace_string( addrIndex->fileName, value ); +} +void addrindex_set_dirty( AddressIndex *addrIndex, const gboolean value ) { + g_return_if_fail( addrIndex != NULL ); + addrIndex->dirtyFlag = value; +} + +/* +* Return list of interfaces. +*/ +GList *addrindex_get_interface_list( AddressIndex *addrIndex ) { + g_return_val_if_fail( addrIndex != NULL, NULL ); + return addrIndex->interfaceList; +} + +/* +* Free up object. +*/ +void addrindex_free_index( AddressIndex *addrIndex ) { + GList *node; + + g_return_if_fail( addrIndex != NULL ); + + g_free( ADDRITEM_ID(addrIndex) ); + g_free( ADDRITEM_NAME(addrIndex) ); + g_free( addrIndex->filePath ); + g_free( addrIndex->fileName ); + ADDRITEM_TYPE(addrIndex) = ITEMTYPE_NONE; + ADDRITEM_ID(addrIndex) = NULL; + ADDRITEM_NAME(addrIndex) = NULL; + ADDRITEM_PARENT(addrIndex) = NULL; + ADDRITEM_SUBTYPE(addrIndex) = 0; + addrIndex->filePath = NULL; + addrIndex->fileName = NULL; + addrIndex->retVal = MGU_SUCCESS; + addrIndex->needsConversion = FALSE; + addrIndex->wasConverted = FALSE; + addrIndex->conversionError = FALSE; + addrIndex->lastType = ADDR_IF_NONE; + addrIndex->dirtyFlag = FALSE; + node = addrIndex->interfaceList; + while( node ) { + AddressInterface *iface = node->data; + addrindex_free_interface( iface ); + node = g_list_next( node ); + } + g_list_free( addrIndex->interfaceList ); + addrIndex->interfaceList = NULL; + g_free( addrIndex ); +} + +/* +* Print address index. +*/ +void addrindex_print_index( AddressIndex *addrIndex, FILE *stream ) { + g_return_if_fail( addrIndex != NULL ); + fprintf( stream, "AddressIndex:\n" ); + fprintf( stream, "\tfile path: '%s'\n", addrIndex->filePath ); + fprintf( stream, "\tfile name: '%s'\n", addrIndex->fileName ); + fprintf( stream, "\t status: %d : '%s'\n", addrIndex->retVal, mgu_error2string( addrIndex->retVal ) ); + fprintf( stream, "\tconverted: '%s'\n", addrIndex->wasConverted ? "yes" : "no" ); + fprintf( stream, "\tcvt error: '%s'\n", addrIndex->conversionError ? "yes" : "no" ); + fprintf( stream, "\t---\n" ); +} + +/* +* Retrieve specified interface from index. +*/ +AddressInterface *addrindex_get_interface( AddressIndex *addrIndex, AddressIfType ifType ) { + AddressInterface *retVal = NULL; + GList *node; + + g_return_val_if_fail( addrIndex != NULL, NULL ); + + node = addrIndex->interfaceList; + while( node ) { + AddressInterface *iface = node->data; + node = g_list_next( node ); + if( iface->type == ifType ) { + retVal = iface; + break; + } + } + return retVal; +} + +AddressDataSource *addrindex_create_datasource() { + AddressDataSource *ds = NULL; + ds = g_new0( AddressDataSource, 1 ); + ADDRITEM_TYPE(ds) = ITEMTYPE_DATASOURCE; + ADDRITEM_ID(ds) = NULL; + ADDRITEM_NAME(ds) = NULL; + ADDRITEM_PARENT(ds) = NULL; + ADDRITEM_SUBTYPE(ds) = 0; + ds->type = ADDR_IF_NONE; + ds->rawDataSource = NULL; + ds->interface = NULL; + return ds; +} + +/* +* Add data source to index. +* Enter: addrIndex Address index object. +* ifType Interface type to add. +* dataSource Actual data source to add. +* Return: TRUE if data source was added. +* Note: The raw data object (for example, AddressBookFile or VCardFile object) should be +* supplied as the dataSource argument. +*/ +AddressDataSource *addrindex_index_add_datasource( AddressIndex *addrIndex, AddressIfType ifType, gpointer dataSource ) { + AddressInterface *iface; + AddressDataSource *ds = NULL; + + g_return_val_if_fail( addrIndex != NULL, NULL ); + g_return_val_if_fail( dataSource != NULL, NULL ); + + iface = addrindex_get_interface( addrIndex, ifType ); + if( iface ) { + ds = addrindex_create_datasource(); + ADDRITEM_PARENT(ds) = ADDRITEM_OBJECT(iface); + ds->type = ifType; + ds->rawDataSource = dataSource; + ds->interface = iface; + iface->listSource = g_list_append( iface->listSource, ds ); + addrIndex->dirtyFlag = TRUE; + } + return ds; +} + +/* +* Remove data source from index. +* Enter: addrIndex Address index object. +* dataSource Data source to remove. +* Return: Data source if removed, or NULL if data source was not found in +* index. Note the this object must still be freed. +*/ +AddressDataSource *addrindex_index_remove_datasource( AddressIndex *addrIndex, AddressDataSource *dataSource ) { + AddressDataSource *retVal = FALSE; + AddressInterface *iface; + + g_return_val_if_fail( addrIndex != NULL, NULL ); + g_return_val_if_fail( dataSource != NULL, NULL ); + + iface = addrindex_get_interface( addrIndex, dataSource->type ); + if( iface ) { + iface->listSource = g_list_remove( iface->listSource, dataSource ); + addrIndex->dirtyFlag = TRUE; + dataSource->interface = NULL; + retVal = dataSource; + } + return retVal; +} + +static AddressInterface *addrindex_tag_get_interface( AddressIndex *addrIndex, gchar *tag, AddressIfType ifType ) { + AddressInterface *retVal = NULL; + GList *node = addrIndex->interfaceList; + + while( node ) { + AddressInterface *iface = node->data; + node = g_list_next( node ); + if( tag ) { + if( strcmp( iface->listTag, tag ) == 0 ) { + retVal = iface; + break; + } + } + else { + if( iface->type == ifType ) { + retVal = iface; + break; + } + } + } + return retVal; +} + +static AddressInterface *addrindex_tag_get_datasource( AddressIndex *addrIndex, AddressIfType ifType, gchar *tag ) { + AddressInterface *retVal = NULL; + GList *node = addrIndex->interfaceList; + + while( node ) { + AddressInterface *iface = node->data; + node = g_list_next( node ); + if( iface->type == ifType && iface->itemTag ) { + if( strcmp( iface->itemTag, tag ) == 0 ) { + retVal = iface; + break; + } + } + } + return retVal; +} + +/* ********************************************************************** +* Interface XML parsing functions. +* *********************************************************************** +*/ +#if 0 +static void show_attribs( GList *attr ) { + while( attr ) { + gchar *name = ((XMLAttr *)attr->data)->name; + gchar *value = ((XMLAttr *)attr->data)->value; + printf( "\tattr value : %s :%s:\n", name, value ); + attr = g_list_next( attr ); + } + printf( "\t---\n" ); +} +#endif + +static void addrindex_write_elem_s( FILE *fp, gint lvl, gchar *name ) { + gint i; + for( i = 0; i < lvl; i++ ) fputs( " ", fp ); + fputs( "<", fp ); + fputs( name, fp ); +} + +static void addrindex_write_elem_e( FILE *fp, gint lvl, gchar *name ) { + gint i; + for( i = 0; i < lvl; i++ ) fputs( " ", fp ); + fputs( "</", fp ); + fputs( name, fp ); + fputs( ">\n", fp ); +} + +static void addrindex_write_attr( FILE *fp, gchar *name, gchar *value ) { + fputs( " ", fp ); + fputs( name, fp ); + fputs( "=\"", fp ); + xml_file_put_escape_str( fp, value ); + fputs( "\"", fp ); +} + +/* +* Return list of name-value pairs. +*/ +static GList *addrindex_read_attributes( XMLFile *file ) { + GList *list = NULL; + AddressIfAttrib *nv; + GList *attr; + gchar *name; + gchar *value; + + attr = xml_get_current_tag_attr( file ); + while( attr ) { + name = ((XMLAttr *)attr->data)->name; + value = ((XMLAttr *)attr->data)->value; + nv = g_new0( AddressIfAttrib, 1 ); + nv->name = g_strdup( name ); + nv->value = g_strdup( value ); + list = g_list_append( list, nv ); + attr = g_list_next( attr ); + } + return list; +} + +/* +* Output name-value pairs. +*/ +static void addrindex_write_attributes( FILE *fp, gchar *tag, GList *list, gint lvl ) { + GList *node; + AddressIfAttrib *nv; + if( list ) { + addrindex_write_elem_s( fp, lvl, tag ); + node = list; + while( node ) { + nv = node->data; + addrindex_write_attr( fp, nv->name, nv->value ); + node = g_list_next( node ); + } + fputs(" />\n", fp); + } +} + +#if 0 +static void addrindex_print_attributes( GList *list, FILE *stream ) { + GList *node = list; + while( node ) { + AddressIfAttrib *nv = node->data; + fprintf( stream, "%s : %s\n", nv->name, nv->value ); + node = g_list_next( node ); + } +} +#endif + +static AddressDataSource *addrindex_parse_book( XMLFile *file ) { + AddressDataSource *ds = g_new0( AddressDataSource, 1 ); + AddressBookFile *abf; + GList *attr; + + abf = addrbook_create_book(); + attr = xml_get_current_tag_attr( file ); + while( attr ) { + gchar *name = ((XMLAttr *)attr->data)->name; + gchar *value = ((XMLAttr *)attr->data)->value; + if( strcmp( name, ATTAG_BOOK_NAME ) == 0 ) { + addrbook_set_name( abf, value ); + } + else if( strcmp( name, ATTAG_BOOK_FILE ) == 0) { + addrbook_set_file( abf, value ); + } + attr = g_list_next( attr ); + } + ds->rawDataSource = abf; + return ds; +} + +static void addrindex_write_book( FILE *fp, AddressDataSource *ds, gint lvl ) { + AddressBookFile *abf = ds->rawDataSource; + if( abf ) { + addrindex_write_elem_s( fp, lvl, TAG_DS_ADDRESS_BOOK ); + addrindex_write_attr( fp, ATTAG_BOOK_NAME, abf->name ); + addrindex_write_attr( fp, ATTAG_BOOK_FILE, abf->fileName ); + fputs( " />\n", fp ); + } +} + +static AddressDataSource *addrindex_parse_vcard( XMLFile *file ) { + AddressDataSource *ds = g_new0( AddressDataSource, 1 ); + VCardFile *vcf; + GList *attr; + + vcf = vcard_create(); + attr = xml_get_current_tag_attr( file ); + while( attr ) { + gchar *name = ((XMLAttr *)attr->data)->name; + gchar *value = ((XMLAttr *)attr->data)->value; + if( strcmp( name, ATTAG_VCARD_NAME ) == 0 ) { + vcard_set_name( vcf, value ); + } + else if( strcmp( name, ATTAG_VCARD_FILE ) == 0) { + vcard_set_file( vcf, value ); + } + attr = g_list_next( attr ); + } + ds->rawDataSource = vcf; + return ds; +} + +static void addrindex_write_vcard( FILE *fp, AddressDataSource *ds, gint lvl ) { + VCardFile *vcf = ds->rawDataSource; + if( vcf ) { + addrindex_write_elem_s( fp, lvl, TAG_DS_VCARD ); + addrindex_write_attr( fp, ATTAG_VCARD_NAME, vcf->name ); + addrindex_write_attr( fp, ATTAG_VCARD_FILE, vcf->path ); + fputs( " />\n", fp ); + } +} + +#ifdef USE_JPILOT +static AddressDataSource *addrindex_parse_jpilot( XMLFile *file ) { + AddressDataSource *ds = g_new0( AddressDataSource, 1 ); + JPilotFile *jpf; + GList *attr; + + jpf = jpilot_create(); + attr = xml_get_current_tag_attr( file ); + while( attr ) { + gchar *name = ((XMLAttr *)attr->data)->name; + gchar *value = ((XMLAttr *)attr->data)->value; + if( strcmp( name, ATTAG_JPILOT_NAME ) == 0 ) { + jpilot_set_name( jpf, value ); + } + else if( strcmp( name, ATTAG_JPILOT_FILE ) == 0 ) { + jpilot_set_file( jpf, value ); + } + else if( strcmp( name, ATTAG_JPILOT_CUSTOM_1 ) == 0 ) { + jpilot_add_custom_label( jpf, value ); + } + else if( strcmp( name, ATTAG_JPILOT_CUSTOM_2 ) == 0 ) { + jpilot_add_custom_label( jpf, value ); + } + else if( strcmp( name, ATTAG_JPILOT_CUSTOM_3 ) == 0 ) { + jpilot_add_custom_label( jpf, value ); + } + else if( strcmp( name, ATTAG_JPILOT_CUSTOM_4 ) == 0 ) { + jpilot_add_custom_label( jpf, value ); + } + attr = g_list_next( attr ); + } + ds->rawDataSource = jpf; + return ds; +} + +static void addrindex_write_jpilot( FILE *fp,AddressDataSource *ds, gint lvl ) { + JPilotFile *jpf = ds->rawDataSource; + if( jpf ) { + gint ind; + GList *node; + GList *customLbl = jpilot_get_custom_labels( jpf ); + addrindex_write_elem_s( fp, lvl, TAG_DS_JPILOT ); + addrindex_write_attr( fp, ATTAG_JPILOT_NAME, jpf->name ); + addrindex_write_attr( fp, ATTAG_JPILOT_FILE, jpf->path ); + node = customLbl; + ind = 1; + while( node ) { + gchar name[256]; + sprintf( name, "%s%d", ATTAG_JPILOT_CUSTOM, ind ); + addrindex_write_attr( fp, name, node->data ); + ind++; + node = g_list_next( node ); + } + fputs( " />\n", fp ); + } +} +#else +/* Just read/write name-value pairs */ +static AddressDataSource *addrindex_parse_jpilot( XMLFile *file ) { + AddressDataSource *ds = g_new0( AddressDataSource, 1 ); + GList *list = addrindex_read_attributes( file ); + ds->rawDataSource = list; + return ds; +} + +static void addrindex_write_jpilot( FILE *fp, AddressDataSource *ds, gint lvl ) { + GList *list = ds->rawDataSource; + if( list ) { + addrindex_write_attributes( fp, TAG_DS_JPILOT, list, lvl ); + } +} +#endif + +#ifdef USE_LDAP +static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) { + AddressDataSource *ds = g_new0( AddressDataSource, 1 ); + SyldapServer *server; + GList *attr; + + server = syldap_create(); + attr = xml_get_current_tag_attr( file ); + while( attr ) { + gchar *name = ((XMLAttr *)attr->data)->name; + gchar *value = ((XMLAttr *)attr->data)->value; + gint ivalue = atoi( value ); + if( strcmp( name, ATTAG_LDAP_NAME ) == 0 ) { + syldap_set_name( server, value ); + } + else if( strcmp( name, ATTAG_LDAP_HOST ) == 0 ) { + syldap_set_host( server, value ); + } + else if( strcmp( name, ATTAG_LDAP_PORT ) == 0 ) { + syldap_set_port( server, ivalue ); + } + else if( strcmp( name, ATTAG_LDAP_BASE_DN ) == 0 ) { + syldap_set_base_dn( server, value ); + } + else if( strcmp( name, ATTAG_LDAP_BIND_DN ) == 0 ) { + syldap_set_bind_dn( server, value ); + } + else if( strcmp( name, ATTAG_LDAP_BIND_PASS ) == 0 ) { + syldap_set_bind_password( server, value ); + } + else if( strcmp( name, ATTAG_LDAP_CRITERIA ) == 0 ) { + syldap_set_search_criteria( server, value ); + } + else if( strcmp( name, ATTAG_LDAP_MAX_ENTRY ) == 0 ) { + syldap_set_max_entries( server, ivalue ); + } + else if( strcmp( name, ATTAG_LDAP_TIMEOUT ) == 0 ) { + syldap_set_timeout( server, ivalue ); + } + attr = g_list_next( attr ); + } + + ds->rawDataSource = server; + return ds; +} + +static void addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) { + SyldapServer *server = ds->rawDataSource; + if( server ) { + gchar value[256]; + + addrindex_write_elem_s( fp, lvl, TAG_DS_LDAP ); + addrindex_write_attr( fp, ATTAG_LDAP_NAME, server->name ); + addrindex_write_attr( fp, ATTAG_LDAP_HOST, server->hostName ); + + sprintf( value, "%d", server->port ); + addrindex_write_attr( fp, ATTAG_LDAP_PORT, value ); + + addrindex_write_attr( fp, ATTAG_LDAP_BASE_DN, server->baseDN ); + addrindex_write_attr( fp, ATTAG_LDAP_BIND_DN, server->bindDN ); + addrindex_write_attr( fp, ATTAG_LDAP_BIND_PASS, server->bindPass ); + addrindex_write_attr( fp, ATTAG_LDAP_CRITERIA, server->searchCriteria ); + + sprintf( value, "%d", server->maxEntries ); + addrindex_write_attr( fp, ATTAG_LDAP_MAX_ENTRY, value ); + sprintf( value, "%d", server->timeOut ); + addrindex_write_attr( fp, ATTAG_LDAP_TIMEOUT, value ); + + fputs(" />\n", fp); + } +} +#else +/* Just read/write name-value pairs */ +static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) { + AddressDataSource *ds = g_new0( AddressDataSource, 1 ); + GList *list = addrindex_read_attributes( file ); + ds->rawDataSource = list; + return ds; +} + +static void addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) { + GList *list = ds->rawDataSource; + if( list ) { + addrindex_write_attributes( fp, TAG_DS_LDAP, list, lvl ); + } +} +#endif + +/* ********************************************************************** +* Address index I/O functions. +* *********************************************************************** +*/ +static void addrindex_read_index( AddressIndex *addrIndex, XMLFile *file ) { + guint prev_level; + /* gchar *element; */ + /* GList *attr; */ + XMLTag *xtag; + AddressInterface *iface = NULL, *dsIFace = NULL; + AddressDataSource *ds; + + for (;;) { + prev_level = file->level; + xml_parse_next_tag( file ); + if( file->level < prev_level ) return; + + xtag = xml_get_current_tag( file ); + /* printf( "tag : %s\n", xtag->tag ); */ + + iface = addrindex_tag_get_interface( addrIndex, xtag->tag, ADDR_IF_NONE ); + if( iface ) { + addrIndex->lastType = iface->type; + if( iface->legacyFlag ) addrIndex->needsConversion = TRUE; + /* printf( "found : %s\n", iface->name ); */ + } + else { + dsIFace = addrindex_tag_get_datasource( addrIndex, addrIndex->lastType, xtag->tag ); + if( dsIFace ) { + /* Add data source to list */ + /* printf( "\tdata source: %s\n", dsIFace->name ); */ + ds = NULL; + if( addrIndex->lastType == ADDR_IF_BOOK ) { + ds = addrindex_parse_book( file ); + if( ds->rawDataSource ) { + addrbook_set_path( ds->rawDataSource, addrIndex->filePath ); + /* addrbook_print_book( ds->rawDataSource, stdout ); */ + } + } + else if( addrIndex->lastType == ADDR_IF_VCARD ) { + ds = addrindex_parse_vcard( file ); + /* if( ds->rawDataSource ) { */ + /* vcard_print_file( ds->rawDataSource, stdout ); */ + /* } */ + } + else if( addrIndex->lastType == ADDR_IF_JPILOT ) { + ds = addrindex_parse_jpilot( file ); + /* + if( ds->rawDataSource ) { + jpilot_print_file( ds->rawDataSource, stdout ); + // addrindex_print_attributes( ds->rawDataSource, stdout ); + } + */ + } + else if( addrIndex->lastType == ADDR_IF_LDAP ) { + ds = addrindex_parse_ldap( file ); + /* + if( ds->rawDataSource ) { + syldap_print_data( ds->rawDataSource, stdout ); + // addrindex_print_attributes( ds->rawDataSource, stdout ); + } + */ + } + if( ds ) { + ds->type = addrIndex->lastType; + ds->interface = dsIFace; + dsIFace->listSource = g_list_append( dsIFace->listSource, ds ); + } + /* printf( "=============================\n\n" ); */ + } + } + /* + element = xml_get_element( file ); + attr = xml_get_current_tag_attr( file ); + if( _interfaceLast_ && ! _interfaceLast_->legacyFlag ) { + show_attribs( attr ); + printf( "\ttag value : %s :\n", element ); + } + */ + addrindex_read_index( addrIndex, file ); + } +} + +static gint addrindex_read_file( AddressIndex *addrIndex ) { + XMLFile *file = NULL; + gchar *fileSpec = NULL; + + g_return_val_if_fail( addrIndex != NULL, -1 ); + + fileSpec = g_strconcat( addrIndex->filePath, G_DIR_SEPARATOR_S, addrIndex->fileName, NULL ); + addrIndex->retVal = MGU_NO_FILE; + file = xml_open_file( fileSpec ); + g_free( fileSpec ); + + if( file == NULL ) { + /* fprintf( stdout, " file '%s' does not exist.\n", addrIndex->fileName ); */ + return addrIndex->retVal; + } + + addrIndex->retVal = MGU_BAD_FORMAT; + if( xml_get_dtd( file ) == 0 ) { + if( xml_parse_next_tag( file ) == 0 ) { + if( xml_compare_tag( file, TAG_ADDRESS_INDEX ) ) { + addrindex_read_index( addrIndex, file ); + addrIndex->retVal = MGU_SUCCESS; + } + } + } + xml_close_file( file ); + + return addrIndex->retVal; +} + +static void addrindex_write_index( AddressIndex *addrIndex, FILE *fp ) { + GList *nodeIF, *nodeDS; + gint lvlList = 1; + gint lvlItem = 1 + lvlList; + + nodeIF = addrIndex->interfaceList; + while( nodeIF ) { + AddressInterface *iface = nodeIF->data; + if( ! iface->legacyFlag ) { + nodeDS = iface->listSource; + addrindex_write_elem_s( fp, lvlList, iface->listTag ); + fputs( ">\n", fp ); + while( nodeDS ) { + AddressDataSource *ds = nodeDS->data; + if( ds ) { + if( iface->type == ADDR_IF_BOOK ) { + addrindex_write_book( fp, ds, lvlItem ); + } + if( iface->type == ADDR_IF_VCARD ) { + addrindex_write_vcard( fp, ds, lvlItem ); + } + if( iface->type == ADDR_IF_JPILOT ) { + addrindex_write_jpilot( fp, ds, lvlItem ); + } + if( iface->type == ADDR_IF_LDAP ) { + addrindex_write_ldap( fp, ds, lvlItem ); + } + } + nodeDS = g_list_next( nodeDS ); + } + addrindex_write_elem_e( fp, lvlList, iface->listTag ); + } + nodeIF = g_list_next( nodeIF ); + } +} + +/* +* Write data to specified file. +* Enter: addrIndex Address index object. +* newFile New file name. +* return: Status code, from addrIndex->retVal. +* Note: File will be created in directory specified by addrIndex. +*/ +gint addrindex_write_to( AddressIndex *addrIndex, const gchar *newFile ) { + FILE *fp; + gchar *fileSpec; +#ifndef DEV_STANDALONE + PrefFile *pfile; +#endif + + g_return_val_if_fail( addrIndex != NULL, -1 ); + + fileSpec = g_strconcat( addrIndex->filePath, G_DIR_SEPARATOR_S, newFile, NULL ); + addrIndex->retVal = MGU_OPEN_FILE; +#ifdef DEV_STANDALONE + fp = fopen( fileSpec, "wb" ); + g_free( fileSpec ); + if( fp ) { + fputs( "<?xml version=\"1.0\" ?>\n", fp ); +#else + pfile = prefs_file_open( fileSpec ); + g_free( fileSpec ); + if( pfile ) { + fp = pfile->fp; + fprintf( fp, "<?xml version=\"1.0\" encoding=\"%s\" ?>\n", + conv_get_internal_charset_str() ); +#endif + addrindex_write_elem_s( fp, 0, TAG_ADDRESS_INDEX ); + fputs( ">\n", fp ); + + addrindex_write_index( addrIndex, fp ); + addrindex_write_elem_e( fp, 0, TAG_ADDRESS_INDEX ); + + addrIndex->retVal = MGU_SUCCESS; +#ifdef DEV_STANDALONE + fclose( fp ); +#else + if( prefs_file_close( pfile ) < 0 ) { + addrIndex->retVal = MGU_ERROR_WRITE; + } +#endif + } + + fileSpec = NULL; + return addrIndex->retVal; +} + +/* +* Save address index data to original file. +* return: Status code, from addrIndex->retVal. +*/ +gint addrindex_save_data( AddressIndex *addrIndex ) { + g_return_val_if_fail( addrIndex != NULL, -1 ); + + addrIndex->retVal = MGU_NO_FILE; + if( addrIndex->fileName == NULL || *addrIndex->fileName == '\0' ) return addrIndex->retVal; + if( addrIndex->filePath == NULL || *addrIndex->filePath == '\0' ) return addrIndex->retVal; + + addrindex_write_to( addrIndex, addrIndex->fileName ); + if( addrIndex->retVal == MGU_SUCCESS ) { + addrIndex->dirtyFlag = FALSE; + } + return addrIndex->retVal; +} + +/* +* Save all address book files which may have changed. +* Return: Status code, set if there was a problem saving data. +*/ +gint addrindex_save_all_books( AddressIndex *addrIndex ) { + gint retVal = MGU_SUCCESS; + GList *nodeIf, *nodeDS; + + nodeIf = addrIndex->interfaceList; + while( nodeIf ) { + AddressInterface *iface = nodeIf->data; + if( iface->type == ADDR_IF_BOOK ) { + nodeDS = iface->listSource; + while( nodeDS ) { + AddressDataSource *ds = nodeDS->data; + AddressBookFile *abf = ds->rawDataSource; + if( abf->dirtyFlag ) { + if( abf->readFlag ) { + addrbook_save_data( abf ); + if( abf->retVal != MGU_SUCCESS ) { + retVal = abf->retVal; + } + } + } + nodeDS = g_list_next( nodeDS ); + } + break; + } + nodeIf = g_list_next( nodeIf ); + } + return retVal; +} + + +/* ********************************************************************** +* Address book conversion to new format. +* *********************************************************************** +*/ + +#define ELTAG_IF_OLD_FOLDER "folder" +#define ELTAG_IF_OLD_GROUP "group" +#define ELTAG_IF_OLD_ITEM "item" +#define ELTAG_IF_OLD_NAME "name" +#define ELTAG_IF_OLD_ADDRESS "address" +#define ELTAG_IF_OLD_REMARKS "remarks" +#define ATTAG_IF_OLD_NAME "name" + +#define TEMPNODE_ROOT 0 +#define TEMPNODE_FOLDER 1 +#define TEMPNODE_GROUP 2 +#define TEMPNODE_ADDRESS 3 + +typedef struct _AddressCvt_Node AddressCvtNode; +struct _AddressCvt_Node { + gint type; + gchar *name; + gchar *address; + gchar *remarks; + GList *list; +}; + +/* +* Parse current address item. +*/ +static AddressCvtNode *addrindex_parse_item( XMLFile *file ) { + gchar *element; + guint level; + AddressCvtNode *nn; + + nn = g_new0( AddressCvtNode, 1 ); + nn->type = TEMPNODE_ADDRESS; + nn->list = NULL; + + level = file->level; + + for (;;) { + xml_parse_next_tag(file); + if (file->level < level) return nn; + + element = xml_get_element( file ); + if( xml_compare_tag( file, ELTAG_IF_OLD_NAME ) ) { + nn->name = g_strdup( element ); + } + if( xml_compare_tag( file, ELTAG_IF_OLD_ADDRESS ) ) { + nn->address = g_strdup( element ); + } + if( xml_compare_tag( file, ELTAG_IF_OLD_REMARKS ) ) { + nn->remarks = g_strdup( element ); + } + xml_parse_next_tag(file); + } +} + +/* +* Create a temporary node below specified node. +*/ +static AddressCvtNode *addrindex_add_object( AddressCvtNode *node, gint type, gchar *name, gchar *addr, char *rem ) { + AddressCvtNode *nn; + nn = g_new0( AddressCvtNode, 1 ); + nn->type = type; + nn->name = g_strdup( name ); + nn->remarks = g_strdup( rem ); + node->list = g_list_append( node->list, nn ); + return nn; +} + +/* +* Process current temporary node. +*/ +static void addrindex_add_obj( XMLFile *file, AddressCvtNode *node ) { + GList *attr; + guint prev_level; + AddressCvtNode *newNode = NULL; + gchar *name; + gchar *value; + + for (;;) { + prev_level = file->level; + xml_parse_next_tag( file ); + if (file->level < prev_level) return; + name = NULL; + value = NULL; + + if( xml_compare_tag( file, ELTAG_IF_OLD_GROUP ) ) { + attr = xml_get_current_tag_attr(file); + if (attr) { + name = ((XMLAttr *)attr->data)->name; + if( strcmp( name, ATTAG_IF_OLD_NAME ) == 0 ) { + value = ((XMLAttr *)attr->data)->value; + } + } + newNode = addrindex_add_object( node, TEMPNODE_GROUP, value, "", "" ); + addrindex_add_obj( file, newNode ); + + } + else if( xml_compare_tag( file, ELTAG_IF_OLD_FOLDER ) ) { + attr = xml_get_current_tag_attr(file); + if (attr) { + name = ((XMLAttr *)attr->data)->name; + if( strcmp( name, ATTAG_IF_OLD_NAME ) == 0 ) { + value = ((XMLAttr *)attr->data)->value; + } + } + newNode = addrindex_add_object( node, TEMPNODE_FOLDER, value, "", "" ); + addrindex_add_obj( file, newNode ); + } + else if( xml_compare_tag( file, ELTAG_IF_OLD_ITEM ) ) { + newNode = addrindex_parse_item( file ); + node->list = g_list_append( node->list, newNode ); + } + else { + /* printf( "invalid: !!! \n" ); */ + attr = xml_get_current_tag_attr( file ); + } + } +} + +/* +* Consume all nodes below current tag. +*/ +static void addrindex_consume_tree( XMLFile *file ) { + guint prev_level; + gchar *element; + GList *attr; + XMLTag *xtag; + + for (;;) { + prev_level = file->level; + xml_parse_next_tag( file ); + if (file->level < prev_level) return; + + xtag = xml_get_current_tag( file ); + /* printf( "tag : %s\n", xtag->tag ); */ + element = xml_get_element( file ); + attr = xml_get_current_tag_attr( file ); + /* show_attribs( attr ); */ + /* printf( "\ttag value : %s :\n", element ); */ + addrindex_consume_tree( file ); + } +} + +/* +* Print temporary tree. +*/ +static void addrindex_print_node( AddressCvtNode *node, FILE *stream ) { + GList *list; + + fprintf( stream, "Node:\ttype :%d:\n", node->type ); + fprintf( stream, "\tname :%s:\n", node->name ); + fprintf( stream, "\taddr :%s:\n", node->address ); + fprintf( stream, "\trems :%s:\n", node->remarks ); + if( node->list ) { + fprintf( stream, "\t--list----\n" ); + } + list = node->list; + while( list ) { + AddressCvtNode *lNode = list->data; + list = g_list_next( list ); + addrindex_print_node( lNode, stream ); + } + fprintf( stream, "\t==list-%d==\n", node->type ); +} + +/* +* Free up temporary tree. +*/ +static void addrindex_free_node( AddressCvtNode *node ) { + GList *list = node->list; + + while( list ) { + AddressCvtNode *lNode = list->data; + list = g_list_next( list ); + addrindex_free_node( lNode ); + } + node->type = TEMPNODE_ROOT; + g_free( node->name ); + g_free( node->address ); + g_free( node->remarks ); + g_list_free( node->list ); + g_free( node ); +} + +/* +* Process address book for specified node. +*/ +static void addrindex_process_node( + AddressBookFile *abf, AddressCvtNode *node, ItemFolder *parent, + ItemGroup *parentGrp, ItemFolder *folderGrp ) +{ + GList *list; + ItemFolder *itemFolder = NULL; + ItemGroup *itemGParent = parentGrp; + ItemFolder *itemGFolder = folderGrp; + AddressCache *cache = abf->addressCache; + + if( node->type == TEMPNODE_ROOT ) { + itemFolder = parent; + } + else if( node->type == TEMPNODE_FOLDER ) { + itemFolder = addritem_create_item_folder(); + addritem_folder_set_name( itemFolder, node->name ); + addrcache_id_folder( cache, itemFolder ); + addrcache_folder_add_folder( cache, parent, itemFolder ); + itemGFolder = NULL; + } + else if( node->type == TEMPNODE_GROUP ) { + ItemGroup *itemGroup; + gchar *fName; + + /* Create a folder for group */ + fName = g_strdup_printf( "Cvt - %s", node->name ); + itemGFolder = addritem_create_item_folder(); + addritem_folder_set_name( itemGFolder, fName ); + addrcache_id_folder( cache, itemGFolder ); + addrcache_folder_add_folder( cache, parent, itemGFolder ); + g_free( fName ); + + /* Add group into folder */ + itemGroup = addritem_create_item_group(); + addritem_group_set_name( itemGroup, node->name ); + addrcache_id_group( cache, itemGroup ); + addrcache_folder_add_group( cache, itemGFolder, itemGroup ); + itemGParent = itemGroup; + } + else if( node->type == TEMPNODE_ADDRESS ) { + ItemPerson *itemPerson; + ItemEMail *itemEMail; + + /* Create person and email objects */ + itemPerson = addritem_create_item_person(); + addritem_person_set_common_name( itemPerson, node->name ); + addrcache_id_person( cache, itemPerson ); + itemEMail = addritem_create_item_email(); + addritem_email_set_address( itemEMail, node->address ); + addritem_email_set_remarks( itemEMail, node->remarks ); + addrcache_id_email( cache, itemEMail ); + addrcache_person_add_email( cache, itemPerson, itemEMail ); + + /* Add person into appropriate folder */ + if( itemGFolder ) { + addrcache_folder_add_person( cache, itemGFolder, itemPerson ); + } + else { + addrcache_folder_add_person( cache, parent, itemPerson ); + } + + /* Add email address only into group */ + if( parentGrp ) { + addrcache_group_add_email( cache, parentGrp, itemEMail ); + } + } + + list = node->list; + while( list ) { + AddressCvtNode *lNode = list->data; + list = g_list_next( list ); + addrindex_process_node( abf, lNode, itemFolder, itemGParent, itemGFolder ); + } +} + +/* +* Process address book to specified file number. +*/ +static gboolean addrindex_process_book( AddressIndex *addrIndex, XMLFile *file, gchar *displayName ) { + gboolean retVal = FALSE; + AddressBookFile *abf = NULL; + AddressCvtNode *rootNode = NULL; + gchar *newFile = NULL; + GList *fileList = NULL; + gint fileNum = 0; + + /* Setup root node */ + rootNode = g_new0( AddressCvtNode, 1 ); + rootNode->type = TEMPNODE_ROOT; + rootNode->name = g_strdup( "root" ); + rootNode->list = NULL; + addrindex_add_obj( file, rootNode ); + /* addrindex_print_node( rootNode, stdout ); */ + + /* Create new address book */ + abf = addrbook_create_book(); + addrbook_set_name( abf, displayName ); + addrbook_set_path( abf, addrIndex->filePath ); + + /* Determine next available file number */ + fileList = addrbook_get_bookfile_list( abf ); + if( fileList ) { + fileNum = 1 + abf->maxValue; + } + g_list_free( fileList ); + fileList = NULL; + + newFile = addrbook_gen_new_file_name( fileNum ); + if( newFile ) { + addrbook_set_file( abf, newFile ); + } + + addrindex_process_node( abf, rootNode, abf->addressCache->rootFolder, NULL, NULL ); + + /* addrbook_dump_book( abf, stdout ); */ + addrbook_save_data( abf ); + addrIndex->retVal = abf->retVal; + if( abf->retVal == MGU_SUCCESS ) retVal = TRUE; + + addrbook_free_book( abf ); + abf = NULL; + addrindex_free_node( rootNode ); + rootNode = NULL; + + /* Create entries in address index */ + if( retVal ) { + abf = addrbook_create_book(); + addrbook_set_name( abf, displayName ); + addrbook_set_path( abf, addrIndex->filePath ); + addrbook_set_file( abf, newFile ); + addrindex_index_add_datasource( addrIndex, ADDR_IF_BOOK, abf ); + } + + return retVal; +} + +/* +* Process tree converting data. +*/ +static void addrindex_convert_tree( AddressIndex *addrIndex, XMLFile *file ) { + guint prev_level; + gchar *element; + GList *attr; + XMLTag *xtag; + + /* Process file */ + for (;;) { + prev_level = file->level; + xml_parse_next_tag( file ); + if (file->level < prev_level) return; + + xtag = xml_get_current_tag( file ); + /* printf( "tag : %d : %s\n", prev_level, xtag->tag ); */ + if( strcmp( xtag->tag, TAG_IF_OLD_COMMON ) == 0 ) { + if( addrindex_process_book( addrIndex, file, DISP_OLD_COMMON ) ) { + addrIndex->needsConversion = FALSE; + addrIndex->wasConverted = TRUE; + continue; + } + return; + } + if( strcmp( xtag->tag, TAG_IF_OLD_PERSONAL ) == 0 ) { + if( addrindex_process_book( addrIndex, file, DISP_OLD_PERSONAL ) ) { + addrIndex->needsConversion = FALSE; + addrIndex->wasConverted = TRUE; + continue; + } + return; + } + element = xml_get_element( file ); + attr = xml_get_current_tag_attr( file ); + /* show_attribs( attr ); */ + /* printf( "\ttag value : %s :\n", element ); */ + addrindex_consume_tree( file ); + } +} + +static gint addrindex_convert_data( AddressIndex *addrIndex ) { + XMLFile *file = NULL; + gchar *fileSpec; + + fileSpec = g_strconcat( addrIndex->filePath, G_DIR_SEPARATOR_S, addrIndex->fileName, NULL ); + addrIndex->retVal = MGU_NO_FILE; + file = xml_open_file( fileSpec ); + g_free( fileSpec ); + + if( file == NULL ) { + /* fprintf( stdout, " file '%s' does not exist.\n", addrIndex->fileName ); */ + return addrIndex->retVal; + } + + addrIndex->retVal = MGU_BAD_FORMAT; + if( xml_get_dtd( file ) == 0 ) { + if( xml_parse_next_tag( file ) == 0 ) { + if( xml_compare_tag( file, TAG_ADDRESS_INDEX ) ) { + addrindex_convert_tree( addrIndex, file ); + } + } + } + xml_close_file( file ); + return addrIndex->retVal; +} + +/* +* Create a new address book file. +*/ +static gboolean addrindex_create_new_book( AddressIndex *addrIndex, gchar *displayName ) { + gboolean retVal = FALSE; + AddressBookFile *abf = NULL; + gchar *newFile = NULL; + GList *fileList = NULL; + gint fileNum = 0; + + /* Create new address book */ + abf = addrbook_create_book(); + addrbook_set_name( abf, displayName ); + addrbook_set_path( abf, addrIndex->filePath ); + + /* Determine next available file number */ + fileList = addrbook_get_bookfile_list( abf ); + if( fileList ) { + fileNum = 1 + abf->maxValue; + } + g_list_free( fileList ); + fileList = NULL; + + newFile = addrbook_gen_new_file_name( fileNum ); + if( newFile ) { + addrbook_set_file( abf, newFile ); + } + + addrbook_save_data( abf ); + addrIndex->retVal = abf->retVal; + if( abf->retVal == MGU_SUCCESS ) retVal = TRUE; + addrbook_free_book( abf ); + abf = NULL; + + /* Create entries in address index */ + if( retVal ) { + abf = addrbook_create_book(); + addrbook_set_name( abf, displayName ); + addrbook_set_path( abf, addrIndex->filePath ); + addrbook_set_file( abf, newFile ); + addrindex_index_add_datasource( addrIndex, ADDR_IF_BOOK, abf ); + } + + return retVal; +} + +/* +* Read data for address index performing a conversion if necesary. +* Enter: addrIndex Address index object. +* return: Status code, from addrIndex->retVal. +* Note: New address book files will be created in directory specified by +* addrIndex. Three files will be created, for the following: +* "Common addresses" +* "Personal addresses" +* "Gathered addresses" - a new address book. +*/ +gint addrindex_read_data( AddressIndex *addrIndex ) { + g_return_val_if_fail( addrIndex != NULL, -1 ); + + addrIndex->conversionError = FALSE; + addrindex_read_file( addrIndex ); + if( addrIndex->retVal == MGU_SUCCESS ) { + if( addrIndex->needsConversion ) { + if( addrindex_convert_data( addrIndex ) == MGU_SUCCESS ) { + addrIndex->conversionError = TRUE; + } + else { + addrIndex->conversionError = TRUE; + } + } + addrIndex->dirtyFlag = TRUE; + } + return addrIndex->retVal; +} + +/* +* Create new address books for a new address index. +* Enter: addrIndex Address index object. +* return: Status code, from addrIndex->retVal. +* Note: New address book files will be created in directory specified by +* addrIndex. Three files will be created, for the following: +* "Common addresses" +* "Personal addresses" +* "Gathered addresses" - a new address book. +*/ +gint addrindex_create_new_books( AddressIndex *addrIndex ) { + gboolean flg; + + g_return_val_if_fail( addrIndex != NULL, -1 ); + + flg = addrindex_create_new_book( addrIndex, DISP_NEW_COMMON ); + if( flg ) { + flg = addrindex_create_new_book( addrIndex, DISP_NEW_PERSONAL ); + addrIndex->dirtyFlag = TRUE; + } + return addrIndex->retVal; +} + +/* ********************************************************************** +* New interface stuff. +* *********************************************************************** +*/ + +/* + * Return modified flag for specified data source. + */ +gboolean addrindex_ds_get_modify_flag( AddressDataSource *ds ) { + gboolean retVal = FALSE; + AddressInterface *iface; + + if( ds == NULL ) return retVal; + iface = ds->interface; + if( iface == NULL ) return retVal; + if( iface->getModifyFlag ) { + retVal = ( iface->getModifyFlag ) ( ds->rawDataSource ); + } + return retVal; +} + +/* + * Return accessed flag for specified data source. + */ +gboolean addrindex_ds_get_access_flag( AddressDataSource *ds ) { + gboolean retVal = FALSE; + AddressInterface *iface; + + if( ds == NULL ) return retVal; + iface = ds->interface; + if( iface == NULL ) return retVal; + if( iface->getAccessFlag ) { + retVal = ( iface->getAccessFlag ) ( ds->rawDataSource ); + } + return retVal; +} + +/* + * Return data read flag for specified data source. + */ +gboolean addrindex_ds_get_read_flag( AddressDataSource *ds ) { + gboolean retVal = TRUE; + AddressInterface *iface; + + if( ds == NULL ) return retVal; + iface = ds->interface; + if( iface == NULL ) return retVal; + if( iface->getReadFlag ) { + retVal = ( iface->getReadFlag ) ( ds->rawDataSource ); + } + return retVal; +} + +/* + * Return status code for specified data source. + */ +gint addrindex_ds_get_status_code( AddressDataSource *ds ) { + gint retVal = MGU_SUCCESS; + AddressInterface *iface; + + if( ds == NULL ) return retVal; + iface = ds->interface; + if( iface == NULL ) return retVal; + if( iface->getStatusCode ) { + retVal = ( iface->getStatusCode ) ( ds->rawDataSource ); + } + return retVal; +} + +/* + * Return data read flag for specified data source. + */ +gint addrindex_ds_read_data( AddressDataSource *ds ) { + gint retVal = MGU_SUCCESS; + AddressInterface *iface; + + if( ds == NULL ) return retVal; + iface = ds->interface; + if( iface == NULL ) return retVal; + if( iface->getReadData ) { + retVal = ( iface->getReadData ) ( ds->rawDataSource ); + } + return retVal; +} + +/* + * Return data read flag for specified data source. + */ +ItemFolder *addrindex_ds_get_root_folder( AddressDataSource *ds ) { + ItemFolder *retVal = NULL; + AddressInterface *iface; + + if( ds == NULL ) return retVal; + iface = ds->interface; + if( iface == NULL ) return retVal; + if( iface->getRootFolder ) { + retVal = ( iface->getRootFolder ) ( ds->rawDataSource ); + } + return retVal; +} + +/* + * Return list of folders for specified data source. + */ +GList *addrindex_ds_get_list_folder( AddressDataSource *ds ) { + GList *retVal = FALSE; + AddressInterface *iface; + + if( ds == NULL ) return retVal; + iface = ds->interface; + if( iface == NULL ) return retVal; + if( iface->getListFolder ) { + retVal = ( iface->getListFolder ) ( ds->rawDataSource ); + } + return retVal; +} + +/* + * Return list of persons in root folder for specified data source. + */ +GList *addrindex_ds_get_list_person( AddressDataSource *ds ) { + GList *retVal = FALSE; + AddressInterface *iface; + + if( ds == NULL ) return retVal; + iface = ds->interface; + if( iface == NULL ) return retVal; + if( iface->getListPerson ) { + retVal = ( iface->getListPerson ) ( ds->rawDataSource ); + } + return retVal; +} + +/* + * Return name for specified data source. + */ +gchar *addrindex_ds_get_name( AddressDataSource *ds ) { + gchar *retVal = FALSE; + AddressInterface *iface; + + if( ds == NULL ) return retVal; + iface = ds->interface; + if( iface == NULL ) return retVal; + if( iface->getName ) { + retVal = ( iface->getName ) ( ds->rawDataSource ); + } + return retVal; +} + +/* + * Set the access flag inside the data source. + */ +void addrindex_ds_set_access_flag( AddressDataSource *ds, gboolean *value ) { + AddressInterface *iface; + + if( ds == NULL ) return; + iface = ds->interface; + if( iface == NULL ) return; + if( iface->setAccessFlag ) { + ( iface->setAccessFlag ) ( ds->rawDataSource, value ); + } +} + +/* + * Return read only flag for specified data source. + */ +gboolean addrindex_ds_get_readonly( AddressDataSource *ds ) { + AddressInterface *iface; + if( ds == NULL ) return TRUE; + iface = ds->interface; + if( iface == NULL ) return TRUE; + return iface->readOnly; +} + +/* + * Return list of all persons for specified data source. + */ +GList *addrindex_ds_get_all_persons( AddressDataSource *ds ) { + GList *retVal = NULL; + AddressInterface *iface; + + if( ds == NULL ) return retVal; + iface = ds->interface; + if( iface == NULL ) return retVal; + if( iface->getAllPersons ) { + retVal = ( iface->getAllPersons ) ( ds->rawDataSource ); + } + return retVal; +} + +/* + * Return list of all groups for specified data source. + */ +GList *addrindex_ds_get_all_groups( AddressDataSource *ds ) { + GList *retVal = NULL; + AddressInterface *iface; + + if( ds == NULL ) return retVal; + iface = ds->interface; + if( iface == NULL ) return retVal; + if( iface->getAllGroups ) { + retVal = ( iface->getAllGroups ) ( ds->rawDataSource ); + } + return retVal; +} + +/* +* End of Source. +*/ |