int mdb_id2l_insert( ID2L ids, ID2 *id ) { unsigned x, i; x = mdb_id2l_search( ids, id->mid ); assert( x > 0 ); if( x < 1 ) { /* internal error */ return -2; } if ( x <= ids[0].mid && ids[x].mid == id->mid ) { /* duplicate */ return -1; } if ( ids[0].mid >= MDB_IDL_UM_MAX ) { /* too big */ return -2; } else { /* insert id */ ids[0].mid++; for (i=ids[0].mid; i>x; i--) ids[i] = ids[i-1]; ids[x] = *id; } return 0; }
/* See if ID is a child of any of the scopes, * return MDB_KEYEXIST if so. */ int mdb_idscopechk( Operation *op, IdScopes *isc ) { struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private; MDB_val key, data; ID id, prev; char *ptr; int rc = 0; unsigned int x; key.mv_size = sizeof(ID); if ( !isc->mc ) { rc = mdb_cursor_open( isc->mt, mdb->mi_dn2id, &isc->mc ); if ( rc ) return rc; } id = isc->id; while (id) { if ( !rc ) { key.mv_data = &id; rc = mdb_cursor_get( isc->mc, &key, &data, MDB_SET ); if ( rc ) return rc; } ptr = data.mv_data; ptr += data.mv_size - sizeof(ID); prev = id; memcpy( &id, ptr, sizeof(ID) ); /* If we didn't advance, some parent is missing */ if ( id == prev ) return MDB_NOTFOUND; x = mdb_id2l_search( isc->scopes, id ); if ( x <= isc->scopes[0].mid && isc->scopes[x].mid == id ) return MDB_KEYEXIST; } return MDB_SUCCESS; }
/* See if base is a child of any of the scopes */ int mdb_idscopes( Operation *op, IdScopes *isc ) { struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private; MDB_dbi dbi = mdb->mi_dn2id; MDB_val key, data; ID id, prev; ID2 id2; char *ptr; int rc = 0; unsigned int x; unsigned int nrlen, rlen; diskNode *d; key.mv_size = sizeof(ID); if ( !isc->mc ) { rc = mdb_cursor_open( isc->mt, dbi, &isc->mc ); if ( rc ) return rc; } id = isc->id; /* Catch entries from deref'd aliases */ x = mdb_id2l_search( isc->scopes, id ); if ( x <= isc->scopes[0].mid && isc->scopes[x].mid == id ) { isc->nscope = x; return MDB_SUCCESS; } isc->sctmp[0].mid = 0; while (id) { if ( !rc ) { key.mv_data = &id; rc = mdb_cursor_get( isc->mc, &key, &data, MDB_SET ); if ( rc ) return rc; /* save RDN info */ } d = data.mv_data; nrlen = (d->nrdnlen[0] << 8) | d->nrdnlen[1]; rlen = data.mv_size - sizeof(diskNode) - nrlen; isc->nrdns[isc->numrdns].bv_len = nrlen; isc->nrdns[isc->numrdns].bv_val = d->nrdn; isc->rdns[isc->numrdns].bv_len = rlen; isc->rdns[isc->numrdns].bv_val = d->nrdn+nrlen+1; isc->numrdns++; if (!rc && id != isc->id) { /* remember our chain of parents */ id2.mid = id; id2.mval = data; rc = mdb_id2l_insert( isc->sctmp, &id2 ); assert(rc == 0); } ptr = data.mv_data; ptr += data.mv_size - sizeof(ID); prev = id; memcpy( &id, ptr, sizeof(ID) ); /* If we didn't advance, some parent is missing */ if ( id == prev ) return MDB_NOTFOUND; x = mdb_id2l_search( isc->scopes, id ); if ( x <= isc->scopes[0].mid && isc->scopes[x].mid == id ) { if ( !isc->scopes[x].mval.mv_data ) { /* This node is in scope, add parent chain to scope */ int i; for ( i = 1; i <= isc->sctmp[0].mid; i++ ) { rc = mdb_id2l_insert( isc->scopes, &isc->sctmp[i] ); if ( rc ) break; } /* check id again since inserts may have changed its position */ if ( isc->scopes[x].mid != id ) x = mdb_id2l_search( isc->scopes, id ); isc->nscope = x; return MDB_SUCCESS; } data = isc->scopes[x].mval; rc = 1; } if ( op->ors_scope == LDAP_SCOPE_ONELEVEL ) break; } return MDB_SUCCESS; }
/* See if base is a child of any of the scopes */ int mdb_idscopes( Operation *op, IdScopes *isc ) { struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private; MDB_dbi dbi = mdb->mi_dn2id; MDB_val key, data; ID id; ID2 id2; char *ptr; int rc = 0; unsigned int x; unsigned int nrlen, rlen; diskNode *d; key.mv_size = sizeof(ID); if ( !isc->mc ) { rc = mdb_cursor_open( isc->mt, dbi, &isc->mc ); if ( rc ) return rc; } id = isc->id; while (id) { if ( !rc ) { key.mv_data = &id; rc = mdb_cursor_get( isc->mc, &key, &data, MDB_SET ); if ( rc ) return rc; /* save RDN info */ } d = data.mv_data; nrlen = (d->nrdnlen[0] << 8) | d->nrdnlen[1]; rlen = data.mv_size - sizeof(diskNode) - nrlen; isc->nrdns[isc->numrdns].bv_len = nrlen; isc->nrdns[isc->numrdns].bv_val = d->nrdn; isc->rdns[isc->numrdns].bv_len = rlen; isc->rdns[isc->numrdns].bv_val = d->nrdn+nrlen+1; isc->numrdns++; if (!rc && id != isc->id) { id2.mid = id; id2.mval = data; mdb_id2l_insert( isc->scopes, &id2 ); } ptr = data.mv_data; ptr += data.mv_size - sizeof(ID); memcpy( &id, ptr, sizeof(ID) ); x = mdb_id2l_search( isc->scopes, id ); if ( x <= isc->scopes[0].mid && isc->scopes[x].mid == id ) { if ( !isc->scopes[x].mval.mv_data ) { isc->nscope = x; return MDB_SUCCESS; } data = isc->scopes[x].mval; rc = 1; } if ( op->ors_scope == LDAP_SCOPE_ONELEVEL ) break; } return MDB_SUCCESS; }