/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1998-2010 The OpenLDAP Foundation.
+ * Copyright 1998-2011 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
/* SlapReply debugging, prodo-slap.h overrides it in OpenLDAP releases */
#if defined(LDAP_TEST) || (defined(USE_RS_ASSERT) && (USE_RS_ASSERT))
+
+int rs_suppress_assert = 0;
+
+/* RS_ASSERT() helper function */
+void rs_assert_(const char*file, unsigned line, const char*fn, const char*cond)
+{
+ int no_assert = rs_suppress_assert, save_errno = errno;
+ const char *s;
+
+ if ( no_assert >= 0 ) {
+ if ( no_assert == 0 && (s = getenv( "NO_RS_ASSERT" )) && *s ) {
+ no_assert = rs_suppress_assert = atoi( s );
+ }
+ if ( no_assert > 0 ) {
+ errno = save_errno;
+ return;
+ }
+ }
+
+#ifdef rs_assert_ /* proto-slap.h #defined away the fn parameter */
+ fprintf( stderr,"%s:%u: " "RS_ASSERT(%s) failed.\n", file,line,cond );
+#else
+ fprintf( stderr,"%s:%u: %s: RS_ASSERT(%s) failed.\n", file,line,fn,cond );
+#endif
+ fflush( stderr );
+
+ errno = save_errno;
+ /* $NO_RS_ASSERT > 0: ignore rs_asserts, 0: abort, < 0: just warn */
+ if ( !no_assert /* from $NO_RS_ASSERT */ ) abort();
+}
+
+/* SlapReply is consistent */
void
(rs_assert_ok)( const SlapReply *rs )
{
#endif
#endif
}
+
+/* Ready for calling a new backend operation */
void
(rs_assert_ready)( const SlapReply *rs )
{
RS_ASSERT( !(rs->sr_flags & REP_ENTRY_MASK) );
#endif
}
+
+/* Backend operation done */
void
(rs_assert_done)( const SlapReply *rs )
{
RS_ASSERT( !(rs->sr_flags & REP_ENTRY_MUSTFLUSH) );
#endif
}
+
#endif /* LDAP_TEST || USE_RS_ASSERT */
/* Reset a used SlapReply whose contents has been flushed (freed/released) */
void
-(rs_reinit)( SlapReply *rs )
+(rs_reinit)( SlapReply *rs, slap_reply_t type )
{
- rs_assert_done( rs );
- memset( rs, 0, sizeof(SlapReply) );
+ rs_reinit( rs, type ); /* proto-slap.h macro */
}
/* Obey and clear rs->sr_flags & REP_ENTRY_MASK. Clear sr_entry if freed. */
* Return nonzero if rs->sr_entry was replaced.
*/
int
-rs_ensure_entry_modifiable( Operation *op, SlapReply *rs, slap_overinst *on )
+rs_entry2modifiable( Operation *op, SlapReply *rs, slap_overinst *on )
{
if ( rs->sr_flags & REP_ENTRY_MODIFIABLE ) {
rs_assert_ok( rs );
rs->sr_err, rs->sr_text ? rs->sr_text : "", NULL );
assert( LDAP_UNSOLICITED_ERROR( rs->sr_err ) );
+ /* TODO: Flush the entry if sr_type == REP_SEARCH/REP_SEARCHREF? */
+ RS_ASSERT( !(rs->sr_flags & REP_ENTRY_MASK) );
+ rs->sr_flags &= ~REP_ENTRY_MASK; /* paranoia */
+
rs->sr_type = REP_EXTENDED;
rs->sr_rspdata = NULL;
rs->sr_err,
rs->sr_sasldata ? (long) rs->sr_sasldata->bv_len : -1, NULL );
+ RS_ASSERT( !(rs->sr_flags & REP_ENTRY_MASK) );
+ rs->sr_flags &= ~REP_ENTRY_MASK; /* paranoia */
+
rs->sr_type = REP_SASL;
rs->sr_tag = slap_req2res( op->o_tag );
rs->sr_msgid = (rs->sr_tag != LBER_SEQUENCE) ? op->o_msgid : 0;
rs->sr_rspoid ? rs->sr_rspoid : "",
rs->sr_rspdata != NULL ? rs->sr_rspdata->bv_len : 0 );
+ RS_ASSERT( !(rs->sr_flags & REP_ENTRY_MASK) );
+ rs->sr_flags &= ~REP_ENTRY_MASK; /* paranoia */
+
rs->sr_type = REP_EXTENDED;
rs->sr_tag = slap_req2res( op->o_tag );
rs->sr_msgid = (rs->sr_tag != LBER_SEQUENCE) ? op->o_msgid : 0;
rs->sr_rspoid ? rs->sr_rspoid : "",
rs->sr_rspdata != NULL ? rs->sr_rspdata->bv_len : 0 );
+ RS_ASSERT( !(rs->sr_flags & REP_ENTRY_MASK) );
+ rs->sr_flags &= ~REP_ENTRY_MASK; /* paranoia */
+
rs->sr_type = REP_INTERMEDIATE;
rs->sr_tag = LDAP_RES_INTERMEDIATE;
rs->sr_msgid = op->o_msgid;
#endif
if ( op->o_res_ber ) {
/* read back control */
- rc = ber_printf( ber, "{O{" /*}}*/, &rs->sr_entry->e_name );
+ rc = ber_printf( ber, "t{O{" /*}}*/,
+ LDAP_RES_SEARCH_ENTRY, &rs->sr_entry->e_name );
} else {
rc = ber_printf( ber, "{it{O{" /*}}}*/, op->o_msgid,
LDAP_RES_SEARCH_ENTRY, &rs->sr_entry->e_name );
Statslog( LDAP_DEBUG_STATS2, "%s ENTRY dn=\"%s\"\n",
op->o_log_prefix, rs->sr_entry->e_nname.bv_val, 0, 0, 0 );
- if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) {
- be_entry_release_rw( op, rs->sr_entry, 0 );
- rs->sr_flags ^= REP_ENTRY_MUSTRELEASE;
- rs->sr_entry = NULL;
- }
+ rs_flush_entry( op, rs, NULL );
if ( op->o_res_ber == NULL ) {
bytes = send_ldap_ber( op, ber );
slap_sl_free( e_flags, op->o_tmpmemctx );
}
+ /* FIXME: Can break if rs now contains an extended response */
if ( rs->sr_operational_attrs ) {
attrs_free( rs->sr_operational_attrs );
rs->sr_operational_attrs = NULL;
}
rs->sr_attr_flags = SLAP_ATTRS_UNDEFINED;
- /* FIXME: I think rs->sr_type should be explicitly set to
- * REP_SEARCH here. That's what it was when we entered this
- * function. send_ldap_error may have changed it, but we
- * should set it back so that the cleanup functions know
- * what they're doing.
- */
- if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_SEARCH
- && rs->sr_entry
- && ( rs->sr_flags & REP_ENTRY_MUSTBEFREED ) )
- {
- entry_free( rs->sr_entry );
- rs->sr_entry = NULL;
- rs->sr_flags &= ~REP_ENTRY_MUSTBEFREED;
+ if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_SEARCH ) {
+ rs_flush_entry( op, rs, NULL );
+ } else {
+ RS_ASSERT( (rs->sr_flags & REP_ENTRY_MASK) == 0 );
}
if ( rs->sr_flags & REP_CTRLS_MUSTBEFREED ) {
}
rc = 0;
- if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) {
- assert( rs->sr_entry != NULL );
- be_entry_release_rw( op, rs->sr_entry, 0 );
- rs->sr_flags ^= REP_ENTRY_MUSTRELEASE;
- rs->sr_entry = NULL;
- }
+ rs_flush_entry( op, rs, NULL );
#ifdef LDAP_CONNECTIONLESS
if (!op->o_conn || op->o_conn->c_is_udp == 0) {
myop.o_res_ber = ber;
myop.o_callback = NULL;
myop.ors_slimit = 1;
+ myop.ors_attrsonly = 0;
rc = slap_send_search_entry( &myop, rs );
if( rc ) return rc;