1 /* idl.c - ldap id list handling routines */
4 * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
12 #include <ac/string.h>
13 #include <ac/socket.h>
17 #define IDL_CMP(x,y) ( x < y ? -1 : ( x > y ? 1 : 0 ) )
19 static int idl_search( ID *ids, ID id )
22 * binary search of id in ids
23 * if found, returns position of id
24 * if not found, returns first postion greater than id
33 cursor = base + pivot;
34 val = IDL_CMP( id, ids[cursor + 1] );
39 } else if ( val > 0 ) {
55 static int idl_insert( ID *ids, ID id )
57 int x = idl_search( ids, id );
69 } else if ( ++ids[0] >= BDB_IDL_MAX ) {
74 AC_MEMCPY( &ids[x+1], &ids[x], (ids[0]-x) * sizeof(ID) );
82 static int idl_delete( ID *ids, ID id )
84 int x = idl_search( ids, id );
86 if( x == 0 || ids[x] != id ) {
90 } else if ( --ids[0] == 0 ) {
91 if( x != 1 ) return -1;
94 AC_MEMCPY( &ids[x], &ids[x+1], (1+ids[0]-x) * sizeof(ID) );
109 ID ids[BDB_IDL_SIZE];
112 assert( id != NOID );
115 data.ulen = sizeof( ids );
116 data.flags = DB_DBT_USERMEM;
118 /* fetch the key and grab a write lock */
119 rc = db->get( db, tid, key, &data, DB_RMW );
121 if( rc == DB_NOTFOUND ) {
124 data.size = 2 * sizeof( ID );
126 } else if ( rc != 0 ) {
129 } else if ( data.size == 0 || data.size % sizeof( ID ) ) {
130 /* size not multiple of ID size */
133 } else if ( BDB_IS_ALLIDS(ids) ) {
136 } else if ( data.size != (1 + ids[0]) * sizeof( ID ) ) {
141 rc = idl_insert( ids, id );
143 if( rc != 0 ) return rc;
145 data.size = (ids[0]+1) * sizeof( ID );
149 rc = db->put( db, tid, key, &data, 0 );
163 ID ids[BDB_IDL_SIZE];
166 assert( id != NOID );
169 data.ulen = sizeof( ids );
170 data.flags = DB_DBT_USERMEM;
172 /* fetch the key and grab a write lock */
173 rc = db->get( db, tid, key, &data, DB_RMW );
178 } else if ( data.size == 0 || data.size % sizeof( ID ) ) {
179 /* size not multiple of ID size */
182 } else if ( BDB_IS_ALLIDS(ids) ) {
185 } else if ( data.size != (1 + ids[0]) * sizeof( ID ) ) {
190 rc = idl_delete( ids, id );
192 if( rc != 0 ) return rc;
194 if( BDB_IS_ALLIDS(ids) ) {
196 rc = db->del( db, tid, key, 0 );
200 data.size = (ids[0]+1) * sizeof( ID );
204 rc = db->put( db, tid, key, &data, 0 );