From 22e739b736cb7ff337b8102db5be6848b8db4747 Mon Sep 17 00:00:00 2001
From: Kurt Zeilenga <kurt@openldap.org>
Date: Tue, 19 Sep 2000 18:08:04 +0000
Subject: [PATCH] Add rough implementation of tool callbacks.

---
 servers/slapd/back-bdb/back-bdb.h  |  44 ++++--
 servers/slapd/back-bdb/backbdb.dsp |  10 +-
 servers/slapd/back-bdb/init.c      | 183 +++++++++++++-----------
 servers/slapd/back-bdb/tools.c     | 222 +++++++++++++++++++++++++++++
 4 files changed, 368 insertions(+), 91 deletions(-)
 create mode 100644 servers/slapd/back-bdb/tools.c

diff --git a/servers/slapd/back-bdb/back-bdb.h b/servers/slapd/back-bdb/back-bdb.h
index fbdcb5b801..ae2f78f524 100644
--- a/servers/slapd/back-bdb/back-bdb.h
+++ b/servers/slapd/back-bdb/back-bdb.h
@@ -11,8 +11,16 @@
 #include <portable.h>
 #include <db.h>
 
+#include "slap.h"
+
 LDAP_BEGIN_DECL
 
+#define DBTzero(t)			(memset((t), 0, sizeof(DBT)))
+#define DBT2bv(t,bv)		((bv)->bv_val = (t)->data, \
+								(bv)->bv_len = (t)->size)
+#define bv2DBT(bv,t)		((t)->data = (bv)->bv_val, \
+								(t)->size = (bv)->bv_len )
+
 #define DEFAULT_MODE		0600
 
 #define DEFAULT_DBENV_HOME	LDAP_RUNDIR LDAP_DIRSEP "openldap-bdb"
@@ -21,18 +29,36 @@ LDAP_BEGIN_DECL
 #define DEFAULT_DB_LG_DIR	DEFAULT_DBENV_HOME LDAP_DIRSEP "log"
 #define DEFAULT_DB_DATA_DIR	DEFAULT_DBENV_HOME LDAP_DIRSEP "data"
 
-struct bdb_dbinfo {
-	DB_ENV		*bdi_dbenv;
+#define BDB_ID		0
+#define BDB_ENTRIES	1
+#define BDB_DNS		2
+
+struct bdb_db_info {
+	DB			*bdi_db;
+};
+
+struct bdb_info {
+	DB_ENV		*bi_dbenv;
+
+	/* DB_env parameters */
+	char		*bi_dbenv_home;
+	u_int32_t	bi_dbenv_xflags; /* extra flags */
+	int			bi_dbenv_mode;
+
+	int			bi_tx_max;
+
+	char		*bi_db_tmp_dir;
+	char		*bi_db_lg_dir;
+	char		*bi_db_data_dir;
 
-	/* DBenv parameters */
-	char		*bdi_dbenv_home;
-	u_int32_t	bdi_dbenv_xflags; /* extra flags */
-	int			bdi_dbenv_mode;
+	ID			*bi_lastid;
 
-	char		*bdi_db_tmp_dir;
-	char		*bdi_db_lg_dir;
-	char		*bdi_db_data_dir;
+	int			bi_ndatabases;
+	struct bdb_db_info **bdi_databases;
 };
+#define bi_id		bdi_databases[BDB_ID]
+#define bi_entries	bdi_databases[BDB_ENTRIES]
+#define bi_dns		bdi_databases[BDB_DNS]
 
 LDAP_END_DECL
 
diff --git a/servers/slapd/back-bdb/backbdb.dsp b/servers/slapd/back-bdb/backbdb.dsp
index 649c298efa..45d3786ea3 100644
--- a/servers/slapd/back-bdb/backbdb.dsp
+++ b/servers/slapd/back-bdb/backbdb.dsp
@@ -131,6 +131,10 @@ SOURCE=".\back-bdb.h"
 # End Source File
 # Begin Source File
 
+SOURCE=.\error.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\external.h
 # End Source File
 # Begin Source File
@@ -139,7 +143,11 @@ SOURCE=.\init.c
 # End Source File
 # Begin Source File
 
-SOURCE=".\proto-back-bdb.h"
+SOURCE=".\proto-bdb.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\tools.c
 # End Source File
 # End Target
 # End Project
diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c
index 49f7b7af9c..a93d53e2d6 100644
--- a/servers/slapd/back-bdb/init.c
+++ b/servers/slapd/back-bdb/init.c
@@ -12,64 +12,65 @@
 #include <ac/string.h>
 #include <ac/socket.h>
 
-#include "slap.h"
 #include "back-bdb.h"
 
 static int
-bdb_back_destroy( BackendInfo *bi )
+bi_back_destroy( BackendInfo *bi )
 {
 	return 0;
 }
 
 static int
-bdb_back_open( BackendInfo *bi )
+bi_back_open( BackendInfo *bi )
 {
 	/* initialize the underlying database system */
 	return 0;
 }
 
 static int
-bdb_back_close( BackendInfo *bi )
+bi_back_close( BackendInfo *bi )
 {
 	/* terminate the underlying database system */
 	return 0;
 }
 
 static int
-bdb_back_db_init( Backend *be )
+bi_back_db_init( Backend *be )
 {
-	struct bdb_dbinfo	*bdi;
+	struct bdb_info	*bdb;
 
 	/* allocate backend-database-specific stuff */
-	bdi = (struct bdb_dbinfo *) ch_calloc( 1, sizeof(struct bdb_dbinfo) );
+	bdb = (struct bdb_info *) ch_calloc( 1, sizeof(struct bdb_info) );
 
 	/* DBEnv parameters */
-	bdi->bdi_dbenv_home = ch_strdup( DEFAULT_DBENV_HOME );
-	bdi->bdi_dbenv_xflags = 0;
-	bdi->bdi_dbenv_mode = DEFAULT_MODE;
+	bdb->bi_dbenv_home = ch_strdup( DEFAULT_DBENV_HOME );
+	bdb->bi_dbenv_xflags = 0;
+	bdb->bi_dbenv_mode = DEFAULT_MODE;
 
 	/* default database directories */
-	bdi->bdi_db_tmp_dir = ch_strdup( DEFAULT_DB_TMP_DIR );
-	bdi->bdi_db_lg_dir = ch_strdup( DEFAULT_DB_LG_DIR );
-	bdi->bdi_db_data_dir = ch_strdup( DEFAULT_DB_DATA_DIR );
+	bdb->bi_db_tmp_dir = ch_strdup( DEFAULT_DB_TMP_DIR );
+	bdb->bi_db_lg_dir = ch_strdup( DEFAULT_DB_LG_DIR );
+	bdb->bi_db_data_dir = ch_strdup( DEFAULT_DB_DATA_DIR );
 
-	be->be_private = bdi;
+	bdb->bi_lastid = NOID;
+
+	be->be_private = bdb;
 	return 0;
 }
 
 static int
-bdb_back_db_open( BackendDB *be )
+bi_back_db_open( BackendDB *be )
 {
 	int rc;
-	struct bdb_dbinfo *bdi = (struct bdb_dbinfo *) be->be_private;
+	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
 	u_int32_t flags;
 
 	/* we should check existance of dbenv_home and db_directory */
 
-	rc = db_env_create( &bdi->bdi_dbenv, 0 );
+	rc = db_env_create( &bdb->bi_dbenv, 0 );
 	if( rc != 0 ) {
 		Debug( LDAP_DEBUG_ANY,
-			"bdb_back_db_open: db_env_create failed: %s (%d)\n",
+			"bi_back_db_open: db_env_create failed: %s (%d)\n",
 			db_strerror(rc), rc, 0 );
 		return rc;
 	}
@@ -83,44 +84,55 @@ bdb_back_db_open( BackendDB *be )
 	flags |= DB_INIT_MPOOL;
 #endif
 
-	bdi->bdi_dbenv->set_errpfx( bdi->bdi_dbenv, be->be_suffix[0] );
-	bdi->bdi_dbenv->set_errcall( bdi->bdi_dbenv, bdb_errcall );
+	bdb->bi_dbenv->set_errpfx( bdb->bi_dbenv, be->be_suffix[0] );
+	bdb->bi_dbenv->set_errcall( bdb->bi_dbenv, bdb_errcall );
+
+	if( bdb->bi_tx_max ) {
+		rc = bdb->bi_dbenv->set_tx_max( bdb->bi_dbenv,
+			bdb->bi_tx_max );
+		if( rc != 0 ) {
+			Debug( LDAP_DEBUG_ANY,
+				"bi_back_db_open: set_tx_max(%d) failed: %s (%d)\n",
+				bdb->bi_tx_max, db_strerror(rc), rc );
+			return rc;
+		}
+	}
 
-	rc = bdi->bdi_dbenv->set_tmp_dir( bdi->bdi_dbenv,
-		bdi->bdi_db_tmp_dir );
+	rc = bdb->bi_dbenv->set_tmp_dir( bdb->bi_dbenv,
+		bdb->bi_db_tmp_dir );
 	if( rc != 0 ) {
 		Debug( LDAP_DEBUG_ANY,
-			"bdb_back_db_open: set_tmp_dir(%s) failed: %s (%d)\n",
-			bdi->bdi_db_tmp_dir, db_strerror(rc), rc );
+			"bi_back_db_open: set_tmp_dir(%s) failed: %s (%d)\n",
+			bdb->bi_db_tmp_dir, db_strerror(rc), rc );
 		return rc;
 	}
 
-	rc = bdi->bdi_dbenv->set_lg_dir( bdi->bdi_dbenv,
-		bdi->bdi_db_lg_dir );
+	rc = bdb->bi_dbenv->set_lg_dir( bdb->bi_dbenv,
+		bdb->bi_db_lg_dir );
 	if( rc != 0 ) {
 		Debug( LDAP_DEBUG_ANY,
-			"bdb_back_db_open: set_lg_dir(%s) failed: %s (%d)\n",
-			bdi->bdi_db_lg_dir, db_strerror(rc), rc );
+			"bi_back_db_open: set_lg_dir(%s) failed: %s (%d)\n",
+			bdb->bi_db_lg_dir, db_strerror(rc), rc );
 		return rc;
 	}
 
-	rc = bdi->bdi_dbenv->set_data_dir( bdi->bdi_dbenv,
-		bdi->bdi_db_data_dir );
+	rc = bdb->bi_dbenv->set_data_dir( bdb->bi_dbenv,
+		bdb->bi_db_data_dir );
 	if( rc != 0 ) {
 		Debug( LDAP_DEBUG_ANY,
-			"bdb_back_db_open: set_data_dir(%s) failed: %s (%d)\n",
-			bdi->bdi_db_data_dir, db_strerror(rc), rc );
+			"bi_back_db_open: set_data_dir(%s) failed: %s (%d)\n",
+			bdb->bi_db_data_dir, db_strerror(rc), rc );
 		return rc;
 	}
 
-	rc = bdi->bdi_dbenv->open( bdi->bdi_dbenv,
-		bdi->bdi_dbenv_home,
-		flags | bdi->bdi_dbenv_xflags,
-		bdi->bdi_dbenv_mode );
+	rc = bdb->bi_dbenv->open( bdb->bi_dbenv,
+		bdb->bi_dbenv_home,
+		flags | bdb->bi_dbenv_xflags,
+		bdb->bi_dbenv_mode );
 	if( rc != 0 ) {
 		Debug( LDAP_DEBUG_ANY,
-			"bdb_back_db_open: db_open(%s) failed: %s (%d)\n",
-			bdi->bdi_dbenv_home, db_strerror(rc), rc );
+			"bi_back_db_open: db_open(%s) failed: %s (%d)\n",
+			bdb->bi_dbenv_home, db_strerror(rc), rc );
 		return rc;
 	}
 
@@ -128,17 +140,26 @@ bdb_back_db_open( BackendDB *be )
 }
 
 static int
-bdb_back_db_destroy( BackendDB *be )
+bi_back_db_destroy( BackendDB *be )
 {
 	int rc;
-	struct bdb_dbinfo *bdi = (struct bdb_dbinfo *) be->be_private;
+	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
 
-	rc = bdi->bdi_dbenv->close( bdi->bdi_dbenv, 0 );
-	bdi->bdi_dbenv = NULL;
+	/* force a checkpoint */
+	rc = txn_checkpoint( bdb->bi_dbenv, 0, 0, DB_FORCE );
+	if( rc != 0 ) {
+		Debug( LDAP_DEBUG_ANY,
+			"bi_back_db_destroy: txn_checkpoint failed: %s (%d)\n",
+			db_strerror(rc), rc, 0 );
+		return rc;
+	}
 
+	/* close db environment */
+	rc = bdb->bi_dbenv->close( bdb->bi_dbenv, 0 );
+	bdb->bi_dbenv = NULL;
 	if( rc != 0 ) {
 		Debug( LDAP_DEBUG_ANY,
-			"bdb_back_db_open: db_open failed: %s (%d)\n",
+			"bi_back_db_destroy: close failed: %s (%d)\n",
 			db_strerror(rc), rc, 0 );
 		return rc;
 	}
@@ -147,12 +168,12 @@ bdb_back_db_destroy( BackendDB *be )
 }
 
 #ifdef SLAPD_BDB_DYNAMIC
-int back_bdb_LTX_init_module( int argc, char *argv[] ) {
+int back_bi_LTX_init_module( int argc, char *argv[] ) {
     BackendInfo bi;
 
     memset( &bi, '\0', sizeof(bi) );
     bi.bi_type = "bdb";
-    bi.bi_init = bdb_back_initialize;
+    bi.bi_init = bi_back_initialize;
 
     backend_add( &bi );
     return 0;
@@ -160,7 +181,7 @@ int back_bdb_LTX_init_module( int argc, char *argv[] ) {
 #endif /* SLAPD_BDB_DYNAMIC */
 
 int
-bdb_back_initialize(
+bi_back_initialize(
     BackendInfo	*bi
 )
 {
@@ -178,57 +199,57 @@ bdb_back_initialize(
 			patch < DB_VERSION_PATCH )
 		{
 			Debug( LDAP_DEBUG_ANY,
-				"bdb_back_initialize: version mismatch\n"
+				"bi_back_initialize: version mismatch\n"
 				"\texpected: " DB_VERSION_STRING "\n"
 				"\tgot: %s \n", version, 0, 0 );
 		}
 
-		Debug( LDAP_DEBUG_ANY, "bdb_back_initialize: %s\n",
+		Debug( LDAP_DEBUG_ANY, "bi_back_initialize: %s\n",
 			version, 0, 0 );
 	}
 
 	bi->bi_controls = controls;
 
-	bi->bi_open = bdb_back_open;
-	bi->bi_close = bdb_back_close;
+	bi->bi_open = bi_back_open;
+	bi->bi_close = bi_back_close;
 	bi->bi_config = 0;
-	bi->bi_destroy = bdb_back_destroy;
+	bi->bi_destroy = bi_back_destroy;
 
 #if 0
-	bi->bi_db_init = bdb_back_db_init;
-	bi->bi_db_config = bdb_back_db_config;
-	bi->bi_db_open = bdb_back_db_open;
-	bi->bi_db_close = bdb_back_db_close;
-	bi->bi_db_destroy = bdb_back_db_destroy;
-
-	bi->bi_op_bind = bdb_back_bind;
-	bi->bi_op_unbind = bdb_back_unbind;
-	bi->bi_op_search = bdb_back_search;
-	bi->bi_op_compare = bdb_back_compare;
-	bi->bi_op_modify = bdb_back_modify;
-	bi->bi_op_modrdn = bdb_back_modrdn;
-	bi->bi_op_add = bdb_back_add;
-	bi->bi_op_delete = bdb_back_delete;
-	bi->bi_op_abandon = bdb_back_abandon;
-
-	bi->bi_extended = bdb_back_extended;
-
-	bi->bi_entry_release_rw = bdb_back_entry_release_rw;
-	bi->bi_acl_group = bdb_back_group;
-	bi->bi_acl_attribute = bdb_back_attribute;
-	bi->bi_chk_referrals = bdb_back_referrals;
+	bi->bi_db_init = bi_back_db_init;
+	bi->bi_db_config = bi_back_db_config;
+	bi->bi_db_open = bi_back_db_open;
+	bi->bi_db_close = bi_back_db_close;
+	bi->bi_db_destroy = bi_back_db_destroy;
+
+	bi->bi_op_bind = bi_back_bind;
+	bi->bi_op_unbind = bi_back_unbind;
+	bi->bi_op_search = bi_back_search;
+	bi->bi_op_compare = bi_back_compare;
+	bi->bi_op_modify = bi_back_modify;
+	bi->bi_op_modrdn = bi_back_modrdn;
+	bi->bi_op_add = bi_back_add;
+	bi->bi_op_delete = bi_back_delete;
+	bi->bi_op_abandon = bi_back_abandon;
+
+	bi->bi_extended = bi_back_extended;
+
+	bi->bi_entry_release_rw = bi_back_entry_release_rw;
+	bi->bi_acl_group = bi_back_group;
+	bi->bi_acl_attribute = bi_back_attribute;
+	bi->bi_chk_referrals = bi_back_referrals;
 
 	/*
 	 * hooks for slap tools
 	 */
-	bi->bi_tool_entry_open = bdb_tool_entry_open;
-	bi->bi_tool_entry_close = bdb_tool_entry_close;
-	bi->bi_tool_entry_first = bdb_tool_entry_first;
-	bi->bi_tool_entry_next = bdb_tool_entry_next;
-	bi->bi_tool_entry_get = bdb_tool_entry_get;
-	bi->bi_tool_entry_put = bdb_tool_entry_put;
-	bi->bi_tool_entry_reindex = bdb_tool_entry_reindex;
-	bi->bi_tool_sync = bdb_tool_sync;
+	bi->bi_tool_entry_open = bi_tool_entry_open;
+	bi->bi_tool_entry_close = bi_tool_entry_close;
+	bi->bi_tool_entry_first = bi_tool_entry_first;
+	bi->bi_tool_entry_next = bi_tool_entry_next;
+	bi->bi_tool_entry_get = bi_tool_entry_get;
+	bi->bi_tool_entry_put = bi_tool_entry_put;
+	bi->bi_tool_entry_reindex = bi_tool_entry_reindex;
+	bi->bi_tool_sync = bi_tool_sync;
 
 	bi->bi_connection_init = 0;
 	bi->bi_connection_destroy = 0;
diff --git a/servers/slapd/back-bdb/tools.c b/servers/slapd/back-bdb/tools.c
new file mode 100644
index 0000000000..8282961f97
--- /dev/null
+++ b/servers/slapd/back-bdb/tools.c
@@ -0,0 +1,222 @@
+/* tools.c - tools for slap tools */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/string.h>
+#include <ac/socket.h>
+
+#include "back-bdb.h"
+
+static DBC *cursor = NULL;
+static DBT key, data;
+
+int bdb_tool_entry_open(
+	BackendDB *be, int mode )
+{
+	int rc;
+	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+	
+	rc = bdb->bi_entries->bdi_db->cursor(
+		bdb->bi_entries->bdi_db, NULL, &cursor, 0 );
+	if( rc != 0 ) {
+		return NOID;
+	}
+
+	/* initialize key and data thangs */
+	DBTzero( &key );
+	DBTzero( &data );
+	key.flags = DB_DBT_REALLOC;
+	data.flags = DB_DBT_REALLOC;
+
+	return 0;
+}
+
+int bdb_tool_entry_close(
+	BackendDB *be )
+{
+	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+
+	if( key.data ) {
+		ch_free( key.data );
+		key.data = NULL;
+	}
+	if( data.data ) {
+		ch_free( data.data );
+		data.data = NULL;
+	}
+
+	if( cursor ) {
+		cursor->c_close( cursor );
+		cursor = NULL;
+	}
+
+	return 0;
+}
+
+ID bdb_tool_entry_next(
+	BackendDB *be )
+{
+	int rc;
+	ID id;
+
+	assert( slapMode & SLAP_TOOL_MODE );
+	assert( cursor != NULL );
+
+	rc = cursor->c_get( cursor, &key, &data, DB_NEXT );
+
+	if( rc != 0 ) {
+		return NOID;
+	}
+
+	if( data.data == NULL ) {
+		return NOID;
+	}
+
+	AC_MEMCPY( &id, key.data, key.size );
+	return id;
+}
+
+Entry* bdb_tool_entry_get( BackendDB *be, ID id )
+{
+	int rc;
+	Entry *e;
+	struct berval bv;
+	assert( slapMode & SLAP_TOOL_MODE );
+	assert( data.data != NULL );
+
+	DBT2bv( &data, &bv );
+
+	rc = entry_decode( &bv, &e );
+
+	if( rc == LDAP_SUCCESS ) {
+		e->e_id = id;
+	}
+
+	return e;
+}
+
+ID bdb_tool_entry_put(
+	BackendDB *be,
+	Entry *e )
+{
+	int rc;
+	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+	DB_TXN *tid;
+	DBT key, data;
+	struct berval *bv;
+
+	assert( slapMode & SLAP_TOOL_MODE );
+
+	DBTzero( &key );
+	key.data = (char *) &e->e_id;
+	key.size = sizeof(ID);
+
+	rc = entry_encode( e, &bv );
+	if( rc != LDAP_SUCCESS ) {
+		return NOID;
+	}
+
+	DBTzero( &data );
+	bv2DBT( bv, &data );
+
+	Debug( LDAP_DEBUG_TRACE, "=> bdb_tool_entry_put( %ld, \"%s\" )\n",
+		e->e_id, e->e_dn, 0 );
+
+	rc = txn_begin( bdb->bi_dbenv, NULL, &tid, 0 );
+	if( rc != 0 ) {
+		ber_bvfree( bv );
+		return NOID;
+	}
+
+	e->e_id = bdb_next_id( be, tid );
+	if( e->e_id == NOID ) {
+		goto done;
+	}
+
+	/* store it -- don't override */
+	rc = bdb->bi_entries->bdi_db->put( bdb->bi_entries->bdi_db,
+		tid, &key, &data, DB_NOOVERWRITE );
+	if( rc != 0 ) {
+		e->e_id = NOID;
+		goto done;
+	}
+
+	/* add dn indices */
+	rc = bdb_index_dn_add( be, tid, e->e_ndn, e->e_id );
+	if( rc != 0 ) {
+		e->e_id = NOID;
+		goto done;
+	}
+
+#if 0
+	rc = bdb_index_entry_add( be, tid, e, e->e_attrs );
+	if( rc != 0 ) {
+		e->e_id = NOID;
+		goto done;
+	}
+#endif
+
+done:
+	if( e->e_id != NOID ) {
+		rc = txn_commit( tid, 0 );
+		if( rc != 0 ) {
+			e->e_id = NOID;
+		}
+
+	} else {
+		txn_abort( tid );
+	}
+
+	ber_bvfree( bv );
+	return e->e_id;
+}
+
+#if 0
+int bdb_tool_entry_reindex(
+	BackendDB *be,
+	ID id )
+{
+	struct bdb_dbinfo *bdi = (struct bdb_dbinfo *) be->be_private;
+	int rc;
+	Entry *e;
+	DB_TXN *tid;
+
+	Debug( LDAP_DEBUG_ARGS, "=> bdb_tool_entry_reindex( %ld )\n",
+		(long) id, 0, 0 );
+
+	rc = txn_begin( bdi->bdi_db_env, NULL, &tid, 0 );
+ 	
+	e = bdb_tool_entry_get( be, tid, id );
+
+	if( e == NULL ) {
+		Debug( LDAP_DEBUG_ANY,
+			"bdb_tool_entry_reindex:: could not locate id=%ld\n",
+			(long) id, 0, 0 );
+		txn_abort( bdi->bdi_db_env );
+		return -1;
+	}
+
+	/*
+	 * just (re)add them for now
+	 * assume that some other routine (not yet implemented)
+	 * will zap index databases
+	 *
+	 */
+
+	Debug( LDAP_DEBUG_TRACE, "=> bdb_tool_entry_reindex( %ld, \"%s\" )\n",
+		id, e->e_dn, 0 );
+
+	rc = index_entry_add( be, e, e->e_attrs );
+
+	entry_free( e );
+
+	return rc;
+}
+#endif
-- 
GitLab