Esempio n. 1
0
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 );
}
Esempio n. 2
0
static int sssvlv_op_response(
	Operation	*op,
	SlapReply	*rs )
{
	sort_ctrl *sc = op->o_controls[sss_cid];
	sort_op *so = op->o_callback->sc_private;

	if ( rs->sr_type == REP_SEARCH ) {
		int i;
		size_t len;
		sort_node *sn, *sn2;
		struct berval *bv;
		char *ptr;

		len = sizeof(sort_node) + sc->sc_nkeys * sizeof(struct berval) +
			rs->sr_entry->e_nname.bv_len + 1;
		sn = op->o_tmpalloc( len, op->o_tmpmemctx );
		sn->sn_vals = (struct berval *)(sn+1);

		/* Build tmp list of key values */
		for ( i=0; i<sc->sc_nkeys; i++ ) {
			Attribute *a = attr_find( rs->sr_entry->e_attrs,
				sc->sc_keys[i].sk_ad );
			if ( a ) {
				if ( a->a_numvals > 1 ) {
					bv = select_value( a, &sc->sc_keys[i] );
				} else {
					bv = a->a_nvals;
				}
				sn->sn_vals[i] = *bv;
				len += bv->bv_len + 1;
			} else {
				BER_BVZERO( &sn->sn_vals[i] );
			}
		}

		/* Now dup into regular memory */
		sn2 = ch_malloc( len );
		sn2->sn_vals = (struct berval *)(sn2+1);
		memcpy( sn2->sn_vals, sn->sn_vals,
				sc->sc_nkeys * sizeof(struct berval));

		ptr = (char *)(sn2->sn_vals + sc->sc_nkeys);
		sn2->sn_dn.bv_val = ptr;
		sn2->sn_dn.bv_len = rs->sr_entry->e_nname.bv_len;
		memcpy( ptr, rs->sr_entry->e_nname.bv_val,
			rs->sr_entry->e_nname.bv_len );
		ptr += rs->sr_entry->e_nname.bv_len;
		*ptr++ = '\0';
		for ( i=0; i<sc->sc_nkeys; i++ ) {
			if ( !BER_BVISNULL( &sn2->sn_vals[i] )) {
				memcpy(ptr, sn2->sn_vals[i].bv_val, sn2->sn_vals[i].bv_len);
				sn2->sn_vals[i].bv_val = ptr;
				ptr += sn2->sn_vals[i].bv_len;
				*ptr++ = '\0';
			}
		}
		op->o_tmpfree( sn, op->o_tmpmemctx );
		sn = sn2;
		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 );

		/* Insert into the AVL tree */
		tavl_insert(&(so->so_tree), sn, node_insert, avl_dup_error);

		so->so_nentries++;

		/* Collected the keys so that they can be sorted.  Thus, stop
		 * the entry from propagating.
		 */
		rs->sr_err = LDAP_SUCCESS;
	}
	else if ( rs->sr_type == REP_RESULT ) {
		/* Remove serversort response callback.
		 * We don't want the entries that we are about to send to be
		 * processed by serversort response again. */
		slap_callback **scp = &op->o_callback;
		while ( *scp ) {
			if ( (*scp)->sc_response == sssvlv_op_response ) {
				*scp = (*scp)->sc_next;
				break;
			}
			scp = &(*scp)->sc_next;
		}

		send_entry( op, rs, so );
		send_result( op, rs, so );
	}

	return rs->sr_err;
}
Esempio n. 3
0
static int translucent_search_cb(Operation *op, SlapReply *rs) {
	trans_ctx *tc;
	BackendDB *db;
	slap_overinst *on;
	translucent_info *ov;
	Entry *le, *re;
	Attribute *a, *ax, *an, *as = NULL;
	int rc;
	int test_f = 0;

	tc = op->o_callback->sc_private;

	/* Don't let the op complete while we're gathering data */
	if ( rs->sr_type == REP_RESULT && ( tc->step & USE_LIST ))
		return 0;

	if(rs->sr_type != REP_SEARCH || !rs->sr_entry)
		return(SLAP_CB_CONTINUE);

	Debug(LDAP_DEBUG_TRACE, "==> translucent_search_cb: %s\n",
		rs->sr_entry->e_name.bv_val, 0, 0);

	op->ors_slimit = tc->slimit + ( tc->slimit > 0 ? 1 : 0 );
	if ( op->ors_attrs == slap_anlist_all_attributes ) {
		op->ors_attrs = tc->attrs;
		rs->sr_attrs = tc->attrs;
		rs->sr_attr_flags = slap_attr_flags( rs->sr_attrs );
	}

	on = tc->on;
	ov = on->on_bi.bi_private;

	db = op->o_bd;
	re = NULL;

	/* If we have local, get remote */
	if ( tc->step & LCL_SIDE ) {
		le = rs->sr_entry;
		/* If entry is already on list, use it */
		if ( tc->step & USE_LIST ) {
			re = tavl_delete( &tc->list, le, entry_dn_cmp );
			if ( re ) {
				rs_flush_entry( op, rs, on );
				rc = test_filter( op, re, tc->orig );
				if ( rc == LDAP_COMPARE_TRUE ) {
					rs->sr_flags |= REP_ENTRY_MUSTBEFREED;
					rs->sr_entry = re;

					if ( tc->slimit >= 0 && rs->sr_nentries >= tc->slimit ) {
						return LDAP_SIZELIMIT_EXCEEDED;
					}

					return SLAP_CB_CONTINUE;
				} else {
					entry_free( re );
					rs->sr_entry = NULL;
					return 0;
				}
			}
		}
		op->o_bd = &ov->db;
		rc = be_entry_get_rw( op, &rs->sr_entry->e_nname, NULL, NULL, 0, &re );
		if ( rc == LDAP_SUCCESS && re ) {
			Entry *tmp = entry_dup( re );
			be_entry_release_r( op, re );
			re = tmp;
			test_f = 1;
		}
	} else {
	/* Else we have remote, get local */
		op->o_bd = tc->db;
		le = NULL;
		rc = overlay_entry_get_ov(op, &rs->sr_entry->e_nname, NULL, NULL, 0, &le, on);
		if ( rc == LDAP_SUCCESS && le ) {
			re = entry_dup( rs->sr_entry );
			rs_flush_entry( op, rs, on );
		} else {
			le = NULL;
		}
	}

/*
** if we got remote and local entry:
**	foreach local attr:
**		foreach remote attr:
**			if match, remote attr with local attr;
**			if new local, add to list;
**	append new local attrs to remote;
**
*/

	if ( re && le ) {
		for(ax = le->e_attrs; ax; ax = ax->a_next) {
			for(a = re->e_attrs; a; a = a->a_next) {
				if(a->a_desc == ax->a_desc) {
					test_f = 1;
					if(a->a_vals != a->a_nvals)
						ber_bvarray_free(a->a_nvals);
					ber_bvarray_free(a->a_vals);
					ber_bvarray_dup_x( &a->a_vals, ax->a_vals, NULL );
					if ( ax->a_vals == ax->a_nvals ) {
						a->a_nvals = a->a_vals;
					} else {
						ber_bvarray_dup_x( &a->a_nvals, ax->a_nvals, NULL );
					}
					break;
				}
			}
			if(a) continue;
			an = attr_dup(ax);
			an->a_next = as;
			as = an;
		}
		/* Dispose of local entry */
		if ( tc->step & LCL_SIDE ) {
			rs_flush_entry(op, rs, on);
		} else {
			overlay_entry_release_ov(op, le, 0, on);
		}

		/* literally append, so locals are always last */
		if(as) {
			if(re->e_attrs) {
				for(ax = re->e_attrs; ax->a_next; ax = ax->a_next);
				ax->a_next = as;
			} else {
				re->e_attrs = as;
			}
		}
		/* If both filters, save entry for later */
		if ( tc->step == (USE_LIST|RMT_SIDE) ) {
			tavl_insert( &tc->list, re, entry_dn_cmp, avl_dup_error );
			rs->sr_entry = NULL;
			rc = 0;
		} else {
		/* send it now */
			rs->sr_entry = re;
			rs->sr_flags |= REP_ENTRY_MUSTBEFREED;
			if ( test_f ) {
				rc = test_filter( op, rs->sr_entry, tc->orig );
				if ( rc == LDAP_COMPARE_TRUE ) {
					rc = SLAP_CB_CONTINUE;
				} else {
					rc = 0;
				}
			} else {
				rc = SLAP_CB_CONTINUE;
			}
		}
	} else if ( le ) {
	/* Only a local entry: remote was deleted
	 * Ought to delete the local too...
	 */
	 	rc = 0;
	} else if ( tc->step & USE_LIST ) {
	/* Only a remote entry, but both filters:
	 * Test the complete filter
	 */
		rc = test_filter( op, rs->sr_entry, tc->orig );
		if ( rc == LDAP_COMPARE_TRUE ) {
			rc = SLAP_CB_CONTINUE;
		} else {
			rc = 0;
		}
	} else {
	/* Only a remote entry, only remote filter:
	 * just pass thru
	 */
		rc = SLAP_CB_CONTINUE;
	}

	op->o_bd = db;

	if ( rc == SLAP_CB_CONTINUE && tc->slimit >= 0 && rs->sr_nentries >= tc->slimit ) {
		return LDAP_SIZELIMIT_EXCEEDED;
	}

	return rc;
}
Esempio n. 4
0
int mdb_tool_idl_add(
	MDB_cursor *mc,
	struct berval *keys,
	ID id )
{
	MDB_dbi dbi;
	mdb_tool_idl_cache *ic, itmp;
	mdb_tool_idl_cache_entry *ice;
	int i, rc, lcount;
	AttrInfo *ai = (AttrInfo *)mc;
	mc = ai->ai_cursor;

	dbi = ai->ai_dbi;
	for (i=0; keys[i].bv_val; i++) {
	itmp.kstr = keys[i];
	ic = tavl_find( (Avlnode *)ai->ai_root, &itmp, mdb_tool_idl_cmp );

	/* No entry yet, create one */
	if ( !ic ) {
		MDB_val key, data;
		ID nid;
		int rc;

		if ( ai->ai_clist ) {
			ic = ai->ai_clist;
			ai->ai_clist = ic->head;
		} else {
			ic = ch_malloc( sizeof( mdb_tool_idl_cache ) + itmp.kstr.bv_len + 4 );
		}
		ic->kstr.bv_len = itmp.kstr.bv_len;
		ic->kstr.bv_val = (char *)(ic+1);
		memcpy( ic->kstr.bv_val, itmp.kstr.bv_val, ic->kstr.bv_len );
		ic->head = ic->tail = NULL;
		ic->last = 0;
		ic->count = 0;
		ic->offset = 0;
		ic->flags = 0;
		tavl_insert( (Avlnode **)&ai->ai_root, ic, mdb_tool_idl_cmp,
			avl_dup_error );

		/* load existing key count here */
		key.mv_size = keys[i].bv_len;
		key.mv_data = keys[i].bv_val;
		rc = mdb_cursor_get( mc, &key, &data, MDB_SET );
		if ( rc == 0 ) {
			ic->flags |= WAS_FOUND;
			nid = *(ID *)data.mv_data;
			if ( nid == 0 ) {
				ic->count = MDB_IDL_DB_SIZE+1;
				ic->flags |= WAS_RANGE;
			} else {
				size_t count;

				mdb_cursor_count( mc, &count );
				ic->count = count;
				ic->first = nid;
				ic->offset = count & (IDBLOCK-1);
			}
		}
	}
	/* are we a range already? */
	if ( ic->count > MDB_IDL_DB_SIZE ) {
		ic->last = id;
		continue;
	/* Are we at the limit, and converting to a range? */
	} else if ( ic->count == MDB_IDL_DB_SIZE ) {
		if ( ic->head ) {
			ic->tail->next = ai->ai_flist;
			ai->ai_flist = ic->head;
		}
		ic->head = ic->tail = NULL;
		ic->last = id;
		ic->count++;
		continue;
	}
	/* No free block, create that too */
	lcount = ic->count & (IDBLOCK-1);
	if ( !ic->tail || lcount == 0) {
		if ( ai->ai_flist ) {
			ice = ai->ai_flist;
			ai->ai_flist = ice->next;
		} else {
			ice = ch_malloc( sizeof( mdb_tool_idl_cache_entry ));
		}
		ice->next = NULL;
		if ( !ic->head ) {
			ic->head = ice;
		} else {
			ic->tail->next = ice;
		}
		ic->tail = ice;
		if ( lcount )
			ice->ids[lcount-1] = 0;
		if ( !ic->count )
			ic->first = id;
	}
	ice = ic->tail;
	if (!lcount || ice->ids[lcount-1] != id)
		ice->ids[lcount] = id;
	ic->count++;
	}

	return 0;
}