+static slap_overinst *
+glue_tool_inst(
+ BackendInfo *bi
+)
+{
+ slap_overinfo *oi = (slap_overinfo *)bi;
+ slap_overinst *on;
+
+ for ( on = oi->oi_list; on; on=on->on_next ) {
+ if ( !strcmp( on->on_bi.bi_type, glue.on_bi.bi_type ))
+ return on;
+ }
+ return NULL;
+}
+
+/* This function will only be called in tool mode */
+static int
+glue_open (
+ BackendInfo *bi
+)
+{
+ slap_overinst *on = glue_tool_inst( bi );
+ glueinfo *gi = on->on_bi.bi_private;
+ static int glueOpened = 0;
+ int i, j, same, bsame = 0, rc = 0;
+
+ if (glueOpened) return 0;
+
+ glueOpened = 1;
+
+ /* If we were invoked in tool mode, open all the underlying backends */
+ if (slapMode & SLAP_TOOL_MODE) {
+ for (i = 0; i<gi->gi_nodes; i++) {
+ same = 0;
+ /* Same bi_open as our main backend? */
+ if ( gi->gi_n[i].gn_be->bd_info->bi_open ==
+ on->on_info->oi_orig->bi_open )
+ bsame = 1;
+
+ /* Loop thru the bd_info's and make sure we only
+ * invoke their bi_open functions once each.
+ */
+ for ( j = 0; j<i; j++ ) {
+ if ( gi->gi_n[i].gn_be->bd_info->bi_open ==
+ gi->gi_n[j].gn_be->bd_info->bi_open ) {
+ same = 1;
+ break;
+ }
+ }
+ /* OK, it's unique and non-NULL, call it. */
+ if ( !same && gi->gi_n[i].gn_be->bd_info->bi_open )
+ rc = gi->gi_n[i].gn_be->bd_info->bi_open(
+ gi->gi_n[i].gn_be->bd_info );
+ /* Let backend.c take care of the rest of startup */
+ if ( !rc )
+ rc = backend_startup_one( gi->gi_n[i].gn_be );
+ if ( rc ) break;
+ }
+ if ( !rc && !bsame && on->on_info->oi_orig->bi_open )
+ rc = on->on_info->oi_orig->bi_open( on->on_info->oi_orig );
+
+ } /* other case is impossible */
+ return rc;
+}
+
+/* This function will only be called in tool mode */
+static int
+glue_close (
+ BackendInfo *bi
+)
+{
+ static int glueClosed = 0;
+ int rc = 0;
+
+ if (glueClosed) return 0;
+
+ glueClosed = 1;
+
+ if (slapMode & SLAP_TOOL_MODE) {
+ rc = backend_shutdown( NULL );
+ }
+ return rc;
+}
+
+static int
+glue_entry_release_rw (
+ Operation *op,
+ Entry *e,
+ int rw
+)
+{
+ BackendDB *b0, b2;
+ int rc = -1;
+
+ b0 = op->o_bd;
+ b2 = *op->o_bd;
+ b2.bd_info = (BackendInfo *)glue_tool_inst( op->o_bd->bd_info );
+ op->o_bd = glue_back_select (&b2, &e->e_nname);
+
+ if ( op->o_bd->be_release ) {
+ rc = op->o_bd->be_release( op, e, rw );
+
+ } else {
+ /* FIXME: mimic be_entry_release_rw
+ * when no be_release() available */
+ /* free entry */
+ entry_free( e );
+ rc = 0;
+ }
+ op->o_bd = b0;
+ return rc;
+}
+