+ BER_BVZERO( &rdi->rdi_e.e_name );
+ BER_BVZERO( &rdi->rdi_e.e_nname );
+
+ entry_clean( &rdi->rdi_e );
+
+ if ( !BER_BVISNULL( &rdi->rdi_unsolicited_oid ) ) {
+ ber_memfree( rdi->rdi_unsolicited_oid.bv_val );
+ if ( !BER_BVISNULL( &rdi->rdi_unsolicited_data ) )
+ ber_memfree( rdi->rdi_unsolicited_data.bv_val );
+ }
+
+ ch_free( rdi );
+}
+
+enum {
+ RC_PARENT = 1,
+ RC_ITEM
+};
+
+static ConfigDriver rc_cf_gen;
+
+static ConfigTable rccfg[] = {
+ { "retcode-parent", "dn",
+ 2, 2, 0, ARG_MAGIC|ARG_DN|RC_PARENT, rc_cf_gen,
+ "( OLcfgOvAt:20.1 NAME 'olcRetcodeParent' "
+ "DESC '' "
+ "SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL },
+ { "retcode-item", "rdn> <retcode> <...",
+ 3, 0, 0, ARG_MAGIC|RC_ITEM, rc_cf_gen,
+ "( OLcfgOvAt:20.2 NAME 'olcRetcodeItem' "
+ "DESC '' "
+ "EQUALITY caseIgnoreMatch "
+ "SYNTAX OMsDirectoryString "
+ "X-ORDERED 'VALUES' )", NULL, NULL },
+ { "retcode-indir", "on|off",
+ 1, 2, 0, ARG_OFFSET|ARG_ON_OFF,
+ (void *)offsetof(retcode_t, rd_indir),
+ "( OLcfgOvAt:20.3 NAME 'olcRetcodeInDir' "
+ "DESC '' "
+ "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
+
+ { "retcode-sleep", "sleeptime",
+ 2, 2, 0, ARG_OFFSET|ARG_INT,
+ (void *)offsetof(retcode_t, rd_sleep),
+ "( OLcfgOvAt:20.4 NAME 'olcRetcodeSleep' "
+ "DESC '' "
+ "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
+
+ { NULL, NULL, 0, 0, 0, ARG_IGNORED }
+};
+
+static ConfigOCs rcocs[] = {
+ { "( OLcfgOvOc:20.1 "
+ "NAME 'olcRetcodeConfig' "
+ "DESC 'Retcode configuration' "
+ "SUP olcOverlayConfig "
+ "MAY ( olcRetcodeParent "
+ "$ olcRetcodeItem "
+ "$ olcRetcodeInDir "
+ "$ olcRetcodeSleep "
+ ") )",
+ Cft_Overlay, rccfg, NULL, NULL },
+ { NULL, 0, NULL }
+};
+
+static int
+rc_cf_gen( ConfigArgs *c )
+{
+ slap_overinst *on = (slap_overinst *)c->bi;
+ retcode_t *rd = (retcode_t *)on->on_bi.bi_private;
+ int rc = ARG_BAD_CONF;
+
+ if ( c->op == SLAP_CONFIG_EMIT ) {
+ switch( c->type ) {
+ case RC_PARENT:
+ if ( !BER_BVISEMPTY( &rd->rd_pdn )) {
+ rc = value_add_one( &c->rvalue_vals,
+ &rd->rd_pdn );
+ if ( rc == 0 ) {
+ rc = value_add_one( &c->rvalue_nvals,
+ &rd->rd_npdn );
+ }
+ return rc;
+ }
+ rc = 0;
+ break;
+
+ case RC_ITEM: {
+ retcode_item_t *rdi;
+ int i;
+
+ for ( rdi = rd->rd_item, i = 0; rdi; rdi = rdi->rdi_next, i++ ) {
+ char buf[4096];
+ struct berval bv;
+ char *ptr;
+
+ bv.bv_len = snprintf( buf, sizeof( buf ), SLAP_X_ORDERED_FMT, i );
+ bv.bv_len += rdi->rdi_line.bv_len;
+ ptr = bv.bv_val = ch_malloc( bv.bv_len + 1 );
+ ptr = lutil_strcopy( ptr, buf );
+ ptr = lutil_strncopy( ptr, rdi->rdi_line.bv_val, rdi->rdi_line.bv_len );
+ ber_bvarray_add( &c->rvalue_vals, &bv );
+ }
+ rc = 0;
+ } break;
+
+ default:
+ assert( 0 );
+ break;