LDAP static search.
authorMatch Grun <match@dimensional.com>
Sun, 7 Sep 2003 19:28:56 +0000 (19:28 +0000)
committerMatch Grun <match@dimensional.com>
Sun, 7 Sep 2003 19:28:56 +0000 (19:28 +0000)
src/addressbook.c
src/addressitem.h
src/addrindex.c
src/addritem.c
src/addritem.h
src/addrquery.c [new file with mode: 0644]
src/addrquery.h
src/ldapquery.c
src/ldapserver.c

index a76ca489c5a58cd44f47adc0584998093e1d2745..6daf690400b23cea8561f065e2526b091d7c92ab 100644 (file)
@@ -135,6 +135,8 @@ static GdkPixmap *categoryxpm;
 static GdkBitmap *categoryxpmmask;
 static GdkPixmap *ldapxpm;
 static GdkBitmap *ldapxpmmask;
+static GdkPixmap *addrsearchxpm;
+static GdkPixmap *addrsearchxpmmask;
 
 /* Message buffer */
 static gchar addressbook_msgbuf[ ADDRESSBOOK_MSGBUF_SIZE ];
@@ -862,6 +864,7 @@ static void addressbook_create(void)
        addrbook.listSelected = NULL;
        address_completion_start(window);
        gtk_widget_show_all(window);
+       gtk_widget_set_sensitive(addrbook.lup_btn, FALSE);
 
 }
 
@@ -938,7 +941,6 @@ static void addressbook_button_set_sensitive(void)
                        bcc_sens = TRUE;
        }
 
-       gtk_widget_set_sensitive(addrbook.lup_btn, FALSE);
        gtk_widget_set_sensitive(addrbook.to_btn, to_sens);
        gtk_widget_set_sensitive(addrbook.cc_btn, cc_sens);
        gtk_widget_set_sensitive(addrbook.bcc_btn, bcc_sens);
@@ -1277,6 +1279,15 @@ static void addressbook_menuitem_set_sensitive( AddressObject *obj, GtkCTreeNode
        menu_set_sensitive( addrbook.menu_factory, "/Tools/Export LDIF...", canExport );
 }
 
+/**
+ * Address book tree callback function that responds to selection of tree
+ * items.
+ *
+ * \param ctree  Tree widget.
+ * \param node   Node that was selected.
+ * \param column Column number where selected occurred.
+ * \param data   Pointer to user data.
+ */
 static void addressbook_tree_selected(GtkCTree *ctree, GtkCTreeNode *node,
                                      gint column, gpointer data)
 {
@@ -1284,6 +1295,7 @@ static void addressbook_tree_selected(GtkCTree *ctree, GtkCTreeNode *node,
        AdapterDSource *ads = NULL;
        AddressDataSource *ds = NULL;
        ItemFolder *rootFolder = NULL;
+       AddressObjectType aot;
 
        addrbook.treeSelected = node;
        addrbook.listSelected = NULL;
@@ -1323,11 +1335,15 @@ static void addressbook_tree_selected(GtkCTree *ctree, GtkCTreeNode *node,
                        /* Load folders into the tree */
                        rootFolder = addrindex_ds_get_root_folder( ds );
                        if( ds->type == ADDR_IF_JPILOT ) {
-                               addressbook_node_add_folder( node, ds, rootFolder, ADDR_CATEGORY );
+                               aot = ADDR_CATEGORY;
+                       }
+                       else if( ds->type == ADDR_IF_LDAP ) {
+                               aot = ADDR_LDAP_QUERY;
                        }
                        else {
-                               addressbook_node_add_folder( node, ds, rootFolder, ADDR_ITEM_FOLDER );
+                               aot = ADDR_ITEM_FOLDER;
                        }
+                       addressbook_node_add_folder( node, ds, rootFolder, aot );
                        addrindex_ds_set_access_flag( ds, &tVal );
                        gtk_ctree_expand( ctree, node );
                }
@@ -1819,6 +1835,7 @@ static void addressbook_tree_button_pressed(GtkWidget *ctree,
        gboolean canTreeCut = FALSE;
        gboolean canTreeCopy = FALSE;
        gboolean canTreePaste = FALSE;
+       gboolean canLookup = FALSE;
 
        if( ! event ) return;
        addressbook_menubar_set_sensitive( FALSE );
@@ -1830,6 +1847,7 @@ static void addressbook_tree_button_pressed(GtkWidget *ctree,
        }
 
        menu_set_insensitive_all(GTK_MENU_SHELL(addrbook.tree_popup));
+       gtk_widget_set_sensitive( addrbook.lup_btn, FALSE );
 
        if( obj == NULL ) return;
 
@@ -1852,6 +1870,7 @@ static void addressbook_tree_button_pressed(GtkWidget *ctree,
                        gtk_widget_set_sensitive( addrbook.reg_btn, TRUE );
                }
                canTreeCopy = TRUE;
+               if( iface->externalQuery ) canLookup = TRUE;
        }
        else if (obj->type == ADDR_ITEM_FOLDER) {
                ds = addressbook_find_datasource( addrbook.treeSelected );
@@ -1868,6 +1887,8 @@ static void addressbook_tree_button_pressed(GtkWidget *ctree,
                        gtk_widget_set_sensitive( addrbook.reg_btn, TRUE );
                }
                canTreeCopy = TRUE;
+               iface = ds->interface;
+               if( iface->externalQuery ) canLookup = TRUE;
        }
        else if (obj->type == ADDR_ITEM_GROUP) {
                ds = addressbook_find_datasource( addrbook.treeSelected );
@@ -1902,6 +1923,8 @@ static void addressbook_tree_button_pressed(GtkWidget *ctree,
        menu_set_sensitive( addrbook.menu_factory, "/Edit/Paste",         canPaste );
        menu_set_sensitive( addrbook.menu_factory, "/Edit/Paste Address", canPaste );
 
+       gtk_widget_set_sensitive( addrbook.lup_btn, canLookup );
+
        if( event->button == 3 ) {
                gtk_menu_popup(GTK_MENU(addrbook.tree_popup), NULL, NULL, NULL, NULL,
                               event->button, event->time);
@@ -3091,7 +3114,10 @@ static GtkCTreeNode *addressbook_add_object(GtkCTreeNode *node,
 *        itemGroup Group to add.
 * Return: Inserted node.
 */
-static GtkCTreeNode *addressbook_node_add_group( GtkCTreeNode *node, AddressDataSource *ds, ItemGroup *itemGroup ) {
+static GtkCTreeNode *addressbook_node_add_group(
+               GtkCTreeNode *node, AddressDataSource *ds,
+               ItemGroup *itemGroup )
+{
        GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
        GtkCTreeNode *newNode;
        AdapterGroup *adapter;
@@ -3119,13 +3145,16 @@ static GtkCTreeNode *addressbook_node_add_group( GtkCTreeNode *node, AddressData
        return newNode;
 }
 
-/*
-* Add folder into the address index tree.
-* Enter: node      Parent node.
-*        ds         Data source.
-*        itemFolder Folder to add.
-*        otype      Object type to display.
-* Return: Inserted node.
+/**
+ * Add folder into the address index tree. Only visible folders are loaded into
+ * the address index tree. Note that the root folder is not inserted into the
+ * tree.
+ *
+ * \param  node              Parent node.
+ * \param  ds         Data source.
+ * \param  itemFolder Folder to add.
+ * \param  otype      Object type to display.
+ * \return Inserted node for the folder.
 */
 static GtkCTreeNode *addressbook_node_add_folder(
                GtkCTreeNode *node, AddressDataSource *ds,
@@ -3136,9 +3165,12 @@ static GtkCTreeNode *addressbook_node_add_folder(
        AdapterFolder *adapter;
        AddressTypeControlItem *atci = NULL;
        GList *listItems = NULL;
-       gchar **name;
+       gchar *name;
        ItemFolder *rootFolder;
 
+       /* Only visible folders */
+       if( itemFolder->isHidden ) return NULL;
+
        if( ds == NULL ) return NULL;
        if( node == NULL || itemFolder == NULL ) return NULL;
 
@@ -3151,14 +3183,13 @@ static GtkCTreeNode *addressbook_node_add_folder(
                newNode = node;
        }
        else {
-               name = &itemFolder->obj.name;
-
                adapter = g_new0( AdapterFolder, 1 );
                ADDRESS_OBJECT_TYPE(adapter) = ADDR_ITEM_FOLDER;
                ADDRESS_OBJECT_NAME(adapter) = g_strdup( ADDRITEM_NAME(itemFolder) );
                adapter->itemFolder = itemFolder;
 
-               newNode = gtk_ctree_insert_node( ctree, node, NULL, name, FOLDER_SPACING,
+               name = ADDRITEM_NAME(itemFolder);
+               newNode = gtk_ctree_insert_node( ctree, node, NULL, &name, FOLDER_SPACING,
                                atci->iconXpm, atci->maskXpm, atci->iconXpm, atci->maskXpm,
                                atci->treeLeaf, atci->treeExpand );
                if( newNode ) {
@@ -3331,147 +3362,193 @@ static void addressbook_new_ldap_cb( gpointer data, guint action, GtkWidget *wid
                }
        }
 }
+#endif
 
-static void addressbook_ldap_show_message( LdapServer *svr ) {
-       gchar *name;
-       gchar *desc;
+/**
+ * Display address search status message.
+ * \param queryType Query type.
+ * \param status    Status/Error code.
+ */
+static void addressbook_search_message( AddrQueryType queryType, gint sts ) {
+       gchar *desc = NULL;
        *addressbook_msgbuf = '\0';
-       if( svr ) {
-               name = ldapsvr_get_name( svr );
-               if( svr->retVal == MGU_SUCCESS ) {
-                       g_snprintf( addressbook_msgbuf,
-                                   sizeof(addressbook_msgbuf), "%s",
-                                   name );
+
+       if( sts != MGU_SUCCESS ) {
+               if( queryType == ADDRQUERY_LDAP ) {
+#ifdef USE_LDAP                        
+                       desc = addressbook_err2string( _lutErrorsLDAP_, sts );
+#endif
                }
                else {
-                       desc = addressbook_err2string(
-                                       _lutErrorsLDAP_, svr->retVal );
-                       g_snprintf( addressbook_msgbuf,
-                                   sizeof(addressbook_msgbuf),
-                                   "%s: %s", name, desc );
+                       desc = NULL;
                }
+               g_snprintf( addressbook_msgbuf,
+                       sizeof(addressbook_msgbuf), "%s", desc );
        }
        addressbook_status_show( addressbook_msgbuf );
 }
 
-static void addressbook_ldap_show_results( LdapServer *server ) {
-       GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
+/**
+ * Refresh addressbook by forcing refresh of current selected object in
+ * tree.
+ */
+static void addressbook_refresh_current( void ) {
        AddressObject *obj;
-       AdapterDSource *ads = NULL;
-       AddressDataSource *ds = NULL;
-       AddressInterface *iface = NULL;
-
-       if( server == NULL ) return;
-       if( ! addrbook.treeSelected ) return;
-       if( GTK_CTREE_ROW( addrbook.treeSelected )->level == 1 ) return;
+       GtkCTree *ctree;
 
+       ctree = GTK_CTREE(addrbook.ctree);
        obj = gtk_ctree_node_get_row_data( ctree, addrbook.treeSelected );
        if( obj == NULL ) return;
-       if( obj->type == ADDR_DATASOURCE ) {
-               ads = ADAPTER_DSOURCE(obj);
-               if( ads->subType == ADDR_LDAP ) {
-                       LdapServer *ldapSvr;
-
-                       ds = ads->dataSource;
-                       if( ds == NULL ) return;
-                       iface = ds->interface;
-                       if( ! iface->haveLibrary ) return;
-                       server = ds->rawDataSource;
-                       if( ldapSvr == server ) {
-                               /* Read from cache */
-                               gtk_widget_show_all(addrbook.window);
-                               addressbook_set_clist( obj );
-                               addressbook_ldap_show_message( server );
-                               gtk_widget_show_all(addrbook.window);
-                               gtk_entry_set_text( GTK_ENTRY(addrbook.entry), "" );
-                       }
-               }
-       }
+       addressbook_set_clist( obj );
 }
 
-static gint _idleID_ = 0;
-static gchar *_tempMessage_ = N_("Busy searching LDAP...");
+static gchar *_tempMessage_ = N_("Busy searching...");
 
-/*
- * LDAP idle function. This function is called during UI idle time while
- * an LDAP search is in progress.
- * Enter: data Reference to LDAP server object.
+/**
+ * Address search idle function. This function is called during UI idle time
+ * while a search is in progress.
+ *
+ * \param data Idler data.
  */
-static void addressbook_ldap_idle( gpointer data ) {
+static void addressbook_search_idle( gpointer data ) {
+       /*
+       gint queryID;
+
+       queryID = GPOINTER_TO_INT( data );
+       printf( "addressbook_ldap_idle... queryID=%d\n", queryID );
+       */
 }
 
-/*
- * LDAP search completion function.
+/**
+ * Search completion function. This removes the query from the idle list.
+ *
+ * \param queryID   Query to be removed.
+ * \param queryType Query type being removed.
+ * \param status    Search status.
  */
-static void addressbook_ldap_idle_end( void ) {
-       /* Server has completed search - remove from idle list */
-       printf( "addressbook_ldap_idle_end... completed" );
-       if( _idleID_ != 0 ) {
-               gtk_idle_remove( _idleID_ );
+static void addressbook_search_idle_end(
+               gint queryID, AddrQueryType queryType, gint status )
+{
+       gpointer data;
+
+       data = GINT_TO_POINTER( queryID );
+       if( data ) {
+               gtk_idle_remove_by_data( data );
        }
-       _idleID_ = 0;
+       addressbook_refresh_current();
+       addressbook_search_message( queryType, status );
 }
 
-/*
- * Perform lookup for LDAP search.
- * Enter: ads     Adapter for data source.
- *        sLookup Lookup string.
+/**
+ * Perform search.
+ *
+ * \param ds         Data source to search.
+ * \param searchTerm String to lookup.
+ * \param pNode      Parent data source node.
  */
-static void addressbook_ldap_lookup( AdapterDSource *ads, gchar *sLookup ) {
-       AddressDataSource *ds = NULL;
-       AddressInterface *iface = NULL;
-       LdapServer *server;
+static void addressbook_perform_search(
+               AddressDataSource *ds, gchar *searchTerm,
+               GtkCTreeNode *pNode )
+{
+       AddressBookFile *abf;
+       ItemFolder *folder;
+       GtkCTree *ctree;
+       GtkCTreeNode *nNode;
+       gchar *name;
+       gint queryID;
+       guint idleID;
+       AddressObjectType aoType;
+
+       if( ds->type == ADDR_IF_LDAP ) {
+#ifdef USE_LDAP
+               aoType = ADDR_LDAP_QUERY;
+#endif
+       }
+       else {
+               return;
+       }
+       abf = ds->rawDataSource;
+
+       /* Setup a query */
+       if( *searchTerm == '\0' || strlen( searchTerm ) < 1 ) return;
 
-       printf( "addressbook_ldap_lookup/Searching for '%s'\n", sLookup );
-       ds = ads->dataSource;
-       if( ds == NULL ) return;
-       iface = ds->interface;
-       if( ! iface->haveLibrary ) return;
-       server = ds->rawDataSource;
-       if( server ) {
-               printf( "addressbook_ldap_lookup/Starting.../1\n" );
-               if( *sLookup == '\0' || strlen( sLookup ) < 1 ) return;
 
-               /* Setup a query */
-               printf( "addressbook_ldap_lookup/Starting.../2\n" );
+       /* Create a folder for the search results */
+       folder = addrbook_add_new_folder( abf, NULL );
+       name = g_strdup_printf( "Search '%s'", searchTerm );
+       addritem_folder_set_name( folder, name );
+       addritem_folder_set_remarks( folder, "" );
+       g_free( name );
 
-               /* Sit back and wait for something to happen */
-               _idleID_ = gtk_idle_add(
-                       ( GtkFunction ) addressbook_ldap_idle, NULL );
-               addrindex_search_ldap_noid( server, sLookup, addressbook_ldap_idle_end  );
-               addressbook_status_show( _tempMessage_ );
+       /* Now let's see the folder */
+       ctree = GTK_CTREE(addrbook.ctree);
+       nNode = addressbook_node_add_folder( pNode, ds, folder, aoType );
+       gtk_ctree_expand( ctree, pNode );
+       if( nNode ) {
+               gtk_ctree_select( ctree, nNode );
+               addrbook.treeSelected = nNode;
        }
+
+       /* Setup the search */
+       queryID = addrindex_setup_static_search(
+                       ds, searchTerm, folder, addressbook_search_idle_end );
+       if( queryID == 0 ) return;
+
+       /* Set up idler function */
+       idleID = gtk_idle_add(
+                       ( GtkFunction ) addressbook_search_idle,
+                       GINT_TO_POINTER( queryID ) );
+
+       /* Start search, sit back and wait for something to happen */
+       addrindex_start_static_search( queryID, idleID );
+
+       addressbook_status_show( _tempMessage_ );
 }
-#endif /* USE_LDAP */
 
-/*
- * Lookup button handler.
+/**
+ * Lookup button handler. Address search is only performed against
+ * address interfaces for external queries.
+ *
+ * \param button Lookup button widget.
+ * \param data   Data object.
  */
 static void addressbook_lup_clicked( GtkButton *button, gpointer data ) {
-       GtkCTree *ctree = GTK_CTREE(addrbook.ctree);
+       GtkCTree *ctree;
        AddressObject *obj;
-       AdapterDSource *ads = NULL;
-       gchar *sLookup;
+       AddressDataSource *ds;
+       AddressInterface *iface;
+       gchar *searchTerm;
+       GtkCTreeNode *node, *parentNode;
 
-       if( ! addrbook.treeSelected ) return;
-       if( GTK_CTREE_ROW( addrbook.treeSelected )->level == 1 ) return;
+       node = addrbook.treeSelected;
+       if( ! node ) return;
+       if( GTK_CTREE_ROW(node)->level == 1 ) return;
 
-       obj = gtk_ctree_node_get_row_data( ctree, addrbook.treeSelected );
+       ctree = GTK_CTREE(addrbook.ctree);
+       obj = gtk_ctree_node_get_row_data( ctree, node );
        if( obj == NULL ) return;
 
-       sLookup = gtk_editable_get_chars( GTK_EDITABLE(addrbook.entry), 0, -1 );
-       g_strchomp( sLookup );
+       ds = addressbook_find_datasource( node );
+       if( ds == NULL ) return;
 
-       if( obj->type == ADDR_DATASOURCE ) {
-               ads = ADAPTER_DSOURCE(obj);
-#ifdef USE_LDAP
-               if( ads->subType == ADDR_LDAP ) {
-                       addressbook_ldap_lookup( ads, sLookup );
-               }
-#endif /* USE_LDAP */
+       /* We must have a datasource that is an external interface */
+       iface = ds->interface;
+       if( ! iface->haveLibrary ) return;
+       if( ! iface->externalQuery ) return;
+
+       searchTerm =
+               gtk_editable_get_chars( GTK_EDITABLE(addrbook.entry), 0, -1 );
+       g_strchomp( searchTerm );
+
+       if( obj->type == ADDR_ITEM_FOLDER ) {
+               parentNode = GTK_CTREE_ROW(node)->parent;
+       }
+       else {
+               parentNode = node;
        }
+       addressbook_perform_search( ds, searchTerm, parentNode );
 
-       g_free( sLookup );
+       g_free( searchTerm );
 }
 
 /* **********************************************************************
@@ -3514,6 +3591,7 @@ void addrbookctl_build_map( GtkWidget *window ) {
        stock_pixmap_gdk(window, STOCK_PIXMAP_JPILOT, &jpilotxpm, &jpilotxpmmask);
        stock_pixmap_gdk(window, STOCK_PIXMAP_CATEGORY, &categoryxpm, &categoryxpmmask);
        stock_pixmap_gdk(window, STOCK_PIXMAP_LDAP, &ldapxpm, &ldapxpmmask);
+       stock_pixmap_gdk(window, STOCK_PIXMAP_ADDRESS_SEARCH, &addrsearchxpm, &addrsearchxpmmask);
 
        _addressBookTypeHash_ = g_hash_table_new( g_int_hash, g_int_equal );
        _addressBookTypeList_ = NULL;
@@ -3668,7 +3746,7 @@ void addrbookctl_build_map( GtkWidget *window ) {
        atci->interfaceType = ADDR_IF_LDAP;
        atci->showInTree = TRUE;
        atci->treeExpand = TRUE;
-       atci->treeLeaf = TRUE;
+       atci->treeLeaf = FALSE;
        atci->displayName = _( "LDAP Server" );
        atci->iconXpm = ldapxpm;
        atci->maskXpm = ldapxpmmask;
@@ -3678,6 +3756,22 @@ void addrbookctl_build_map( GtkWidget *window ) {
        g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
        _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
 
+       /* LDAP Query  */
+       atci = g_new0( AddressTypeControlItem, 1 );
+       atci->objectType = ADDR_LDAP_QUERY;
+       atci->interfaceType = ADDR_IF_LDAP;
+       atci->showInTree = TRUE;
+       atci->treeExpand = FALSE;
+       atci->treeLeaf = TRUE;
+       atci->displayName = _( "LDAP Query" );
+       atci->iconXpm = addrsearchxpm;
+       atci->maskXpm = addrsearchxpmmask;
+       atci->iconXpmOpen = addrsearchxpm;
+       atci->maskXpmOpen = addrsearchxpmmask;
+       atci->menuCommand = NULL;
+       g_hash_table_insert( _addressBookTypeHash_, &atci->objectType, atci );
+       _addressBookTypeList_ = g_list_append( _addressBookTypeList_, atci );
+
 }
 
 /*
@@ -3809,7 +3903,6 @@ void addrbookctl_build_ifselect() {
        gchar *endptr = NULL;
        gboolean enabled;
        AdapterInterface *adapter;
-       /* GList *node; */
 
        selectStr = g_strdup( ADDRESSBOOK_IFACE_SELECTION );
 
@@ -3844,7 +3937,6 @@ void addrbookctl_build_ifselect() {
        g_list_free( _addressIFaceSelection_ );
        _addressIFaceSelection_ = newList;
        newList = NULL;
-
 }
 
 /* **********************************************************************
@@ -3876,74 +3968,11 @@ gboolean addressbook_add_contact( const gchar *name, const gchar *address, const
 *                     to be loaded.
 * Return: TRUE if data loaded, FALSE if address index not loaded.
 */
-gboolean addressbook_load_completion( gint (*callBackFunc) ( const gchar *, const gchar *, const gchar * ) ) {
-       AddressDataSource *ds;
-       GList *nodeIf, *nodeDS;
-       GList *listP, *nodeP;
-       GList *nodeM;
-       gchar *sName, *sAddress, *sAlias, *sFriendly;
-
+gboolean addressbook_load_completion(
+               gint (*callBackFunc) ( const gchar *, const gchar *, const gchar * ) )
+{
        debug_print( "addressbook_load_completion\n" );
-
-       if( _addressIndex_ == NULL ) return FALSE;
-
-       nodeIf = addrindex_get_interface_list( _addressIndex_ );
-       while( nodeIf ) {
-               AddressInterface *interface = nodeIf->data;
-               nodeDS = interface->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;
-                               nodeM = person->listEMail;
-
-                               /* Figure out name to use */
-                               sName = person->nickName;
-                               if( sName == NULL || *sName == '\0' ) {
-                                       sName = ADDRITEM_NAME(person);
-                               }
-
-                               /* Process each E-Mail address */
-                               while( nodeM ) {
-                                       ItemEMail *email = nodeM->data;
-                                       /* Have mail */
-                                       sFriendly = sName;
-                                       sAddress = email->address;
-                                       if( sAddress || *sAddress != '\0' ) {
-                                               sAlias = ADDRITEM_NAME(email);
-                                               if( sAlias && *sAlias != '\0' ) {
-                                                       sFriendly = sAlias;
-                                               }
-                                               ( callBackFunc ) ( sFriendly, sAddress, sName );
-                                       }
-
-                                       nodeM = g_list_next( nodeM );
-                               }
-                               nodeP = g_list_next( nodeP );
-                       }
-                       /* Free up the list */
-                       g_list_free( listP );
-
-                       nodeDS = g_list_next( nodeDS );
-               }
-               nodeIf = g_list_next( nodeIf );
-       }
-       debug_print( "addressbook_load_completion... done\n" );
-
-       return TRUE;
+       return addrindex_load_completion( _addressIndex_, callBackFunc );
 }
 
 /* **********************************************************************
index ffa87ffe1bc26d52b5db5b3ed931ef8ce78bbfc9..8b39df650264f981e662a808b6918d8b176dc258 100644 (file)
@@ -52,7 +52,8 @@ typedef enum {
        ADDR_VCARD,             /* Sub-type */
        ADDR_JPILOT,            /* Sub-type */
        ADDR_CATEGORY,          /* Sub-type */
-       ADDR_LDAP               /* Sub-type */
+       ADDR_LDAP,              /* Sub-type */
+       ADDR_LDAP_QUERY         /* Sub-type */
 } AddressObjectType;
 
 typedef struct _AddressBook_win        AddressBook_win;
index eb92219c2446dd109af0909ff12674c20bd8f805..a1d2f33af8be6cb3085a9a8d854293c9326fde19 100644 (file)
@@ -674,6 +674,7 @@ GList *addrindex_get_interface_list( AddressIndex *addrIndex ) {
  * \param addrIndex Address index.
  */
 void addrindex_initialize( AddressIndex *addrIndex ) {
+       qrymgr_initialize();
        addrcompl_initialize( addrIndex );
 }
 
@@ -683,6 +684,7 @@ void addrindex_initialize( AddressIndex *addrIndex ) {
  */
 void addrindex_teardown( AddressIndex *addrIndex ) {
        addrcompl_teardown();
+       qrymgr_teardown();
 }
 
 /**
@@ -2527,7 +2529,8 @@ static void addrindex_ldap_end_cb( LdapQuery *qry ) {
  * \param folder.
  * \return List of ItemEMail objects.
  */
-static void addrindex_ldap_use_previous( const ItemFolder *folder, const gint queryID )
+static void addrindex_ldap_use_previous(
+       const ItemFolder *folder, const gint queryID )
 {
        GList *listEMail;
        GList *node;
@@ -2554,10 +2557,13 @@ static void addrindex_ldap_use_previous( const ItemFolder *folder, const gint qu
        }
 }
 
+/*
+ * Function prototype (not in header file or circular reference encountered!)
+ */
 LdapQuery *ldapsvr_locate_query( LdapServer *server, const gchar *searchTerm );
 
 /**
- * Construct an LDAP query and initiate an LDAP search.
+ * Construct an LDAP query and initiate an LDAP dynamic search.
  * \param server  LDAP server object.
  * \param queryID ID of search query to be executed.
  */
@@ -2600,34 +2606,6 @@ static void addrindex_search_ldap( LdapServer *server, const gint queryID ) {
        ldapsvr_execute_query( server, qry );
 }
 
-/**
- * Construct an LDAP query and initiate an LDAP search.
- * \param server      LDAP server object to search.
- * \param searchTerm  Search term to locate.
- * \param callbackEnd Function to call when search has terminated.
- *
- */
-void addrindex_search_ldap_noid(
-       LdapServer *server, const gchar *searchTerm, void * callbackEnd )
-{
-       LdapQuery *qry;
-       gchar *name;
-
-       /* Construct a query */
-       qry = ldapqry_create();
-       ldapqry_set_search_value( qry, searchTerm );
-       ldapqry_set_query_type( qry, LDAPQUERY_STATIC );
-       ldapqry_set_callback_end( qry, callbackEnd );
-
-       /* Name the query */
-       name = g_strdup_printf( "Static Search for '%s'", searchTerm );
-       ldapqry_set_name( qry, name );
-       g_free( name );
-
-       ldapsvr_add_query( server, qry );
-       /* printf( "addrindex_search_ldap_noid::executing static search...\n" ); */
-       ldapsvr_execute_query( server, qry );
-}
 #endif
 
 /**
@@ -2714,6 +2692,140 @@ void addrindex_stop_search( AddressIndex *addrIndex, const gint queryID ){
 #endif
 }
 
+#ifdef USE_LDAP
+/**
+ * LDAP callback entry point for completion of search.
+ * \param qry LDAP query.
+ */
+static void addrindex_ldap_end_static_cb( LdapQuery *qry ) {
+       AddrQuery *addrQry;
+       gint queryID;
+       AddrQueryType queryType;
+       AddrSearchStaticFunc *callBack;
+
+       queryID = qry->queryID;
+       queryType = qry->queryType;
+       addrQry = qrymgr_find_query( queryID );
+       if( addrQry == NULL ) {
+               return;
+       }
+       callBack = addrQry->callBack;
+
+       /* Delete query */
+       qrymgr_delete_query( queryID );
+
+       /* Execute callback function */
+       callBack( queryID, queryType, qry->retVal );
+}
+#endif
+
+/**
+ * Setup the explicit search that will be performed. The search is registered with
+ * the query manager.
+ *
+ * \param  ds          Data source to search.
+ * \param  searchTerm  Search term to locate.
+ * \param  folder      Folder to receive search results; may be NULL.
+ * \param  callbackEnd Function to call when search has terminated.
+ * \return ID allocated to query that will be executed.
+ */
+gint addrindex_setup_static_search(
+       AddressDataSource *ds, const gchar *searchTerm, ItemFolder *folder,
+       void *callbackEnd )
+{
+       AddrQuery *addrQry;
+       gint queryID;
+       gchar *name;
+
+       queryID = ++_currentQueryID_;
+
+       /* Name the query */
+       name = g_strdup_printf( "Search '%s'", searchTerm );
+
+       /* Set up a generic address query */
+       addrQry = qrymgr_add_query( queryID, searchTerm, callbackEnd, NULL );
+
+       if( ds->type == ADDR_IF_LDAP ) {
+#ifdef USE_LDAP
+               LdapServer *server;
+               LdapQuery *qry;
+
+               server = ds->rawDataSource;
+
+               /* Construct a query */
+               qry = ldapqry_create();
+               ldapqry_set_query_id( qry, queryID );
+               ldapqry_set_name( qry, name );
+               ldapqry_set_search_value( qry, searchTerm );
+               ldapqry_set_query_type( qry, LDAPQUERY_STATIC );
+               ldapqry_set_callback_end( qry, addrindex_ldap_end_static_cb );
+
+               /* Specify folder type and back reference */
+               qry->folder = folder;
+               folder->folderType = ADDRFOLDER_LDAP_QUERY;
+               folder->folderData = ( gpointer ) qry;
+
+               /* Setup server */
+               ldapsvr_add_query( server, qry );
+
+               /* Set up generic query */
+               addrqry_set_query_type( addrQry, ADDRQUERY_LDAP );
+               addrqry_set_server( addrQry, server );
+               addrqry_set_query( addrQry, qry );
+#endif
+       }
+       else {
+               qrymgr_delete_query( queryID );
+               queryID = 0;
+       }
+
+       g_free( name );
+
+       return queryID;
+}
+
+/**
+ * Perform the previously registered explicit search.
+ * \param  queryID    ID of search query to be executed.
+ * \param  idleID     Idler ID.
+ * \return <i>TRUE</i> if search started successfully, or <i>FALSE</i> if
+ *         failed.
+ */
+gboolean addrindex_start_static_search( const gint queryID, const guint idleID )
+{
+       gboolean retVal;
+       AddrQuery *addrQry;
+
+       retVal = FALSE;
+       addrQry = qrymgr_find_query( queryID );
+       if( addrQry == NULL ) {
+               return retVal;
+       }
+
+       if( addrQry->queryType == ADDRQUERY_LDAP ) {
+#ifdef USE_LDAP
+               LdapServer *server;
+               LdapQuery *qry;
+
+               server = ( LdapServer * ) addrQry->serverObject;
+               qry = ( LdapQuery * ) addrQry->queryObject;
+
+               /* Retire any aged queries */
+               ldapsvr_retire_query( server );
+
+               /* Start the search */
+               ldapsvr_execute_query( server, qry );
+               retVal = TRUE;
+#endif
+       }
+
+       if( retVal ) {
+               addrqry_set_idle_id( addrQry, idleID );
+       }
+
+       return retVal;
+}
+
 /**
  * Read all address books that do not support dynamic queries.
  * \param addrIndex Address index object.
index 0c78ea5c0a2c13a2b67e64fb8cd405efe1aa6370..8a9adbf1edc65194b3eececc53840416241a43e4 100644 (file)
@@ -923,6 +923,7 @@ ItemFolder *addritem_create_item_folder( void ) {
        folder->listGroup = NULL;
        folder->folderType = ADDRFOLDER_NONE;
        folder->folderData = NULL;
+       folder->isHidden = FALSE;
        return folder;
 }
 
@@ -971,6 +972,15 @@ void addritem_folder_set_remarks( ItemFolder *folder, const gchar *value ) {
        folder->remarks = mgu_replace_string( folder->remarks, value );
 }
 
+/**
+ * Specify visibility of folder.
+ * \param folder Folder.
+ * \param value  Set to <code>TRUE</code> to hide folder.
+ */
+void addritem_folder_set_hidden( ItemFolder *folder, const gboolean value ) {
+       folder->isHidden = value;
+}
+
 /**
  * Free address folder. Note: this does not free up the lists of children
  * (folders, groups and person). This should be done prior to calling this
@@ -1000,6 +1010,7 @@ void addritem_free_item_folder( ItemFolder *folder ) {
        folder->listPerson = NULL;
        folder->folderType = ADDRFOLDER_NONE;
        folder->folderData = NULL;
+       folder->isHidden = FALSE;
 
        g_free( folder );
 }
@@ -1108,6 +1119,7 @@ void addritem_print_item_folder( ItemFolder *folder, FILE *stream ) {
        fprintf( stream, "\tnam: '%s'\n", ADDRITEM_NAME(folder) );
        fprintf( stream, "\trem: '%s'\n", folder->remarks );
        fprintf( stream, "\ttyp: %d\n", folder->folderType );
+       fprintf( stream, "\thid: %s\n", folder->isHidden ? "hidden" : "visible" );
        fprintf( stream, "\t---\n" );
        parent = ( ItemFolder * ) ADDRITEM_PARENT(folder);
        if( parent ) {
index d1a76b70fc8e32f7728f7908abc65d3fcd880802..e2a24a671e0e054d8504a162f024d4677d4e8afa 100644 (file)
@@ -99,6 +99,7 @@ struct _ItemFolder {
        GList    *listGroup;    /* List of contained (child) groups */
        AddressFolderType folderType;   /* Folder type */
        gpointer *folderData;           /* Pointer to folder's data */
+       gboolean isHidden;      /* TRUE if folder is hidden */
 };
 
 typedef struct _ItemGroup ItemGroup;
@@ -168,6 +169,7 @@ ItemFolder *addritem_copy_item_folder       ( ItemFolder *item );
 void addritem_folder_set_id            ( ItemFolder *folder, const gchar *value );
 void addritem_folder_set_name          ( ItemFolder *folder, const gchar *value );
 void addritem_folder_set_remarks       ( ItemFolder *folder, const gchar *value );
+void addritem_folder_set_hidden                ( ItemFolder *folder, const gboolean value );
 void addritem_free_item_folder         ( ItemFolder *folder );
 void addritem_free_item_folder_recurse ( ItemFolder *parent );
 
diff --git a/src/addrquery.c b/src/addrquery.c
new file mode 100644 (file)
index 0000000..049e8e1
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 2003 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.
+ */
+
+/*
+ * Functions to define an address query (a request).
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+#include <pthread.h>
+
+#include "mgutils.h"
+#include "addrquery.h"
+
+/**
+ * Query list for tracking current queries.
+ */
+static GList *_queryList_ = NULL;
+
+/**
+ * Mutex to protect list from multiple threads.
+ */
+static pthread_mutex_t _queryListMutex_ = PTHREAD_MUTEX_INITIALIZER;
+
+/**
+ * Create new address query.
+ * \return Initialized address query object.
+ */
+AddrQuery *addrqry_create( void ) {
+       AddrQuery *qry;
+
+       qry = g_new0( AddrQuery, 1 );
+       qry->queryType = ADDRQUERY_NONE;
+       qry->queryID = 0;
+       qry->idleID = 0;
+       qry->searchTerm = NULL;
+       qry->callBack = NULL;
+       qry->target = NULL;
+       qry->serverObject = NULL;
+       qry->queryObject = NULL;
+       return qry;
+}
+
+/**
+ * Clear the query.
+ * \param qry Address query object.
+ */
+void addrqry_clear( AddrQuery *qry ) {
+       g_return_if_fail( qry != NULL );
+       g_free( qry->searchTerm );
+       qry->queryType = ADDRQUERY_NONE;
+       qry->queryID = 0;
+       qry->idleID = 0;
+       qry->searchTerm = NULL;
+       qry->callBack = NULL;
+       qry->target = NULL;
+       qry->serverObject = NULL;
+       qry->queryObject = NULL;
+}
+
+/**
+ * Free query.
+ * \param qry Address query object.
+ */
+void addrqry_free( AddrQuery *qry ) {
+       g_return_if_fail( qry != NULL );
+       addrqry_clear( qry );
+       g_free( qry );
+}
+
+/**
+ * Specify query type.
+ * \param qry   Address query object.
+ * \param value Type.
+ */
+void addrqry_set_query_type( AddrQuery *qry, const AddrQueryType value ) {
+       g_return_if_fail( qry != NULL );
+       qry->queryType = value;
+}
+
+/**
+ * Specify idle ID.
+ * \param qry   Address query object.
+ * \param value Idle ID.
+ */
+void addrqry_set_idle_id( AddrQuery *qry, const guint value ) {
+       g_return_if_fail( qry != NULL );
+       qry->idleID = value;
+}
+
+/**
+ * Specify search term to be used.
+ * \param qry   Address query object.
+ * \param value Search term.
+ */
+void addrqry_set_search_term( AddrQuery* qry, const gchar *value ) {
+       qry->searchTerm = mgu_replace_string( qry->searchTerm, value );
+       g_return_if_fail( qry != NULL );
+       g_strstrip( qry->searchTerm );
+}
+
+/**
+ * Specify server object to be used.
+ * \param qry   Address query object.
+ * \param value Server object that performs the search.
+ */
+void addrqry_set_server( AddrQuery* qry, const gpointer value ) {
+       g_return_if_fail( qry != NULL );
+       qry->serverObject = value;
+}
+
+/**
+ * Specify query object to be used.
+ * \param qry   Address query object.
+ * \param value Query object that performs the search.
+ */
+void addrqry_set_query( AddrQuery* qry, const gpointer value ) {
+       g_return_if_fail( qry != NULL );
+       qry->queryObject = value;
+}
+
+/**
+ * Display object to specified stream.
+ * \param qry    Address query object.
+ * \param stream Output stream.
+ */
+void addrqry_print( const AddrQuery *qry, FILE *stream ) {
+       g_return_if_fail( qry != NULL );
+
+       fprintf( stream, "AddressQuery:\n" );
+       fprintf( stream, "     queryID: %d\n",   qry->queryID );
+       fprintf( stream, "      idleID: %d\n",   qry->idleID );
+       fprintf( stream, "  searchTerm: '%s'\n", qry->searchTerm );
+}
+
+/**
+ * Add query to list.
+ * \param queryID    ID of query being executed.
+ * \param searchTerm Search term. A private copy will be made.
+ * \param callBack   Callback function.
+ * \param target     Target object to receive data.
+ */
+AddrQuery *qrymgr_add_query(
+       const gint queryID, const gchar *searchTerm, void *callBack,
+       gpointer target )
+{
+       AddrQuery *qry;
+
+       qry = g_new0( AddrQuery, 1 );
+       qry->queryType = ADDRQUERY_NONE;
+       qry->queryID = queryID;
+       qry->idleID = 0;
+       qry->searchTerm = g_strdup( searchTerm );
+       qry->callBack = callBack;
+       qry->target = NULL;
+       qry->timeStart = time( NULL );
+       qry->serverObject = NULL;
+       qry->queryObject = NULL;
+
+       /* Insert in head of list */
+       pthread_mutex_lock( & _queryListMutex_ );
+       _queryList_ = g_list_prepend( _queryList_, qry );
+       pthread_mutex_unlock( & _queryListMutex_ );
+
+       return qry;
+}
+
+/**
+ * Find query in list.
+ * \param  queryID ID of query to find.
+ * \return Query object, or <i>NULL</i> if not found.
+ */
+AddrQuery *qrymgr_find_query( const gint queryID ) {
+       AddrQuery *qry;
+       AddrQuery *q;
+       GList *node;
+
+       pthread_mutex_lock( & _queryListMutex_ );
+       qry = NULL;
+       node = _queryList_;
+       while( node ) {
+               q = node->data;
+               if( q->queryID == queryID ) {
+                       qry = q;
+                       break;
+               }
+               node = g_list_next( node );
+       }
+       pthread_mutex_unlock( & _queryListMutex_ );
+
+       return qry;
+}
+
+/**
+ * Delete specified query.
+ * \param  queryID ID of query to retire.
+ */
+void qrymgr_delete_query( const gint queryID ) {
+       AddrQuery *qry;
+       GList *node, *nf;
+
+       pthread_mutex_lock( & _queryListMutex_ );
+
+       /* Find node */
+       nf = NULL;
+       node = _queryList_;
+       while( node ) {
+               qry = node->data;
+               if( qry->queryID == queryID ) {
+                       nf = node;
+                       addrqry_free( qry );
+                       break;
+               }
+               node = g_list_next( node );
+       }
+
+       /* Free link element and associated query */
+       if( nf ) {
+               _queryList_ = g_list_remove_link( _queryList_, nf );
+               g_list_free_1( nf );
+       }
+
+       pthread_mutex_unlock( & _queryListMutex_ );
+}
+
+/**
+ * Initialize query manager.
+ */
+void qrymgr_initialize( void ) {
+       _queryList_ = NULL;
+}
+
+/**
+ * Free all queries.
+ */
+static void qrymgr_free_all_query( void ) {
+       AddrQuery *qry;
+       GList *node;
+
+       pthread_mutex_lock( & _queryListMutex_ );
+       node = _queryList_;
+       while( node ) {
+               qry = node->data;
+               addrqry_free( qry );
+               node->data = NULL;
+               node = g_list_next( node );
+       }
+       g_list_free( _queryList_ );
+       _queryList_ = NULL;
+       pthread_mutex_unlock( & _queryListMutex_ );
+}
+
+/**
+ * Teardown query manager.
+ */
+void qrymgr_teardown( void ) {
+       qrymgr_free_all_query();
+}
+
+/**
+ * Display all queries to specified stream.
+ * \param stream Output stream.
+ */
+void qrymgr_print( FILE *stream ) {
+       AddrQuery *qry;
+       GList *node;
+
+       pthread_mutex_lock( & _queryListMutex_ );
+       fprintf( stream, "=== Query Manager ===\n" );
+       node = _queryList_;
+       while( node ) {
+               qry = node->data;
+               addrqry_print( qry, stream );
+               fprintf( stream, "---\n" );
+               node = g_list_next( node );
+       }
+       pthread_mutex_unlock( & _queryListMutex_ );
+}
+
+/*
+* End of Source.
+*/
+
+
index f496dcb34e50d0c2ae6a126a8f48869603bb3bb5..5e288d609b14ddfa13cb37d9d750765e97cef107 100644 (file)
 #define __ADDRQUERY_H__
 
 #include <glib.h>
-/* #include <stdio.h> */
+#include <stdio.h>
+#include <sys/time.h>
+
+/* Query types */
+typedef enum {
+       ADDRQUERY_NONE,
+       ADDRQUERY_LDAP
+} AddrQueryType;
 
 /* Address search call back function */
 typedef gint ( AddrSearchCallbackFunc ) ( gint cacheID,
                                          GList *listEMail,
                                          gpointer target );
 
+typedef void ( AddrSearchStaticFunc ) ( gint qid, AddrQueryType qty, gint status );
+
+/* Data structures */
+typedef struct {
+       AddrQueryType queryType;
+       gint     queryID;
+       gint     idleID;
+       gchar    *searchTerm;
+       time_t   timeStart;
+       AddrSearchStaticFunc *callBack;
+       gpointer target;
+       gpointer serverObject;
+       gpointer queryObject;
+}
+AddrQuery;
+
+/* Function prototypes */
+AddrQuery *addrqry_create      ( void );
+void addrqry_clear             ( AddrQuery *qry );
+void addrqry_free              ( AddrQuery *qry );
+void addrqry_set_query_type    ( AddrQuery *qry, const AddrQueryType value );
+void addrqry_set_idle_id       ( AddrQuery *qry, const guint value );
+void addrqry_set_search_term   ( AddrQuery* qry, const gchar *value );
+void addrqry_set_server                ( AddrQuery* qry, const gpointer server );
+void addrqry_set_query         ( AddrQuery* qry, const gpointer query );
+void addrqry_print             ( const AddrQuery *qry, FILE *stream );
+
+void qrymgr_initialize         ( void );
+void qrymgr_teardown           ( void );
+AddrQuery *qrymgr_add_query(
+               const gint queryID, const gchar *searchTerm,
+               void *callBack, gpointer target );
+
+AddrQuery *qrymgr_find_query   ( const gint queryID );
+void qrymgr_delete_query       ( const gint queryID );
+void qrymgr_print              ( FILE *stream );
+
 #endif /* __ADDRQUERY_H__ */
 
 /*
- * End of Source.
- */
+* End of Source.
+*/
index e157dfc1f37f2d4b644c9c1ef545298f54573f46..6ef4bbacc32fa9cdabd86b0b57cbd3cee4bd545e 100644 (file)
@@ -494,6 +494,7 @@ static GList *ldapqry_build_items_fl(
        GList *listReturn;
 
        listReturn = NULL;
+       if( listAddr == NULL ) return listReturn;
 
        /* Find longest first name in list */
        firstName = mgu_slist_longest_entry( listFirst );
@@ -527,32 +528,31 @@ static GList *ldapqry_build_items_fl(
                }
        }
 
-       if( listAddr ) {
-               /* Create new folder for results */
-               if( qry->folder == NULL ) {
-                       folder = addritem_create_item_folder();
-                       addritem_folder_set_name( folder, qry->queryName );
-                       addritem_folder_set_remarks( folder, "" );
-                       addrcache_id_folder( cache, folder );
-                       addrcache_add_folder( cache, folder );
-                       qry->folder = folder;
-
-                       /* Specify folder type and back reference */                    
-                       folder->folderType = ADDRFOLDER_LDAP_QUERY;
-                       folder->folderData = ( gpointer ) qry;
-               }
+       /* Create new folder for results */
+       if( qry->folder == NULL ) {
+               folder = addritem_create_item_folder();
+               addritem_folder_set_name( folder, qry->queryName );
+               addritem_folder_set_remarks( folder, "" );
+               addrcache_id_folder( cache, folder );
+               addrcache_add_folder( cache, folder );
+               qry->folder = folder;
+
+               /* Specify folder type and back reference */                    
+               folder->folderType = ADDRFOLDER_LDAP_QUERY;
+               folder->folderData = ( gpointer ) qry;
+               folder->isHidden = TRUE;
+       }
 
-               /* Add person into folder */            
-               person = addritem_create_item_person();
-               addritem_person_set_common_name( person, fullName );
-               addritem_person_set_first_name( person, firstName );
-               addritem_person_set_last_name( person, lastName );
-               addrcache_id_person( cache, person );
-               addritem_person_set_external_id( person, dn );
-               addrcache_folder_add_person( cache, qry->folder, person );
+       /* Add person into folder */            
+       person = addritem_create_item_person();
+       addritem_person_set_common_name( person, fullName );
+       addritem_person_set_first_name( person, firstName );
+       addritem_person_set_last_name( person, lastName );
+       addrcache_id_person( cache, person );
+       addritem_person_set_external_id( person, dn );
+       addrcache_folder_add_person( cache, qry->folder, person );
 
-               qry->entriesRead++;
-       }
+       qry->entriesRead++;
 
        /* Add each address item */
        nodeAddress = listAddr;
index f40ec4e627647d263c0f67b7c265d80971a77efd..f3a31ab4cac06f61cf2490d6fc19fac3dbb4e1aa 100644 (file)
@@ -458,7 +458,7 @@ LdapQuery *ldapsvr_locate_query( LdapServer *server, const gchar *searchTerm )
 }
 
 /**
- * Retire aged queries.
+ * Retire aged queries. Only dynamic queries are retired.
  * \param server LdapServer.
  */
 void ldapsvr_retire_query( LdapServer *server ) {
@@ -468,6 +468,7 @@ void ldapsvr_retire_query( LdapServer *server ) {
        gint maxAge;
        LdapControl *ctl;
 
+       /* printf( "ldapsvr_retire_query\n" ); */
        g_return_if_fail( server != NULL );
        ctl = server->control;
        maxAge = ctl->maxQueryAge;
@@ -478,13 +479,19 @@ void ldapsvr_retire_query( LdapServer *server ) {
        while( node ) {
                LdapQuery *qry = node->data;
 
+               node = g_list_next( node );
+               if( qry->queryType == LDAPQUERY_STATIC ) continue;
+
+               /* Only dynamic queries are retired */
                ldapqry_age( qry, maxAge );
                if( qry->agedFlag ) {
                        /* Delete folder associated with query */
+                       /*
+                       printf( "deleting folder... ::%s::\n", qry->queryName );
+                       */
                        ldapqry_delete_folder( qry );
                        listDelete = g_list_append( listDelete, qry );
                }
-               node = g_list_next( node );
        }
 
        /* Delete queries */