Fix bug 3793: segfault when autocompletion asks for master passphrase
[claws.git] / src / addrindex.c
index 3e80ff9bac036a59eeb7fc1165e0c059fb452e2a..282281f6224b2b9c33663124965000868222177f 100644 (file)
@@ -1,10 +1,10 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 2001-2006 Match Grun and the Claws Mail team
+ * Copyright (C) 2001-2012 Match Grun and the Claws Mail team
  *
  * 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
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
@@ -13,8 +13,8 @@
  * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 
  */
 
 /*
@@ -23,6 +23,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
+#include "claws-features.h"
 #endif
 
 #include "defs.h"
@@ -40,6 +41,8 @@
 #include "addrquery.h"
 #include "addr_compl.h"
 #include "utils.h"
+#include "alertpanel.h"
+#include "passwordstore.h"
 
 #ifndef DEV_STANDALONE
 #include "prefs_gtk.h"
 #include "ldapserver.h"
 #include "ldapctrl.h"
 #include "ldapquery.h"
+#include "ldapupdate.h"
 #include "ldaputil.h"
 #endif
 
+#ifdef G_OS_WIN32
+#undef interface
+#endif
+
 #define TAG_ADDRESS_INDEX    "addressbook"
 
 #define TAG_IF_ADDRESS_BOOK  "book_list"
@@ -137,6 +145,17 @@ struct _AddressIfAttr {
        gchar *value;
 };
 
+static AddressDataSource *addrindex_create_datasource  ( AddressIfType ifType );
+
+static GList *addrindex_ds_get_all_persons     ( AddressDataSource *ds );
+static GList *addrindex_ds_get_all_groups      ( AddressDataSource *ds );
+static AddressDataSource *addrindex_get_datasource     ( AddressIndex *addrIndex,
+                                                 const gchar *cacheID );
+static AddressInterface *addrindex_get_interface       ( AddressIndex *addrIndex,
+                                                 AddressIfType ifType );
+static gint addrindex_write_to                 ( AddressIndex *addrIndex,
+                                         const gchar *newFile );
+
 /*
  * Define DOM fragment.
  */
@@ -279,14 +298,15 @@ static void addrindex_build_if_list( AddressIndex *addrIndex ) {
        iface = addrindex_create_interface(
                        ADDR_IF_LDAP, "LDAP", TAG_IF_LDAP, TAG_DS_LDAP );
 #ifdef USE_LDAP
+       iface->readOnly = FALSE;
        /* iface->haveLibrary = ldapsvr_test_ldap_lib(); */
        iface->haveLibrary = ldaputil_test_ldap_lib();
        iface->useInterface = iface->haveLibrary;
-       /* iface->getModifyFlag = ( void * ) ldapsvr_get_modified; */
+       iface->getModifyFlag = ( void * ) ldapsvr_get_modified;
        iface->getAccessFlag = ( void * ) ldapsvr_get_accessed;
-       /* iface->getReadFlag   = ( void * ) ldapsvr_get_read_flag; */
+       iface->getReadFlag   = ( void * ) ldapsvr_get_read_flag;
        iface->getStatusCode = ( void * ) ldapsvr_get_status;
-       /* iface->getReadData   = ( void * ) ldapsvr_read_data; */
+       iface->getReadData   = ( void * ) ldapsvr_read_data;
        iface->getRootFolder = ( void * ) ldapsvr_get_root_folder;
        iface->getListFolder = ( void * ) ldapsvr_get_list_folder;
        iface->getListPerson = ( void * ) ldapsvr_get_list_person;
@@ -384,7 +404,7 @@ AddressDataSource *addrindex_create_datasource( AddressIfType ifType ) {
 void addrindex_free_datasource( AddressDataSource *ds ) {
        AddressInterface *iface;
 
-       g_return_if_fail( ds != NULL );
+       cm_return_if_fail( ds != NULL );
 
        iface = ds->interface;
        if( ds->rawDataSource != NULL ) {
@@ -498,8 +518,8 @@ gchar *addrindex_get_cache_id( AddressIndex *addrIndex, AddressDataSource *ds )
        AddrBookBase *adbase;
        AddressCache *cache;
 
-       g_return_val_if_fail( addrIndex != NULL, NULL );
-       g_return_val_if_fail( ds != NULL, NULL );
+       cm_return_val_if_fail( addrIndex != NULL, NULL );
+       cm_return_val_if_fail( ds != NULL, NULL );
 
        adbase = ( AddrBookBase * ) ds->rawDataSource;
        if( adbase ) {
@@ -518,11 +538,11 @@ gchar *addrindex_get_cache_id( AddressIndex *addrIndex, AddressDataSource *ds )
  * \param cacheID   ID.
  * \return Data source, or NULL if not found.
  */
-AddressDataSource *addrindex_get_datasource(
+static AddressDataSource *addrindex_get_datasource(
                AddressIndex *addrIndex, const gchar *cacheID )
 {
-       g_return_val_if_fail( addrIndex != NULL, NULL );
-       g_return_val_if_fail( cacheID != NULL, NULL );
+       cm_return_val_if_fail( addrIndex != NULL, NULL );
+       cm_return_val_if_fail( cacheID != NULL, NULL );
        return ( AddressDataSource * ) g_hash_table_lookup( addrIndex->hashCache, cacheID );
 }
 
@@ -537,8 +557,8 @@ AddressCache *addrindex_get_cache( AddressIndex *addrIndex, const gchar *cacheID
        AddrBookBase *adbase;
        AddressCache *cache;
 
-       g_return_val_if_fail( addrIndex != NULL, NULL );
-       g_return_val_if_fail( cacheID != NULL, NULL );
+       cm_return_val_if_fail( addrIndex != NULL, NULL );
+       cm_return_val_if_fail( cacheID != NULL, NULL );
 
        cache = NULL;
        ds = addrindex_get_datasource( addrIndex, cacheID );
@@ -633,21 +653,13 @@ AddressIndex *addrindex_create_index( void ) {
        return _addressIndex_;
 }
 
-/**
- * Return reference to address index.
- * \return Address index object.
- */
-AddressIndex *addrindex_get_object( void ) {
-       return _addressIndex_;
-}
-
 /**
  * Property - Specify file path to address index file.
  * \param addrIndex Address index.
  * \param value Path to index file.
  */
 void addrindex_set_file_path( AddressIndex *addrIndex, const gchar *value ) {
-       g_return_if_fail( addrIndex != NULL );
+       cm_return_if_fail( addrIndex != NULL );
        addrIndex->filePath = mgu_replace_string( addrIndex->filePath, value );
 }
 
@@ -657,38 +669,17 @@ void addrindex_set_file_path( AddressIndex *addrIndex, const gchar *value ) {
  * \param value File name.
  */
 void addrindex_set_file_name( AddressIndex *addrIndex, const gchar *value ) {
-       g_return_if_fail( addrIndex != NULL );
+       cm_return_if_fail( addrIndex != NULL );
        addrIndex->fileName = mgu_replace_string( addrIndex->fileName, value );
 }
 
-/**
- * Property - Specify file path to be used.
- * \param addrIndex Address index.
- * \param value Path to JPilot file.
- */
-void addrindex_set_dirty( AddressIndex *addrIndex, const gboolean value ) {
-       g_return_if_fail( addrIndex != NULL );
-       addrIndex->dirtyFlag = value;
-}
-
-/**
- * Property - get loaded flag. Note that this flag is set after reading data
- * from the address books.
- * \param addrIndex Address index.
- * \return <i>TRUE</i> if address index data was loaded.
- */
-gboolean addrindex_get_loaded( AddressIndex *addrIndex ) {
-       g_return_val_if_fail( addrIndex != NULL, FALSE );
-       return addrIndex->loadedFlag;
-}
-
 /**
  * Return list of address interfaces.
  * \param addrIndex Address index.
  * \return List of address interfaces.
  */
 GList *addrindex_get_interface_list( AddressIndex *addrIndex ) {
-       g_return_val_if_fail( addrIndex != NULL, NULL );
+       cm_return_val_if_fail( addrIndex != NULL, NULL );
        return addrIndex->interfaceList;
 }
 
@@ -715,7 +706,7 @@ void addrindex_teardown( void ) {
 void addrindex_free_index( AddressIndex *addrIndex ) {
        GList *node;
 
-       g_return_if_fail( addrIndex != NULL );
+       cm_return_if_fail( addrIndex != NULL );
 
        /* Search stuff */
        g_list_free( addrIndex->searchOrder );
@@ -769,7 +760,7 @@ void addrindex_free_index( AddressIndex *addrIndex ) {
  * \parem stream    Stream to print.
 */
 void addrindex_print_index( AddressIndex *addrIndex, FILE *stream ) {
-       g_return_if_fail( addrIndex != NULL );
+       cm_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 );
@@ -787,13 +778,13 @@ void addrindex_print_index( AddressIndex *addrIndex, FILE *stream ) {
  * \param  ifType Interface type.
  * \return Address interface, or NULL if not found.
  */
-AddressInterface *addrindex_get_interface(
+static AddressInterface *addrindex_get_interface(
        AddressIndex *addrIndex, AddressIfType ifType )
 {
        AddressInterface *retVal = NULL;
        GList *node;
 
-       g_return_val_if_fail( addrIndex != NULL, NULL );
+       cm_return_val_if_fail( addrIndex != NULL, NULL );
 
        node = addrIndex->interfaceList;
        while( node ) {
@@ -823,8 +814,8 @@ AddressDataSource *addrindex_index_add_datasource(
        AddressInterface *iface;
        AddressDataSource *ds = NULL;
 
-       g_return_val_if_fail( addrIndex != NULL, NULL );
-       g_return_val_if_fail( dataSource != NULL, NULL );
+       cm_return_val_if_fail( addrIndex != NULL, NULL );
+       cm_return_val_if_fail( dataSource != NULL, NULL );
 
        iface = addrindex_get_interface( addrIndex, ifType );
        if( iface ) {
@@ -854,8 +845,8 @@ AddressDataSource *addrindex_index_remove_datasource(
        AddressDataSource *retVal = FALSE;
        AddressInterface *iface;
 
-       g_return_val_if_fail( addrIndex != NULL, NULL );
-       g_return_val_if_fail( dataSource != NULL, NULL );
+       cm_return_val_if_fail( addrIndex != NULL, NULL );
+       cm_return_val_if_fail( dataSource != NULL, NULL );
 
        iface = addrindex_get_interface( addrIndex, dataSource->type );
        if( iface ) {
@@ -942,11 +933,16 @@ static AddressInterface *addrindex_tag_get_datasource(
  * \param lvl  Indentation level.
  * \param name Element name.
  */
-static void addrindex_write_elem_s( FILE *fp, const gint lvl, const gchar *name ) {
+static int addrindex_write_elem_s( FILE *fp, const gint lvl, const gchar *name ) {
        gint i;
-       for( i = 0; i < lvl; i++ ) fputs( "  ", fp );
-       fputs( "<", fp );
-       fputs( name, fp );
+       for( i = 0; i < lvl; i++ ) 
+               if (fputs( "  ", fp ) == EOF)
+                       return -1;
+       if (fputs( "<", fp ) == EOF)
+               return -1;
+       if (fputs( name, fp ) == EOF)
+               return -1;
+       return 0;
 }
 
 /**
@@ -955,12 +951,18 @@ static void addrindex_write_elem_s( FILE *fp, const gint lvl, const gchar *name
  * \param lvl  Indentation level.
  * \param name Element name.
  */
-static void addrindex_write_elem_e( FILE *fp, const gint lvl, const gchar *name ) {
+static int addrindex_write_elem_e( FILE *fp, const gint lvl, const gchar *name ) {
        gint i;
-       for( i = 0; i < lvl; i++ ) fputs( "  ", fp );
-       fputs( "</", fp );
-       fputs( name, fp );
-       fputs( ">\n", fp );
+       for( i = 0; i < lvl; i++ ) 
+               if (fputs( "  ", fp ) == EOF)
+                       return -1;
+       if (fputs( "</", fp ) == EOF)
+               return -1;
+       if (fputs( name, fp ) == EOF)
+               return -1;
+       if (fputs( ">\n", fp ) == EOF)
+               return -1;
+       return 0;
 }
 
 /**
@@ -969,14 +971,21 @@ static void addrindex_write_elem_e( FILE *fp, const gint lvl, const gchar *name
  * \param name  Attribute name.
  * \param value Attribute value.
  */
-static void addrindex_write_attr( FILE *fp, const gchar *name, const gchar *value ) {
-       fputs( " ", fp );
-       fputs( name, fp );
-       fputs( "=\"", fp );
-       xml_file_put_escape_str( fp, value );
-       fputs( "\"", fp );
-}
-
+static int addrindex_write_attr( FILE *fp, const gchar *name, const gchar *value ) {
+       if (fputs( " ", fp ) == EOF)
+               return -1;
+       if (fputs( name, fp ) == EOF)
+               return -1;
+       if (fputs( "=\"", fp ) == EOF)
+               return -1;
+       if (xml_file_put_escape_str( fp, value ) < 0)
+               return -1;
+       if (fputs( "\"", fp ) == EOF)
+               return -1;
+       return 0;
+}
+
+#if !defined(USE_LDAP) || !defined(USE_JPILOT)
 /**
  * Return DOM fragment for current XML tag from file.
  * \param  file XML file being processed.
@@ -994,7 +1003,7 @@ static AddressIfFragment *addrindex_read_fragment( XMLFile *file ) {
        guint prevLevel;
        gint rc;
 
-       /* printf( "addrindex_read_fragment\n" ); */
+       /* g_print( "addrindex_read_fragment\n" ); */
 
        prevLevel = file->level;
 
@@ -1045,39 +1054,47 @@ static AddressIfFragment *addrindex_read_fragment( XMLFile *file ) {
  * \param fragment DOM fragment for configuration element.
  * \param lvl      Indent level.
  */
-static void addrindex_write_fragment(
+static int addrindex_write_fragment(
                FILE *fp, const AddressIfFragment *fragment, const gint lvl )
 {
        GList *node;
 
        if( fragment ) {
-               addrindex_write_elem_s( fp, lvl, fragment->name );
+               if (addrindex_write_elem_s( fp, lvl, fragment->name ) < 0)
+                       return -1;
                node = fragment->attributes;
                while( node ) {
                        AddressIfAttrib *nv = node->data;
-                       addrindex_write_attr( fp, nv->name, nv->value );
+                       if (addrindex_write_attr( fp, nv->name, nv->value ) < 0)
+                               return -1;
                        node = g_list_next( node );
                }
                if( fragment->children ) {
-                       fputs(" >\n", fp);
+                       if (fputs(" >\n", fp) == EOF)
+                               return -1;
 
                        /* Output children */
                        node = fragment->children;
                        while( node ) {
                                AddressIfFragment *child = node->data;
-                               addrindex_write_fragment( fp, child, 1+lvl );
+                               if (addrindex_write_fragment( fp, child, 1+lvl ) < 0)
+                                       return -1;
                                node = g_list_next( node );
                        }
 
                        /* Output closing tag */
-                       addrindex_write_elem_e( fp, lvl, fragment->name );
+                       if (addrindex_write_elem_e( fp, lvl, fragment->name ) < 0)
+                               return -1;
                }
                else {
-                       fputs(" />\n", fp);
+                       if (fputs(" />\n", fp) == EOF)
+                               return -1;
                }
        }
+       
+       return 0;
 }
-
+#endif
 /**
  * Read/parse address index file, creating a data source for a regular
  * intrinsic XML addressbook.
@@ -1107,14 +1124,19 @@ static AddressDataSource *addrindex_parse_book( XMLFile *file ) {
        return ds;
 }
 
-static void addrindex_write_book( FILE *fp, AddressDataSource *ds, gint lvl ) {
+static int 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, addrbook_get_name( abf ) );
-               addrindex_write_attr( fp, ATTAG_BOOK_FILE, abf->fileName );
-               fputs( " />\n", fp );
+               if (addrindex_write_elem_s( fp, lvl, TAG_DS_ADDRESS_BOOK ) < 0)
+                       return -1;
+               if (addrindex_write_attr( fp, ATTAG_BOOK_NAME, addrbook_get_name( abf ) ) < 0)
+                       return -1;
+               if (addrindex_write_attr( fp, ATTAG_BOOK_FILE, abf->fileName ) < 0)
+                       return -1;
+               if (fputs( " />\n", fp ) == EOF)
+                       return -1;
        }
+       return 0;
 }
 
 static AddressDataSource *addrindex_parse_vcard( XMLFile *file ) {
@@ -1140,14 +1162,19 @@ static AddressDataSource *addrindex_parse_vcard( XMLFile *file ) {
        return ds;
 }
 
-static void addrindex_write_vcard( FILE *fp, AddressDataSource *ds, gint lvl ) {
+static int 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, vcard_get_name( vcf ) );
-               addrindex_write_attr( fp, ATTAG_VCARD_FILE, vcf->path );
-               fputs( " />\n", fp );
+               if (addrindex_write_elem_s( fp, lvl, TAG_DS_VCARD ) < 0)
+                       return -1;
+               if (addrindex_write_attr( fp, ATTAG_VCARD_NAME, vcard_get_name( vcf ) ) < 0)
+                       return -1;
+               if (addrindex_write_attr( fp, ATTAG_VCARD_FILE, vcf->path ) < 0)
+                       return -1;
+               if (fputs( " />\n", fp ) == EOF)
+                       return -1;
        }
+       return 0;
 }
 
 #ifdef USE_JPILOT
@@ -1186,27 +1213,33 @@ static AddressDataSource *addrindex_parse_jpilot( XMLFile *file ) {
        return ds;
 }
 
-static void addrindex_write_jpilot( FILE *fp,AddressDataSource *ds, gint lvl ) {
+static int 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, jpilot_get_name( jpf ) );
-               addrindex_write_attr( fp, ATTAG_JPILOT_FILE, jpf->path );
+               if (addrindex_write_elem_s( fp, lvl, TAG_DS_JPILOT ) < 0)
+                       return -1;
+               if (addrindex_write_attr( fp, ATTAG_JPILOT_NAME, jpilot_get_name( jpf ) ) < 0)
+                       return -1;
+               if (addrindex_write_attr( fp, ATTAG_JPILOT_FILE, jpf->path ) < 0)
+                       return -1;
                node = customLbl;
                ind = 1;
                while( node ) {
                        gchar name[256];
                        g_snprintf( name, sizeof(name), "%s%d",
                                    ATTAG_JPILOT_CUSTOM, ind );
-                       addrindex_write_attr( fp, name, node->data );
+                       if (addrindex_write_attr( fp, name, node->data ) < 0)
+                               return -1;
                        ind++;
                        node = g_list_next( node );
                }
-               fputs( " />\n", fp );
+               if (fputs( " />\n", fp ) == EOF)
+                       return -1;
        }
+       return 0;
 }
 
 #else
@@ -1221,11 +1254,13 @@ static AddressDataSource *addrindex_parse_jpilot( XMLFile *file ) {
        return ds;
 }
 
-static void addrindex_write_jpilot( FILE *fp, AddressDataSource *ds, gint lvl ) {
+static int addrindex_write_jpilot( FILE *fp, AddressDataSource *ds, gint lvl ) {
        AddressIfFragment *fragment = ds->rawDataSource;
        if( fragment ) {
-               addrindex_write_fragment( fp, fragment, lvl );
+               if (addrindex_write_fragment( fp, fragment, lvl ) < 0)
+                       return -1;
        }
+       return 0;
 }
 #endif
 
@@ -1287,7 +1322,6 @@ static void addrindex_parse_ldap_attrlist( XMLFile *file, LdapControl *ctl ) {
                                break;
                        }
                }
-               xtag = xtagPrev;
        }
 
        /* Build list of search attributes */
@@ -1320,8 +1354,9 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
        gboolean bDynSearch;
        gboolean bTLS, bSSL;
        gint iMatch;
+       gchar *password = NULL;
 
-       /* printf( "addrindex_parse_ldap\n" ); */
+       /* g_print( "addrindex_parse_ldap\n" ); */
        /* Set up some defaults */
        bDynSearch = FALSE;
        bTLS = FALSE;
@@ -1353,11 +1388,12 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
                        ldapctl_set_bind_dn( ctl, value );
                }
                else if( strcmp( name, ATTAG_LDAP_BIND_PASS ) == 0 ) {
-                       ldapctl_set_bind_password( ctl, value );
+                       password = value;
                }
                else if( strcmp( name, ATTAG_LDAP_CRITERIA ) == 0 ) {
                        g_free( criteria );
                        criteria = g_strdup( value );
+                       g_print("criteria %s\n", criteria);
                }
                else if( strcmp( name, ATTAG_LDAP_MAX_ENTRY ) == 0 ) {
                        ldapctl_set_max_entries( ctl, ivalue );
@@ -1395,14 +1431,15 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
                attr = g_list_next( attr );
        }
 
+       if (password != NULL)
+               passwd_store_set(PWS_CORE, "LDAP", ctl->hostName, password, TRUE);
+
        server = ldapsvr_create_noctl();
        ldapsvr_set_name( server, serverName );
        ldapsvr_set_search_flag( server, bDynSearch );
        ldapctl_set_matching_option( ctl, iMatch );
-#ifdef USE_LDAP_TLS
        ldapctl_set_tls( ctl, bTLS );
        ldapctl_set_ssl( ctl, bSSL );
-#endif
        g_free( serverName );
        ldapsvr_set_control( server, ctl );
        ds->rawDataSource = server;
@@ -1424,7 +1461,7 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
        return ds;
 }
 
-static void addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) {
+static int addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) {
        LdapServer *server = ds->rawDataSource;
        LdapControl *ctl = NULL;
        GList *node;
@@ -1433,55 +1470,74 @@ static void addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) {
        if( server ) {
                ctl = server->control;
        }
-       if( ctl == NULL ) return;
+       if( ctl == NULL ) return 0;
 
        /* Output start element with attributes */
-       addrindex_write_elem_s( fp, lvl, TAG_DS_LDAP );
-       addrindex_write_attr( fp, ATTAG_LDAP_NAME, ldapsvr_get_name( server ) );
-       addrindex_write_attr( fp, ATTAG_LDAP_HOST, ctl->hostName );
+       if (addrindex_write_elem_s( fp, lvl, TAG_DS_LDAP ) < 0)
+               return -1;
+       if (addrindex_write_attr( fp, ATTAG_LDAP_NAME, ldapsvr_get_name( server ) ) < 0)
+               return -1;
+       if (addrindex_write_attr( fp, ATTAG_LDAP_HOST, ctl->hostName ) < 0)
+               return -1;
 
        sprintf( value, "%d", ctl->port );      
-       addrindex_write_attr( fp, ATTAG_LDAP_PORT, value );
+       if (addrindex_write_attr( fp, ATTAG_LDAP_PORT, value ) < 0)
+               return -1;
 
-       addrindex_write_attr( fp, ATTAG_LDAP_BASE_DN, ctl->baseDN );
-       addrindex_write_attr( fp, ATTAG_LDAP_BIND_DN, ctl->bindDN );
-       addrindex_write_attr( fp, ATTAG_LDAP_BIND_PASS, ctl->bindPass );
+       if (addrindex_write_attr( fp, ATTAG_LDAP_BASE_DN, ctl->baseDN ) < 0)
+               return -1;
+       if (addrindex_write_attr( fp, ATTAG_LDAP_BIND_DN, ctl->bindDN ) < 0)
+               return -1;
 
        sprintf( value, "%d", ctl->maxEntries );
-       addrindex_write_attr( fp, ATTAG_LDAP_MAX_ENTRY, value );
+       if (addrindex_write_attr( fp, ATTAG_LDAP_MAX_ENTRY, value ) < 0)
+               return -1;
        sprintf( value, "%d", ctl->timeOut );
-       addrindex_write_attr( fp, ATTAG_LDAP_TIMEOUT, value );
+       if (addrindex_write_attr( fp, ATTAG_LDAP_TIMEOUT, value ) < 0)
+               return -1;
        sprintf( value, "%d", ctl->maxQueryAge );
-       addrindex_write_attr( fp, ATTAG_LDAP_MAX_AGE, value );
+       if (addrindex_write_attr( fp, ATTAG_LDAP_MAX_AGE, value ) < 0)
+               return -1;
 
-       addrindex_write_attr( fp, ATTAG_LDAP_DYN_SEARCH,
+       if (addrindex_write_attr( fp, ATTAG_LDAP_DYN_SEARCH,
                        server->searchFlag ?
-                       ATVAL_BOOLEAN_YES : ATVAL_BOOLEAN_NO );
+                       ATVAL_BOOLEAN_YES : ATVAL_BOOLEAN_NO ) < 0)
+               return -1;
 
-       addrindex_write_attr( fp, ATTAG_LDAP_MATCH_OPT,
+       if (addrindex_write_attr( fp, ATTAG_LDAP_MATCH_OPT,
                ( ctl->matchingOption == LDAPCTL_MATCH_CONTAINS ) ?
-               ATVAL_LDAP_MATCH_CONTAINS : ATVAL_LDAP_MATCH_BEGIN );
+               ATVAL_LDAP_MATCH_CONTAINS : ATVAL_LDAP_MATCH_BEGIN ) < 0)
+               return -1;
 
-       addrindex_write_attr( fp, ATTAG_LDAP_ENABLE_TLS,
+       if (addrindex_write_attr( fp, ATTAG_LDAP_ENABLE_TLS,
                        ctl->enableTLS ?
-                       ATVAL_BOOLEAN_YES : ATVAL_BOOLEAN_NO );
-       addrindex_write_attr( fp, ATTAG_LDAP_ENABLE_SSL,
+                       ATVAL_BOOLEAN_YES : ATVAL_BOOLEAN_NO ) < 0)
+               return -1;
+       if (addrindex_write_attr( fp, ATTAG_LDAP_ENABLE_SSL,
                        ctl->enableSSL ?
-                       ATVAL_BOOLEAN_YES : ATVAL_BOOLEAN_NO );
+                       ATVAL_BOOLEAN_YES : ATVAL_BOOLEAN_NO ) < 0)
+               return -1;
 
-       fputs(" >\n", fp);
+       if (fputs(" >\n", fp) == EOF)
+               return -1;
 
        /* Output attributes */
        node = ldapctl_get_criteria_list( ctl );
        while( node ) {
-               addrindex_write_elem_s( fp, 1+lvl, ELTAG_LDAP_ATTR_SRCH );
-               addrindex_write_attr( fp, ATTAG_LDAP_ATTR_NAME, node->data );
-               fputs(" />\n", fp);
+               if (addrindex_write_elem_s( fp, 1+lvl, ELTAG_LDAP_ATTR_SRCH ) < 0)
+                       return -1;
+               if (addrindex_write_attr( fp, ATTAG_LDAP_ATTR_NAME, node->data ) < 0)
+                       return -1;
+               if (fputs(" />\n", fp) == EOF)
+                       return -1;
                node = g_list_next( node );
        }
 
        /* End of element */    
-       addrindex_write_elem_e( fp, lvl, TAG_DS_LDAP );
+       if (addrindex_write_elem_e( fp, lvl, TAG_DS_LDAP ) < 0)
+               return -1;
+       
+       return 0;
 }
 
 #else
@@ -1496,11 +1552,13 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
        return ds;
 }
 
-static void addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) {
+static int addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) {
        AddressIfFragment *fragment = ds->rawDataSource;
        if( fragment ) {
-               addrindex_write_fragment( fp, fragment, lvl );
+               if (addrindex_write_fragment( fp, fragment, lvl ) < 0)
+                       return -1;
        }
+       return 0;
 }
 #endif
 
@@ -1516,7 +1574,6 @@ static void addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) {
  * \param  file Address index file.
  */
 static void addrindex_read_index( AddressIndex *addrIndex, XMLFile *file ) {
-       guint prev_level;
        XMLTag *xtag;
        AddressInterface *iface = NULL, *dsIFace = NULL;
        AddressDataSource *ds;
@@ -1524,9 +1581,8 @@ static void addrindex_read_index( AddressIndex *addrIndex, XMLFile *file ) {
 
        addrIndex->loadedFlag = FALSE;
        for (;;) {
-               prev_level = file->level;
                rc = xml_parse_next_tag( file );
-               if( file->level == 0 ) return;
+               if( rc < 0 || file->level == 0 ) return;
 
                xtag = xml_get_current_tag( file );
 
@@ -1609,7 +1665,7 @@ static gint addrindex_read_file( AddressIndex *addrIndex ) {
        XMLFile *file = NULL;
        gchar *fileSpec = NULL;
 
-       g_return_val_if_fail( addrIndex != NULL, -1 );
+       cm_return_val_if_fail( addrIndex != NULL, -1 );
 
        fileSpec = g_strconcat( addrIndex->filePath, G_DIR_SEPARATOR_S, addrIndex->fileName, NULL );
        addrIndex->retVal = MGU_NO_FILE;
@@ -1618,7 +1674,7 @@ static gint addrindex_read_file( AddressIndex *addrIndex ) {
 
        if( file == NULL ) {
                /*
-               fprintf( stdout, " file '%s' does not exist.\n", addrIndex->fileName );
+               g_print( " file '%s' does not exist.\n", addrIndex->fileName );
                */
                return addrIndex->retVal;
        }
@@ -1639,7 +1695,7 @@ static gint addrindex_read_file( AddressIndex *addrIndex ) {
        return addrIndex->retVal;
 }
 
-static void addrindex_write_index( AddressIndex *addrIndex, FILE *fp ) {
+static int addrindex_write_index( AddressIndex *addrIndex, FILE *fp ) {
        GList *nodeIF, *nodeDS;
        gint lvlList = 1;
        gint lvlItem = 1 + lvlList;
@@ -1649,30 +1705,38 @@ static void addrindex_write_index( AddressIndex *addrIndex, FILE *fp ) {
                AddressInterface *iface = nodeIF->data;
                if( ! iface->legacyFlag ) {
                        nodeDS = iface->listSource;
-                       addrindex_write_elem_s( fp, lvlList, iface->listTag );
-                       fputs( ">\n", fp );
+                       if (addrindex_write_elem_s( fp, lvlList, iface->listTag ) < 0)
+                               return -1;
+                       if (fputs( ">\n", fp ) == EOF)
+                               return -1;
                        while( nodeDS ) {
                                AddressDataSource *ds = nodeDS->data;
                                if( ds ) {
                                        if( iface->type == ADDR_IF_BOOK ) {
-                                               addrindex_write_book( fp, ds, lvlItem );
+                                               if (addrindex_write_book( fp, ds, lvlItem ) < 0)
+                                                       return -1;
                                        }
                                        if( iface->type == ADDR_IF_VCARD ) {
-                                               addrindex_write_vcard( fp, ds, lvlItem );
+                                               if (addrindex_write_vcard( fp, ds, lvlItem ) < 0)
+                                                       return -1;
                                        }
                                        if( iface->type == ADDR_IF_JPILOT ) {
-                                               addrindex_write_jpilot( fp, ds, lvlItem );
+                                               if (addrindex_write_jpilot( fp, ds, lvlItem ) < 0)
+                                                       return -1;
                                        }
                                        if( iface->type == ADDR_IF_LDAP ) {
-                                               addrindex_write_ldap( fp, ds, lvlItem );
+                                               if (addrindex_write_ldap( fp, ds, lvlItem ) < 0)
+                                                       return -1;
                                        }
                                }
                                nodeDS = g_list_next( nodeDS );
                        }
-                       addrindex_write_elem_e( fp, lvlList, iface->listTag );
+                       if (addrindex_write_elem_e( fp, lvlList, iface->listTag ) < 0)
+                               return -1;
                }
                nodeIF = g_list_next( nodeIF );
        }
+       return 0;
 }
 
 /*
@@ -1682,14 +1746,14 @@ static void addrindex_write_index( AddressIndex *addrIndex, FILE *fp ) {
 * 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 ) {
+static 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 );
+       cm_return_val_if_fail( addrIndex != NULL, -1 );
 
        fileSpec = g_strconcat( addrIndex->filePath, G_DIR_SEPARATOR_S, newFile, NULL );
        addrIndex->retVal = MGU_OPEN_FILE;
@@ -1703,13 +1767,18 @@ gint addrindex_write_to( AddressIndex *addrIndex, const gchar *newFile ) {
        g_free( fileSpec );
        if( pfile ) {
                fp = pfile->fp;
-               fprintf( fp, "<?xml version=\"1.0\" encoding=\"%s\" ?>\n", CS_INTERNAL );
+               if (fprintf( fp, "<?xml version=\"1.0\" encoding=\"%s\" ?>\n", CS_INTERNAL ) < 0)
+                       goto fail;
 #endif
-               addrindex_write_elem_s( fp, 0, TAG_ADDRESS_INDEX );
-               fputs( ">\n", fp );
+               if (addrindex_write_elem_s( fp, 0, TAG_ADDRESS_INDEX ) < 0)
+                       goto fail;
+               if (fputs( ">\n", fp ) == EOF)
+                       goto fail;
 
-               addrindex_write_index( addrIndex, fp );
-               addrindex_write_elem_e( fp, 0, TAG_ADDRESS_INDEX );
+               if (addrindex_write_index( addrIndex, fp ) < 0)
+                       goto fail;
+               if (addrindex_write_elem_e( fp, 0, TAG_ADDRESS_INDEX ) < 0)
+                       goto fail;
 
                addrIndex->retVal = MGU_SUCCESS;
 #ifdef DEV_STANDALONE
@@ -1723,6 +1792,12 @@ gint addrindex_write_to( AddressIndex *addrIndex, const gchar *newFile ) {
 
        fileSpec = NULL;
        return addrIndex->retVal;
+fail:
+       g_warning("error writing AB index");
+       addrIndex->retVal = MGU_ERROR_WRITE;
+       if (pfile)
+               prefs_file_close_revert( pfile );
+       return addrIndex->retVal;
 }
 
 /*
@@ -1730,8 +1805,44 @@ gint addrindex_write_to( AddressIndex *addrIndex, const gchar *newFile ) {
 * return: Status code, from addrIndex->retVal.
 */
 gint addrindex_save_data( AddressIndex *addrIndex ) {
-       g_return_val_if_fail( addrIndex != NULL, -1 );
+#ifdef USE_LDAP
+       GList *nodeIf;
+       GList *nodeDS;
+#endif
+       
+       cm_return_val_if_fail( addrIndex != NULL, -1 );
 
+#ifdef USE_LDAP
+       nodeIf = addrIndex->interfaceList;
+       /* save LDAP interfaces */
+       while ( nodeIf ) {
+               AddressInterface *iface = nodeIf->data;
+               if( iface->type == ADDR_IF_LDAP ) {
+                       nodeDS = iface->listSource;
+                       while( nodeDS ) {
+                               AddressDataSource *ds = nodeDS->data;
+                               LdapServer *abf = ds->rawDataSource;
+                               if( ldapsvr_get_read_flag( abf ) ) {
+                                       if( ldapsvr_get_modified( abf ) ) {
+                                               ldapsvr_update_book( abf, NULL );
+                                               if( abf->retVal != LDAPRC_SUCCESS ) {
+                                                       alertpanel( _("Address(es) update"),
+                                                               _("Update failed. Changes not written to Directory."),
+                                                               GTK_STOCK_CLOSE, NULL, NULL );
+                                               }
+                                               else {
+                                                       abf->retVal = MGU_SUCCESS;
+                                                       ldapsvr_set_modified( abf, FALSE );
+                                               }
+                                       }
+                               }
+                               nodeDS = g_list_next( nodeDS );
+                       }
+                       break;
+               }
+               nodeIf = g_list_next( nodeIf );
+       }
+#endif
        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;
@@ -1895,8 +2006,7 @@ static void addrindex_add_obj( XMLFile *file, AddressCvtNode *node ) {
                        node->list = g_list_append( node->list, newNode );
                }
                else {
-                       /* printf( "invalid: !!! \n" ); */
-                       attr = xml_get_current_tag_attr( file );
+                       g_warning("Invalid tag");
                }
        }
 }
@@ -1906,47 +2016,17 @@ static void addrindex_add_obj( XMLFile *file, AddressCvtNode *node ) {
 */
 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;
+               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.
 */
@@ -2110,8 +2190,6 @@ static gboolean addrindex_process_book( AddressIndex *addrIndex, XMLFile *file,
 */
 static void addrindex_convert_tree( AddressIndex *addrIndex, XMLFile *file ) {
        guint prev_level;
-       gchar *element;
-       GList *attr;
        XMLTag *xtag;
 
        /* Process file */
@@ -2121,7 +2199,7 @@ static void addrindex_convert_tree( AddressIndex *addrIndex, XMLFile *file ) {
                if (file->level < prev_level) return;
 
                xtag = xml_get_current_tag( file );
-               /* printf( "tag : %d : %s\n", prev_level, xtag->tag ); */
+               /* g_print( "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;
@@ -2138,10 +2216,6 @@ static void addrindex_convert_tree( AddressIndex *addrIndex, XMLFile *file ) {
                        }
                        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 );
        }
 }
@@ -2156,7 +2230,7 @@ static gint addrindex_convert_data( AddressIndex *addrIndex ) {
        g_free( fileSpec );
 
        if( file == NULL ) {
-               /* fprintf( stdout, " file '%s' does not exist.\n", addrIndex->fileName ); */
+               /* g_print( " file '%s' does not exist.\n", addrIndex->fileName ); */
                return addrIndex->retVal;
        }
 
@@ -2229,18 +2303,16 @@ static gboolean addrindex_create_new_book( AddressIndex *addrIndex, gchar *displ
 *      "Gathered addresses" - a new address book.
 */
 gint addrindex_read_data( AddressIndex *addrIndex ) {
-       g_return_val_if_fail( addrIndex != NULL, -1 );
+       cm_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 {
+                       if( addrindex_convert_data( addrIndex ) == MGU_SUCCESS )
+                               addrIndex->conversionError = FALSE;
+                       else
                                addrIndex->conversionError = TRUE;
-                       }
                }
                addrIndex->dirtyFlag = TRUE;
        }
@@ -2260,7 +2332,7 @@ gint addrindex_read_data( AddressIndex *addrIndex ) {
 gint addrindex_create_new_books( AddressIndex *addrIndex ) {
        gboolean flg;
 
-       g_return_val_if_fail( addrIndex != NULL, -1 );
+       cm_return_val_if_fail( addrIndex != NULL, -1 );
 
        flg = addrindex_create_new_book( addrIndex, DISP_NEW_COMMON );
        if( flg ) {
@@ -2352,7 +2424,7 @@ gint addrindex_ds_read_data( AddressDataSource *ds ) {
        if( iface->getReadData ) {
                /*
                gchar *name = ( iface->getName ) ( ds->rawDataSource );
-               printf( "addrindex_ds_read_data...reading:::%s:::\n", name );
+               g_print( "addrindex_ds_read_data...reading:::%s:::\n", name );
                */
                retVal = ( iface->getReadData ) ( ds->rawDataSource );
        }
@@ -2375,38 +2447,6 @@ ItemFolder *addrindex_ds_get_root_folder( AddressDataSource *ds ) {
        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.
  */
@@ -2451,7 +2491,7 @@ gboolean addrindex_ds_get_readonly( AddressDataSource *ds ) {
 /*
  * Return list of all persons for specified data source.
  */
-GList *addrindex_ds_get_all_persons( AddressDataSource *ds ) {
+static GList *addrindex_ds_get_all_persons( AddressDataSource *ds ) {
        GList *retVal = NULL;
        AddressInterface *iface;
 
@@ -2467,7 +2507,7 @@ GList *addrindex_ds_get_all_persons( AddressDataSource *ds ) {
 /*
  * Return list of all groups for specified data source.
  */
-GList *addrindex_ds_get_all_groups( AddressDataSource *ds ) {
+static GList *addrindex_ds_get_all_groups( AddressDataSource *ds ) {
        GList *retVal = NULL;
        AddressInterface *iface;
 
@@ -2507,7 +2547,7 @@ gint addrindex_setup_search(
        queryID = req->queryID;
        qryreq_set_search_type( req, ADDRSEARCH_DYNAMIC );
 
-       /* printf( "***> query ID ::%d::\n", queryID ); */
+       /* g_print( "***> query ID ::%d::\n", queryID ); */
        return queryID;
 }
 
@@ -2539,7 +2579,7 @@ static gboolean addrindex_start_dynamic( QueryRequest *req ) {
        GList *nodeDS;
        gint type;
 
-       /* printf( "addrindex_start_dynamic::%d::\n", req->queryID ); */
+       /* g_print( "addrindex_start_dynamic::%d::\n", req->queryID ); */
        nodeIf = _addressIndex_->searchOrder;
        while( nodeIf ) {
                iface = nodeIf->data;
@@ -2592,7 +2632,7 @@ void addrindex_stop_search( const gint queryID ){
        AddrQueryObject *aqo;
        GList *node;
 
-       /* printf( "addrindex_stop_search/queryID=%d\n", queryID ); */
+       /* g_print( "addrindex_stop_search/queryID=%d\n", queryID ); */
        /* If query ID does not match, search has not been setup */
        req = qrymgr_find_request( queryID );
        if( req == NULL ) {
@@ -2714,7 +2754,7 @@ gboolean addrindex_start_search( const gint queryID ) {
        AddrSearchType searchType;
 
        retVal = FALSE;
-       /* printf( "addrindex_start_search/queryID=%d\n", queryID ); */
+       /* g_print( "addrindex_start_search/queryID=%d\n", queryID ); */
        req = qrymgr_find_request( queryID );
        if( req == NULL ) {
                return retVal;
@@ -2738,17 +2778,15 @@ gboolean addrindex_start_search( const gint queryID ) {
  */
 void addrindex_remove_results( AddressDataSource *ds, ItemFolder *folder ) {
        AddrBookBase *adbase;
-       AddressCache *cache;
        gint queryID = 0;
 
-       /* printf( "addrindex_remove_results/start\n" ); */
+       /* g_print( "addrindex_remove_results/start\n" ); */
 
        /* Test for folder */
        if( folder->folderType != ADDRFOLDER_QUERY_RESULTS ) return;
-       /* printf( "folder name ::%s::\n", ADDRITEM_NAME(folder) ); */
+       /* g_print( "folder name ::%s::\n", ADDRITEM_NAME(folder) ); */
        adbase = ( AddrBookBase * ) ds->rawDataSource;
        if( adbase == NULL ) return;
-       cache = adbase->addressCache;
 
        /* Hide folder to prevent re-display */
        addritem_folder_set_hidden( folder, TRUE );
@@ -2760,24 +2798,23 @@ void addrindex_remove_results( AddressDataSource *ds, ItemFolder *folder ) {
 
                qry = ( LdapQuery * ) folder->folderData;
                queryID = ADDRQUERY_ID(qry);
-               /* printf( "calling ldapquery_remove_results...queryID=%d\n", queryID ); */
+               /* g_print( "calling ldapquery_remove_results...queryID=%d\n", queryID ); */
                delFlag = ldapquery_remove_results( qry );
                if (delFlag) {
                        ldapqry_free( qry );
                }
-               /* printf( "calling ldapquery_remove_results...done\n" ); */
+               /* g_print( "calling ldapquery_remove_results...done\n" ); */
                /*
                if( delFlag ) {
-                       printf( "delFlag IS-TRUE\n" );
+                       g_print( "delFlag IS-TRUE\n" );
                }
                else {
-                       printf( "delFlag IS-FALSE\n" );
-                       addressbook_clear_idler( queryID );
+                       g_print( "delFlag IS-FALSE\n" );
                }
                */
 #endif
        }
-       /* printf( "addrindex_remove_results/end\n" ); */
+       /* g_print( "addrindex_remove_results/end\n" ); */
 
        /* Delete query request */
        if( queryID > 0 ) {
@@ -2883,59 +2920,61 @@ gboolean addrindex_load_completion(
                   folderpath must not be empty or NULL */
                
                if( ! addressbook_peek_folder_exists( folderpath, &book, &folder ) ) {
-                       g_warning("addrindex_load_completion: folder path '%s' doesn't exist\n", folderpath);
+                       g_warning("addrindex_load_completion: folder path '%s' doesn't exist", folderpath);
                        return FALSE;
                }
 
-               if( book != NULL ) {
-                       AddressBookFile *abf = book->rawDataSource;
+               if( folder != NULL ) {
 
-                       debug_print("addrindex_load_completion: book %p '%s'\n", book, abf->fileName);
+                       GList *items;
+                       GList *nodeM;
+                       gchar *sName;
+                       ItemPerson *person;
 
-                       addrindex_load_completion_load_persons( callBackFunc, book );
+                       debug_print("addrindex_load_completion: folder %p '%s'\n", folder, folder->obj.name);
 
-                       return TRUE;
+                       /* Load email addresses */
+                       items = addritem_folder_get_person_list( folder );
+                       for( ; items != NULL; items = g_list_next( items ) ) {
+                               person = items->data;
+                               nodeM = person->listEMail;
 
-               } else {
+                               /* Figure out name to use */
+                               sName = ADDRITEM_NAME(person);
+                               if( sName == NULL || *sName == '\0' ) {
+                                       sName = person->nickName;
+                               }
 
-                       if( folder != NULL ) {
-                               GList *items;
-                               GList *nodeM;
-                               gchar *sName;
-                               ItemPerson *person;
+                               /* Process each E-Mail address */
+                               while( nodeM ) {
+                                       ItemEMail *email = nodeM->data;
 
-                               debug_print("addrindex_load_completion: folder %p '%s'\n", folder, folder->obj.name);
+                                       callBackFunc( sName, email->address, person->nickName, 
+                                                         ADDRITEM_NAME(email), NULL );
 
-                               /* Load email addresses */
-                               items = addritem_folder_get_person_list( folder );
-                               for( ; items != NULL; items = g_list_next( items ) ) {
-                                       person = items->data;
-                                       nodeM = person->listEMail;
+                                       nodeM = g_list_next( nodeM );
+                               }
+                       }
+                       /* Free up the list */
+                       mgu_clear_list( items );
+                       g_list_free( items );
 
-                                       /* Figure out name to use */
-                                       sName = ADDRITEM_NAME(person);
-                                       if( sName == NULL || *sName == '\0' ) {
-                                               sName = person->nickName;
-                                       }
+                       return TRUE;
 
-                                       /* Process each E-Mail address */
-                                       while( nodeM ) {
-                                               ItemEMail *email = nodeM->data;
+               } else {
 
-                                               callBackFunc( sName, email->address, person->nickName, 
-                                                                 ADDRITEM_NAME(email), NULL );
+                       if( book != NULL ) {
 
-                                               nodeM = g_list_next( nodeM );
-                                       }
-                               }
-                               /* Free up the list */
-                               mgu_clear_list( items );
-                               g_list_free( items );
+                               AddressBookFile *abf = book->rawDataSource;
+
+                               debug_print("addrindex_load_completion: book %p '%s'\n", book, abf?abf->fileName:"(null)");
+
+                               addrindex_load_completion_load_persons( callBackFunc, book );
 
                                return TRUE;
 
                        } else {
-                               g_warning("addrindex_load_completion: book/folder path is valid but got no pointer\n");
+                               g_warning("addrindex_load_completion: book/folder path is valid but got no pointer");
                        }
                }
                return FALSE;
@@ -3040,6 +3079,173 @@ gboolean addrindex_load_person_attribute(
        return TRUE;
 }
 
+/**
+ * This function can be used to collect information about
+ * addressbook entries
+ *
+ * \param callBackFunc Function to be called for each ItemPerson
+ * \return <i>TRUE</i>
+ */
+gboolean addrindex_load_person_ds( gint (*callBackFunc)
+                       ( ItemPerson *, AddressDataSource * ) )
+{
+       AddressDataSource *ds;
+       GList *nodeIf, *nodeDS;
+       GList *listP, *nodeP;
+
+       nodeIf = addrindex_get_interface_list( _addressIndex_ );
+       while( nodeIf ) {
+               AddressInterface *iface = nodeIf->data;
+
+               nodeIf = g_list_next( nodeIf );
+
+               if( ! iface->useInterface || iface->externalQuery )
+                       continue;
+
+               nodeDS = iface->listSource;
+               while( nodeDS ) {
+                       ds = nodeDS->data;
+
+                       /* Read address book */
+                       if( addrindex_ds_get_modify_flag( ds ) ) {
+                               addrindex_ds_read_data( ds );
+                       }
+
+                       if( ! addrindex_ds_get_read_flag( ds ) ) {
+                               addrindex_ds_read_data( ds );
+                       }
+
+                       /* Get all persons */
+                       listP = addrindex_ds_get_all_persons( ds );
+                       nodeP = listP;
+                       while( nodeP ) {
+                               ItemPerson *person = nodeP->data;
+
+                               callBackFunc(person, ds);
+                               nodeP = g_list_next( nodeP );
+                       }
+                       /* Free up the list */
+                       g_list_free( listP );
+
+                       nodeDS = g_list_next( nodeDS );
+               }
+       }
+       return TRUE;
+}
+
+gchar *addrindex_get_picture_file(const gchar *emailaddr)
+{
+       AddressDataSource *ds;
+       GList *nodeIf, *nodeDS;
+       GList *listP, *nodeP;
+       gboolean found = FALSE;
+       gchar *filename = NULL;
+       gchar *raw_addr = NULL;
+       
+       if (!emailaddr)
+               return NULL;
+
+       Xstrdup_a(raw_addr, emailaddr, return NULL);
+       extract_address(raw_addr);
+
+       nodeIf = addrindex_get_interface_list( _addressIndex_ );
+       while( nodeIf ) {
+               AddressInterface *iface = nodeIf->data;
+
+               nodeIf = g_list_next( nodeIf );
+
+               if( ! iface->useInterface || iface->externalQuery )
+                       continue;
+
+               nodeDS = iface->listSource;
+               while( nodeDS && !found) {
+                       ds = nodeDS->data;
+
+                       /* Read address book */
+                       if( addrindex_ds_get_modify_flag( ds ) ) {
+                               addrindex_ds_read_data( ds );
+                       }
+
+                       if( ! addrindex_ds_get_read_flag( ds ) ) {
+                               addrindex_ds_read_data( ds );
+                       }
+
+                       /* Get all persons */
+                       listP = addrindex_ds_get_all_persons( ds );
+                       nodeP = listP;
+                       while( nodeP ) {
+                               GList *nodeM;
+                               ItemPerson *person = nodeP->data;
+                               nodeM = person->listEMail;
+                               while(nodeM) {
+                                       ItemEMail *email = nodeM->data;
+                                       if (email->address && !strcasecmp(raw_addr, email->address)) {
+                                               found = TRUE;
+                                               filename = g_strconcat( get_rc_dir(), G_DIR_SEPARATOR_S, 
+                                                       ADDRBOOK_DIR, G_DIR_SEPARATOR_S, 
+                                                       person->picture, ".png", NULL );
+                                               break;
+                                       }
+                                       nodeM = nodeM->next;
+                               }
+                               nodeP = g_list_next( nodeP );
+                       }
+                       /* Free up the list */
+                       g_list_free( listP );
+
+                       nodeDS = g_list_next( nodeDS );
+               }
+       }
+
+       return filename;
+}
+
+#ifdef USE_LDAP
+GSList *addrindex_get_password_protected_ldap_servers()
+{
+       AddressInterface *iface;
+       AddressDataSource *ds;
+       GList *nodeIf;
+       GList *nodeDS;
+       GSList *list = NULL;
+       LdapServer *server;
+       LdapControl *ctl;
+
+       nodeIf = _addressIndex_->searchOrder;
+       while (nodeIf) {
+               iface = nodeIf->data;
+               nodeIf = g_list_next(nodeIf);
+
+               if (!iface->useInterface)
+                       continue;
+               if (!iface->externalQuery)
+                       continue;
+               if (iface->type != ADDR_IF_LDAP)
+                       continue;
+
+               nodeDS = iface->listSource;
+               while (nodeDS) {
+                       ds = nodeDS->data;
+                       nodeDS = g_list_next(nodeDS);
+                       server = ds->rawDataSource;
+                       if (!server->searchFlag)
+                               continue;
+
+                       ctl = server->control;
+
+                       if (!ctl)
+                               continue;
+
+                       if (ctl->bindDN != NULL && strlen(ctl->bindDN)) {
+                               list = g_slist_append(list, server);
+                       }
+               }
+       }
+
+       return list;
+}
+#endif /* USE_LDAP */
+
 /*
  * End of Source.
  */