+ Datum data;
+ ID_BLOCK *idl, *tmp;
+ unsigned i;
+ int j, nids;
+ char *kstr;
+
+ if ( (idl = idl_fetch_one( be, db, key ) ) == NULL )
+ {
+ /* It wasn't found. Hmm... */
+ return -1;
+ }
+
+ if ( ID_BLOCK_ALLIDS( idl ) ) {
+ idl_free( idl );
+ return 0;
+ }
+
+ if ( ! ID_BLOCK_INDIRECT( idl ) ) {
+ for ( i=0; i < ID_BLOCK_NIDS(idl); i++ ) {
+ if ( ID_BLOCK_ID(idl, i) == id ) {
+ if( --ID_BLOCK_NIDS(idl) == 0 ) {
+ ldbm_cache_delete( db, key );
+
+ } else {
+ SAFEMEMCPY (
+ &ID_BLOCK_ID(idl, i),
+ &ID_BLOCK_ID(idl, i+1),
+ (ID_BLOCK_NIDS(idl)-i) * sizeof(ID) );
+
+ ID_BLOCK_ID(idl, ID_BLOCK_NIDS(idl)) = NOID;
+
+ idl_store( be, db, key, idl );
+ }
+
+ idl_free( idl );
+ return 0;
+ }
+ /* We didn't find the ID. Hmmm... */
+ }
+ idl_free( idl );
+ return -1;
+ }
+
+ /* We have to go through an indirect block and find the ID
+ in the list of IDL's
+ */
+ for ( nids = 0; !ID_BLOCK_NOID(idl, nids); nids++ )
+ ; /* NULL */
+ kstr = (char *) ch_malloc( key.dsize + CONT_SIZE );
+
+ for ( j = 0; !ID_BLOCK_NOID(idl, j); j++ )
+ {
+ ldbm_datum_init( data );
+ sprintf( kstr, "%c%ld%s", CONT_PREFIX,
+ ID_BLOCK_ID(idl, j), key.dptr );
+ data.dptr = kstr;
+ data.dsize = strlen( kstr ) + 1;
+
+ if ( (tmp = idl_fetch_one( be, db, data )) == NULL ) {
+ Debug( LDAP_DEBUG_ANY,
+ "idl_fetch of (%s) returns NULL\n", data.dptr, 0, 0 );
+ continue;
+ }
+ /*
+ Now try to find the ID in tmp
+ */
+ for ( i=0; i < ID_BLOCK_NIDS(tmp); i++ )
+ {
+ if ( ID_BLOCK_ID(tmp, i) == id )
+ {
+ SAFEMEMCPY(
+ &ID_BLOCK_ID(tmp, i),
+ &ID_BLOCK_ID(tmp, i+1),
+ (ID_BLOCK_NIDS(tmp)-(i+1)) * sizeof(ID));
+ ID_BLOCK_ID(tmp, ID_BLOCK_NIDS(tmp)-1 ) = NOID;
+ ID_BLOCK_NIDS(tmp)--;
+
+ if ( ID_BLOCK_NIDS(tmp) ) {
+ idl_store ( be, db, data, tmp );
+
+ } else {
+ ldbm_cache_delete( db, data );
+ SAFEMEMCPY(
+ &ID_BLOCK_ID(idl, j),
+ &ID_BLOCK_ID(idl, j+1),
+ (nids-(j+1)) * sizeof(ID));
+ ID_BLOCK_ID(idl, nids-1) = NOID;
+ nids--;
+ if ( ! nids )
+ ldbm_cache_delete( db, key );
+ else
+ idl_store( be, db, key, idl );
+ }
+ idl_free( tmp );
+ free( kstr );
+ idl_free( idl );
+ return 0;
+ }
+ }
+ idl_free( tmp );
+ }
+ free( kstr );
+ idl_free( idl );
+ return -1;
+}
+
+
+/* return a duplicate of a single ID_BLOCK */
+static ID_BLOCK *
+idl_dup( ID_BLOCK *idl )
+{
+ ID_BLOCK *new;