static int mdb_tool_idl_flush_db( MDB_txn *txn, AttrInfo *ai ) { MDB_cursor *mc; Avlnode *root; int rc; mdb_cursor_open( txn, ai->ai_dbi, &mc ); root = tavl_end( ai->ai_root, TAVL_DIR_LEFT ); do { rc = mdb_tool_idl_flush_one( mc, ai, root->avl_data ); if ( rc != -1 ) rc = 0; } while ((root = tavl_next(root, TAVL_DIR_RIGHT))); mdb_cursor_close( mc ); return rc; }
static void send_entry( Operation *op, SlapReply *rs, sort_op *so) { Debug(LDAP_DEBUG_TRACE, "%s: response control: status=%d, text=%s\n", debug_header, rs->sr_err, SAFESTR(rs->sr_text, "<None>")); if ( !so->so_tree ) return; /* RFC 2891: If critical then send the entries iff they were * successfully sorted. If non-critical send all entries * whether they were sorted or not. */ if ( (op->o_ctrlflag[sss_cid] != SLAP_CONTROL_CRITICAL) || (rs->sr_err == LDAP_SUCCESS) ) { if ( so->so_vlv > SLAP_CONTROL_IGNORED ) { send_list( op, rs, so ); } else { /* Get the first node to send */ TAvlnode *start_node = tavl_end(so->so_tree, TAVL_DIR_LEFT); so->so_tree = start_node; if ( so->so_paged <= SLAP_CONTROL_IGNORED ) { /* Not paged result search. Send all entries. * Set the page size to the number of entries * so that send_page() will send all entries. */ so->so_page_size = so->so_nentries; } send_page( op, rs, so ); } } }
int main( int argc, char **argv ) { Avlnode *tree = NULL, *n; char command[ 10 ]; char name[ 80 ]; char *p; printf( "> " ); while ( fgets( command, sizeof( command ), stdin ) != NULL ) { switch( *command ) { case 'n': /* new tree */ ( void ) tavl_free( tree, free ); tree = NULL; break; case 'p': /* print */ ( void ) myprint( tree ); break; case 't': /* traverse with first, next */ printf( "***\n" ); for ( n = tavl_end( tree, TAVL_DIR_LEFT ); n != NULL; n = tavl_next( n, TAVL_DIR_RIGHT )) printf( "%s\n", n->avl_data ); printf( "***\n" ); break; case 'f': /* find */ printf( "data? " ); if ( fgets( name, sizeof( name ), stdin ) == NULL ) exit( EXIT_SUCCESS ); name[ strlen( name ) - 1 ] = '\0'; if ( (p = (char *) tavl_find( tree, name, avl_strcmp )) == NULL ) printf( "Not found.\n\n" ); else printf( "%s\n\n", p ); break; case 'i': /* insert */ printf( "data? " ); if ( fgets( name, sizeof( name ), stdin ) == NULL ) exit( EXIT_SUCCESS ); name[ strlen( name ) - 1 ] = '\0'; if ( tavl_insert( &tree, strdup( name ), avl_strcmp, avl_dup_error ) != 0 ) printf( "\nNot inserted!\n" ); break; case 'd': /* delete */ printf( "data? " ); if ( fgets( name, sizeof( name ), stdin ) == NULL ) exit( EXIT_SUCCESS ); name[ strlen( name ) - 1 ] = '\0'; if ( tavl_delete( &tree, name, avl_strcmp ) == NULL ) printf( "\nNot found!\n" ); break; case 'q': /* quit */ exit( EXIT_SUCCESS ); break; case '\n': break; default: printf("Commands: insert, delete, print, new, quit\n"); } printf( "> " ); } return( 0 ); }
static int translucent_search(Operation *op, SlapReply *rs) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; translucent_info *ov = on->on_bi.bi_private; slap_callback cb = { NULL, NULL, NULL, NULL }; trans_ctx tc; Filter *fl, *fr; struct berval fbv; int rc = 0; if ( op->o_managedsait > SLAP_CONTROL_IGNORED ) return SLAP_CB_CONTINUE; Debug(LDAP_DEBUG_TRACE, "==> translucent_search: <%s> %s\n", op->o_req_dn.bv_val, op->ors_filterstr.bv_val, 0); if(ov->defer_db_open) { send_ldap_error(op, rs, LDAP_UNAVAILABLE, "remote DB not available"); return(rs->sr_err); } fr = ov->remote ? trans_filter_dup( op, op->ors_filter, ov->remote ) : NULL; fl = ov->local ? trans_filter_dup( op, op->ors_filter, ov->local ) : NULL; cb.sc_response = (slap_response *) translucent_search_cb; cb.sc_private = &tc; cb.sc_next = op->o_callback; ov->db.be_acl = op->o_bd->be_acl; tc.db = op->o_bd; tc.on = on; tc.orig = op->ors_filter; tc.list = NULL; tc.step = 0; tc.slimit = op->ors_slimit; tc.attrs = NULL; fbv = op->ors_filterstr; op->o_callback = &cb; if ( fr || !fl ) { tc.attrs = op->ors_attrs; op->ors_slimit = SLAP_NO_LIMIT; op->ors_attrs = slap_anlist_all_attributes; op->o_bd = &ov->db; tc.step |= RMT_SIDE; if ( fl ) { tc.step |= USE_LIST; op->ors_filter = fr; filter2bv_x( op, fr, &op->ors_filterstr ); } rc = ov->db.bd_info->bi_op_search(op, rs); if ( op->ors_attrs == slap_anlist_all_attributes ) op->ors_attrs = tc.attrs; op->o_bd = tc.db; if ( fl ) { op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx ); } } if ( fl && !rc ) { tc.step |= LCL_SIDE; op->ors_filter = fl; filter2bv_x( op, fl, &op->ors_filterstr ); rc = overlay_op_walk( op, rs, op_search, on->on_info, on->on_next ); op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx ); } op->ors_filterstr = fbv; op->ors_filter = tc.orig; op->o_callback = cb.sc_next; rs->sr_attrs = op->ors_attrs; rs->sr_attr_flags = slap_attr_flags( rs->sr_attrs ); /* Send out anything remaining on the list and finish */ if ( tc.step & USE_LIST ) { if ( tc.list ) { Avlnode *av; av = tavl_end( tc.list, TAVL_DIR_LEFT ); while ( av ) { rs->sr_entry = av->avl_data; if ( rc == LDAP_SUCCESS && LDAP_COMPARE_TRUE == test_filter( op, rs->sr_entry, op->ors_filter )) { rs->sr_flags = REP_ENTRY_MUSTBEFREED; rc = send_search_entry( op, rs ); } else { entry_free( rs->sr_entry ); } av = tavl_next( av, TAVL_DIR_RIGHT ); } tavl_free( tc.list, NULL ); rs->sr_flags = 0; rs->sr_entry = NULL; } send_ldap_result( op, rs ); } op->ors_slimit = tc.slimit; /* Free in reverse order */ if ( fl ) trans_filter_free( op, fl ); if ( fr ) trans_filter_free( op, fr ); return rc; }
static void send_list( Operation *op, SlapReply *rs, sort_op *so) { TAvlnode *cur_node, *tmp_node; vlv_ctrl *vc = op->o_controls[vlv_cid]; int i, j, dir, rc; BackendDB *be; Entry *e; LDAPControl *ctrls[2]; rs->sr_attrs = op->ors_attrs; /* FIXME: it may be better to just flatten the tree into * an array before doing all of this... */ /* Are we just counting an offset? */ if ( BER_BVISNULL( &vc->vc_value )) { if ( vc->vc_offset == vc->vc_count ) { /* wants the last entry in the list */ cur_node = tavl_end(so->so_tree, TAVL_DIR_RIGHT); so->so_vlv_target = so->so_nentries; } else if ( vc->vc_offset == 1 ) { /* wants the first entry in the list */ cur_node = tavl_end(so->so_tree, TAVL_DIR_LEFT); so->so_vlv_target = 1; } else { int target; /* Just iterate to the right spot */ if ( vc->vc_count && vc->vc_count != so->so_nentries ) { if ( vc->vc_offset > vc->vc_count ) goto range_err; target = so->so_nentries * vc->vc_offset / vc->vc_count; } else { if ( vc->vc_offset > so->so_nentries ) { range_err: so->so_vlv_rc = LDAP_VLV_RANGE_ERROR; pack_vlv_response_control( op, rs, so, ctrls ); ctrls[1] = NULL; slap_add_ctrls( op, rs, ctrls ); rs->sr_err = LDAP_VLV_ERROR; return; } target = vc->vc_offset; } so->so_vlv_target = target; /* Start at left and go right, or start at right and go left? */ if ( target < so->so_nentries / 2 ) { cur_node = tavl_end(so->so_tree, TAVL_DIR_LEFT); dir = TAVL_DIR_RIGHT; } else { cur_node = tavl_end(so->so_tree, TAVL_DIR_RIGHT); dir = TAVL_DIR_LEFT; target = so->so_nentries - target + 1; } for ( i=1; i<target; i++ ) cur_node = tavl_next( cur_node, dir ); } } else { /* we're looking for a specific value */ sort_ctrl *sc = so->so_ctrl; MatchingRule *mr = sc->sc_keys[0].sk_ordering; sort_node *sn; struct berval bv; if ( mr->smr_normalize ) { rc = mr->smr_normalize( SLAP_MR_VALUE_OF_SYNTAX, mr->smr_syntax, mr, &vc->vc_value, &bv, op->o_tmpmemctx ); if ( rc ) { so->so_vlv_rc = LDAP_INAPPROPRIATE_MATCHING; pack_vlv_response_control( op, rs, so, ctrls ); ctrls[1] = NULL; slap_add_ctrls( op, rs, ctrls ); rs->sr_err = LDAP_VLV_ERROR; return; } } else { bv = vc->vc_value; } sn = op->o_tmpalloc( sizeof(sort_node) + sc->sc_nkeys * sizeof(struct berval), op->o_tmpmemctx ); sn->sn_vals = (struct berval *)(sn+1); sn->sn_conn = op->o_conn->c_conn_idx; sn->sn_session = find_session_by_so( so->so_info->svi_max_percon, op->o_conn->c_conn_idx, so ); sn->sn_vals[0] = bv; for (i=1; i<sc->sc_nkeys; i++) { BER_BVZERO( &sn->sn_vals[i] ); } cur_node = tavl_find3( so->so_tree, sn, node_cmp, &j ); /* didn't find >= match */ if ( j > 0 ) { if ( cur_node ) cur_node = tavl_next( cur_node, TAVL_DIR_RIGHT ); } op->o_tmpfree( sn, op->o_tmpmemctx ); if ( !cur_node ) { so->so_vlv_target = so->so_nentries + 1; } else { sort_node *sn = so->so_tree->avl_data; /* start from the left or the right side? */ mr->smr_match( &i, 0, mr->smr_syntax, mr, &bv, &sn->sn_vals[0] ); if ( i > 0 ) { tmp_node = tavl_end(so->so_tree, TAVL_DIR_RIGHT); dir = TAVL_DIR_LEFT; } else { tmp_node = tavl_end(so->so_tree, TAVL_DIR_LEFT); dir = TAVL_DIR_RIGHT; } for (i=0; tmp_node != cur_node; tmp_node = tavl_next( tmp_node, dir ), i++); so->so_vlv_target = (dir == TAVL_DIR_RIGHT) ? i+1 : so->so_nentries - i; } if ( bv.bv_val != vc->vc_value.bv_val ) op->o_tmpfree( bv.bv_val, op->o_tmpmemctx ); } if ( !cur_node ) { i = 1; cur_node = tavl_end(so->so_tree, TAVL_DIR_RIGHT); } else { i = 0; } for ( ; i<vc->vc_before; i++ ) { tmp_node = tavl_next( cur_node, TAVL_DIR_LEFT ); if ( !tmp_node ) break; cur_node = tmp_node; } j = i + vc->vc_after + 1; be = op->o_bd; for ( i=0; i<j; i++ ) { sort_node *sn = cur_node->avl_data; if ( slapd_shutdown ) break; op->o_bd = select_backend( &sn->sn_dn, 0 ); e = NULL; rc = be_entry_get_rw( op, &sn->sn_dn, NULL, NULL, 0, &e ); if ( e && rc == LDAP_SUCCESS ) { rs->sr_entry = e; rs->sr_flags = REP_ENTRY_MUSTRELEASE; rs->sr_err = send_search_entry( op, rs ); if ( rs->sr_err == LDAP_UNAVAILABLE ) break; } cur_node = tavl_next( cur_node, TAVL_DIR_RIGHT ); if ( !cur_node ) break; } so->so_vlv_rc = LDAP_SUCCESS; op->o_bd = be; }