2006-07-31 [wwp] 2.4.0cvs3
[claws.git] / src / addrindex.c
index 65f2dfe5dca3dc0938dc9283ec7d0dc5201b7747..f98ca944c8dcf690988bd27e42a955964d7222d1 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 2001-2004 Match Grun
+ * Copyright (C) 2001-2006 Match Grun and the Sylpheed-Claws 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
@@ -34,6 +34,7 @@
 #include "addritem.h"
 #include "addrcache.h"
 #include "addrbook.h"
+#include "addressbook.h"
 #include "addrindex.h"
 #include "xml.h"
 #include "addrquery.h"
@@ -98,6 +99,7 @@
 #define ATTAG_LDAP_DYN_SEARCH "dyn-search"
 #define ATTAG_LDAP_MATCH_OPT  "match-opt"
 #define ATTAG_LDAP_ENABLE_TLS "enable-tls"
+#define ATTAG_LDAP_ENABLE_SSL "enable-ssl"
 
 #define ELTAG_LDAP_ATTR_SRCH  "attribute"
 #define ATTAG_LDAP_ATTR_NAME  "name"
 /* New attributes */
 #define ATTAG_LDAP_DEFAULT    "default"
 
-#if 0
-N_("Common address")
-N_("Personal address")
-#endif
-
 #define DISP_NEW_COMMON       _("Common addresses")
 #define DISP_NEW_PERSONAL     _("Personal addresses")
 
@@ -1080,37 +1077,6 @@ static void addrindex_write_fragment(
        }
 }
 
-#if 0
-static void addrindex_print_fragment_r(
-               const AddressIfFragment *fragment, FILE *stream, gint lvl )
-{
-       GList *node;
-       gint i;
-
-       for( i = 0; i < lvl; i++ )
-               fprintf( stream, "  " );
-       fprintf( stream, "Element:%s:\n", fragment->name );
-       node = fragment->attributes;
-       while( node ) {
-               AddressIfAttrib *nv = node->data;
-               for( i = 0; i < lvl; i++ )
-                       fprintf( stream, "  " );
-               fprintf( stream, "    %s : %s\n", nv->name, nv->value );
-               node = g_list_next( node );
-       }
-       node = fragment->children;
-       while( node ) {
-               AddressIfFragment *child = node->data;
-               addrindex_print_fragment_r( child, stream, 1+lvl );
-               node = g_list_next( node );
-       }
-}
-
-static void addrindex_print_fragment( const AddressIfFragment *fragment, FILE *stream ) {
-       addrindex_print_fragment_r( fragment, stream, 0 );
-}
-#endif
-
 /**
  * Read/parse address index file, creating a data source for a regular
  * intrinsic XML addressbook.
@@ -1351,13 +1317,14 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
        gchar *serverName = NULL;
        gchar *criteria = NULL;
        gboolean bDynSearch;
-       gboolean bTLS;
+       gboolean bTLS, bSSL;
        gint iMatch;
 
        /* printf( "addrindex_parse_ldap\n" ); */
        /* Set up some defaults */
        bDynSearch = FALSE;
        bTLS = FALSE;
+       bSSL = FALSE;
        iMatch = LDAPCTL_MATCH_BEGINWITH;
 
        ds = addrindex_create_datasource( ADDR_IF_LDAP );
@@ -1369,7 +1336,7 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
                gint ivalue = atoi( value );
 
                if( strcmp( name, ATTAG_LDAP_NAME ) == 0 ) {
-                       if( serverName ) g_free( serverName );
+                       g_free( serverName );
                        serverName = g_strdup( value );
                }
                else if( strcmp( name, ATTAG_LDAP_HOST ) == 0 ) {
@@ -1388,7 +1355,7 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
                        ldapctl_set_bind_password( ctl, value );
                }
                else if( strcmp( name, ATTAG_LDAP_CRITERIA ) == 0 ) {
-                       if( criteria ) g_free( criteria );
+                       g_free( criteria );
                        criteria = g_strdup( value );
                }
                else if( strcmp( name, ATTAG_LDAP_MAX_ENTRY ) == 0 ) {
@@ -1418,6 +1385,12 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
                                bTLS = TRUE;
                        }
                }
+               else if( strcmp( name, ATTAG_LDAP_ENABLE_SSL ) == 0 ) {
+                       bSSL = FALSE;
+                       if( strcmp( value, ATVAL_BOOLEAN_YES ) == 0 ) {
+                               bSSL = TRUE;
+                       }
+               }
                attr = g_list_next( attr );
        }
 
@@ -1425,7 +1398,10 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
        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;
@@ -1488,6 +1464,9 @@ static void addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) {
        addrindex_write_attr( fp, ATTAG_LDAP_ENABLE_TLS,
                        ctl->enableTLS ?
                        ATVAL_BOOLEAN_YES : ATVAL_BOOLEAN_NO );
+       addrindex_write_attr( fp, ATTAG_LDAP_ENABLE_SSL,
+                       ctl->enableSSL ?
+                       ATVAL_BOOLEAN_YES : ATVAL_BOOLEAN_NO );
 
        fputs(" >\n", fp);
 
@@ -2810,39 +2789,15 @@ void addrindex_remove_results( AddressDataSource *ds, ItemFolder *folder ) {
 * ***********************************************************************
 */
 
-/**
- * This function is used by the address completion function to load
- * addresses for all non-external address book interfaces.
- *
- * \param callBackFunc Function to be called when an address is
- *                     to be loaded.
- * \return <i>TRUE</i> if data loaded, <i>FALSE</i> if address index not loaded.
- */
-gboolean addrindex_load_completion(
+static void addrindex_load_completion_load_persons(
                gint (*callBackFunc) ( const gchar *, const gchar *, 
-                                      const gchar *, const gchar * ) )
+                                      const gchar *, const gchar * ),
+               AddressDataSource *ds)
 {
-       AddressDataSource *ds;
-       GList *nodeIf, *nodeDS;
        GList *listP, *nodeP;
        GList *nodeM;
        gchar *sName;
 
-       nodeIf = addrindex_get_interface_list( _addressIndex_ );
-       while( nodeIf ) {
-               AddressInterface *iface = nodeIf->data;
-
-               nodeIf = g_list_next( nodeIf );
-               if( ! iface->useInterface ) {
-                       continue;
-               }
-               if( 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 );
@@ -2878,10 +2833,111 @@ gboolean addrindex_load_completion(
                        }
                        /* Free up the list */
                        g_list_free( listP );
+}              
 
+/**
+ * This function is used by the address completion function to load
+ * addresses for all non-external address book interfaces.
+ *
+ * \param callBackFunc Function to be called when an address is
+ *                     to be loaded.
+ * \param folderpath Addressbook's Book/folder path to restrict to (if NULL or ""
+ *                     or "Any", assume the whole addressbook
+ * \return <i>TRUE</i> if data loaded, <i>FALSE</i> if address index not loaded.
+ */
+
+gboolean addrindex_load_completion(
+               gint (*callBackFunc) ( const gchar *, const gchar *, 
+                                      const gchar *, const gchar * ),
+               gchar *folderpath )
+{
+       GList *nodeIf, *nodeDS;
+
+       if( folderpath != NULL ) {
+               AddressDataSource *book;
+               ItemFolder* folder;
+
+               /* split the folder path we've received, we'll try to match this path, subpath by
+                  subpath against the book/folder structure in order and restrict loading of
+                  addresses to that subpart (if matches). book/folder path must exist and
+                  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);
+                       return FALSE;
+               }
+
+               if( book != NULL ) {
+                       AddressBookFile *abf = book->rawDataSource;
+
+                       debug_print("addrindex_load_completion: book %p '%s'\n", book, abf->fileName);
+
+                       addrindex_load_completion_load_persons( callBackFunc, book );
+
+                       return TRUE;
+
+               } else {
+
+                       if( folder != NULL ) {
+                               GList *items;
+                               GList *nodeM;
+                               gchar *sName;
+                               ItemPerson *person;
+
+                               debug_print("addrindex_load_completion: folder %p '%s'\n", folder, folder->obj.name);
+
+                               /* Load email addresses */
+                               items = addritem_folder_get_person_list( folder );
+                               for( ; items != NULL; items = g_list_next( items ) ) {
+                                       person = items->data;
+                                       nodeM = person->listEMail;
+
+                                       /* Figure out name to use */
+                                       sName = ADDRITEM_NAME(person);
+                                       if( sName == NULL || *sName == '\0' ) {
+                                               sName = person->nickName;
+                                       }
+
+                                       /* Process each E-Mail address */
+                                       while( nodeM ) {
+                                               ItemEMail *email = nodeM->data;
+
+                                               callBackFunc( sName, email->address, person->nickName, 
+                                                                 ADDRITEM_NAME(email) );
+
+                                               nodeM = g_list_next( nodeM );
+                                       }
+                               }
+                               /* Free up the list */
+                               mgu_clear_list( items );
+                               g_list_free( items );
+
+                               return TRUE;
+
+                       } else {
+                               g_warning("addrindex_load_completion: book/folder path is valid but got no pointer\n");
+                       }
+               }
+               return FALSE;
+
+       } else {
+
+               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 ) {
+                               addrindex_load_completion_load_persons( callBackFunc, nodeDS->data );
                        nodeDS = g_list_next( nodeDS );
                }
        }
+       }
 
        return TRUE;
 }
@@ -2909,12 +2965,10 @@ gboolean addrindex_load_person_attribute(
                AddressInterface *iface = nodeIf->data;
 
                nodeIf = g_list_next( nodeIf );
-               if( ! iface->useInterface ) {
-                       continue;
-               }
-               if( iface->externalQuery ) {
+
+               if( ! iface->useInterface || iface->externalQuery )
                        continue;
-               }
+
                nodeDS = iface->listSource;
                while( nodeDS ) {
                        ds = nodeDS->data;