Attribute * attrs_dup( Attribute *a ) { int i; Attribute *tmp, *anew; if( a == NULL ) return NULL; /* count them */ for( tmp=a,i=0; tmp; tmp=tmp->a_next ) { i++; } anew = attrs_alloc( i ); for( tmp=anew; a; a=a->a_next ) { tmp->a_desc = a->a_desc; attr_dup2( tmp, a ); tmp=tmp->a_next; } return anew; }
/* Duplicates an entry using a single malloc. Saves CPU time, increases * heap usage because a single large malloc is harder to satisfy than * lots of small ones, and the freed space isn't as easily reusable. * * Probably not worth using this function. */ Entry *entry_dup_bv( Entry *e ) { ber_len_t len; int nattrs, nvals; Entry *ret; struct berval *bvl; char *ptr; Attribute *src, *dst; ret = entry_alloc(); entry_partsize(e, &len, &nattrs, &nvals, 1); ret->e_id = e->e_id; ret->e_attrs = attrs_alloc( nattrs ); ret->e_ocflags = e->e_ocflags; ret->e_bv.bv_len = len + nvals * sizeof(struct berval); ret->e_bv.bv_val = ch_malloc( ret->e_bv.bv_len ); bvl = (struct berval *)ret->e_bv.bv_val; ptr = (char *)(bvl + nvals); ret->e_name.bv_len = e->e_name.bv_len; ret->e_name.bv_val = ptr; AC_MEMCPY( ptr, e->e_name.bv_val, e->e_name.bv_len ); ptr += e->e_name.bv_len; *ptr++ = '\0'; ret->e_nname.bv_len = e->e_nname.bv_len; ret->e_nname.bv_val = ptr; AC_MEMCPY( ptr, e->e_nname.bv_val, e->e_nname.bv_len ); ptr += e->e_name.bv_len; *ptr++ = '\0'; dst = ret->e_attrs; for (src = e->e_attrs; src; src=src->a_next,dst=dst->a_next ) { int i; dst->a_desc = src->a_desc; dst->a_flags = SLAP_ATTR_DONT_FREE_DATA | SLAP_ATTR_DONT_FREE_VALS; dst->a_vals = bvl; dst->a_numvals = src->a_numvals; for ( i=0; src->a_vals[i].bv_val; i++ ) { bvl->bv_len = src->a_vals[i].bv_len; bvl->bv_val = ptr; AC_MEMCPY( ptr, src->a_vals[i].bv_val, bvl->bv_len ); ptr += bvl->bv_len; *ptr++ = '\0'; bvl++; } BER_BVZERO(bvl); bvl++; if ( src->a_vals != src->a_nvals ) { dst->a_nvals = bvl; for ( i=0; src->a_nvals[i].bv_val; i++ ) { bvl->bv_len = src->a_nvals[i].bv_len; bvl->bv_val = ptr; AC_MEMCPY( ptr, src->a_nvals[i].bv_val, bvl->bv_len ); ptr += bvl->bv_len; *ptr++ = '\0'; bvl++; } BER_BVZERO(bvl); bvl++; } } return ret; }
/* * call from within bdb_db_open() */ int bdb_monitor_db_open( BackendDB *be ) { struct bdb_info *bdb = (struct bdb_info *) be->be_private; Attribute *a, *next; monitor_callback_t *cb = NULL; int rc = 0; BackendInfo *mi; monitor_extra_t *mbe; struct berval dummy = BER_BVC(""); if ( !SLAP_DBMONITORING( be ) ) { return 0; } mi = backend_info( "monitor" ); if ( !mi || !mi->bi_extra ) { SLAP_DBFLAGS( be ) ^= SLAP_DBFLAG_MONITORING; return 0; } mbe = mi->bi_extra; /* don't bother if monitor is not configured */ if ( !mbe->is_configured() ) { static int warning = 0; if ( warning++ == 0 ) { Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_monitor_db_open) ": monitoring disabled; " "configure monitor database to enable\n", 0, 0, 0 ); } return 0; } /* alloc as many as required (plus 1 for objectClass) */ a = attrs_alloc( 1 + 4 ); if ( a == NULL ) { rc = 1; goto cleanup; } a->a_desc = slap_schema.si_ad_objectClass; attr_valadd( a, &oc_olmBDBDatabase->soc_cname, NULL, 1 ); next = a->a_next; { struct berval bv = BER_BVC( "0" ); next->a_desc = ad_olmBDBEntryCache; attr_valadd( next, &bv, NULL, 1 ); next = next->a_next; next->a_desc = ad_olmBDBDNCache; attr_valadd( next, &bv, NULL, 1 ); next = next->a_next; next->a_desc = ad_olmBDBIDLCache; attr_valadd( next, &bv, NULL, 1 ); next = next->a_next; } { struct berval bv, nbv; ber_len_t pathlen = 0, len = 0; char path[ MAXPATHLEN ] = { '\0' }; char *fname = bdb->bi_dbenv_home, *ptr; len = strlen( fname ); if ( fname[ 0 ] != '/' ) { /* get full path name */ getcwd( path, sizeof( path ) ); pathlen = strlen( path ); if ( fname[ 0 ] == '.' && fname[ 1 ] == '/' ) { fname += 2; len -= 2; } } bv.bv_len = pathlen + STRLENOF( "/" ) + len; ptr = bv.bv_val = ch_malloc( bv.bv_len + STRLENOF( "/" ) + 1 ); if ( pathlen ) { ptr = lutil_strncopy( ptr, path, pathlen ); ptr[ 0 ] = '/'; ptr++; } ptr = lutil_strncopy( ptr, fname, len ); if ( ptr[ -1 ] != '/' ) { ptr[ 0 ] = '/'; ptr++; } ptr[ 0 ] = '\0'; attr_normalize_one( ad_olmDbDirectory, &bv, &nbv, NULL ); next->a_desc = ad_olmDbDirectory; next->a_vals = ch_calloc( sizeof( struct berval ), 2 ); next->a_vals[ 0 ] = bv; next->a_numvals = 1; if ( BER_BVISNULL( &nbv ) ) { next->a_nvals = next->a_vals; } else { next->a_nvals = ch_calloc( sizeof( struct berval ), 2 ); next->a_nvals[ 0 ] = nbv; } next = next->a_next; } cb = ch_calloc( sizeof( monitor_callback_t ), 1 ); cb->mc_update = bdb_monitor_update; #if 0 /* uncomment if required */ cb->mc_modify = bdb_monitor_modify; #endif cb->mc_free = bdb_monitor_free; cb->mc_private = (void *)bdb; /* make sure the database is registered; then add monitor attributes */ rc = mbe->register_database( be, &bdb->bi_monitor.bdm_ndn ); if ( rc == 0 ) { rc = mbe->register_entry_attrs( &bdb->bi_monitor.bdm_ndn, a, cb, &dummy, 0, &dummy ); } cleanup:; if ( rc != 0 ) { if ( cb != NULL ) { ch_free( cb ); cb = NULL; } if ( a != NULL ) { attrs_free( a ); a = NULL; } } /* store for cleanup */ bdb->bi_monitor.bdm_cb = (void *)cb; /* we don't need to keep track of the attributes, because * bdb_monitor_free() takes care of everything */ if ( a != NULL ) { attrs_free( a ); } return rc; }
int entry_decode(EntryHeader *eh, Entry **e) #endif { int i, j, nattrs, nvals ALLOW_UNUSED; int rc; Attribute *a; Entry *x; const char *text; AttributeDescription *ad; unsigned char *ptr = (unsigned char *)eh->bv.bv_val; BerVarray bptr; nattrs = eh->nattrs; nvals = eh->nvals; x = entry_alloc(); x->e_attrs = attrs_alloc( nattrs ); ptr = (unsigned char *)eh->data; i = entry_getlen(&ptr); x->e_name.bv_val = (char *) ptr; x->e_name.bv_len = i; ptr += i+1; i = entry_getlen(&ptr); x->e_nname.bv_val = (char *) ptr; x->e_nname.bv_len = i; ptr += i+1; Debug( LDAP_DEBUG_TRACE, "entry_decode: \"%s\"\n", x->e_dn ); x->e_bv = eh->bv; a = x->e_attrs; bptr = (BerVarray)eh->bv.bv_val; while ((i = entry_getlen(&ptr))) { struct berval bv; bv.bv_len = i; bv.bv_val = (char *) ptr; ad = NULL; rc = slap_bv2ad( &bv, &ad, &text ); if( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "<= entry_decode: str2ad(%s): %s\n", ptr, text ); rc = slap_bv2undef_ad( &bv, &ad, &text, 0 ); if( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "<= entry_decode: slap_str2undef_ad(%s): %s\n", ptr, text ); return rc; } } ptr += i + 1; a->a_desc = ad; a->a_flags = SLAP_ATTR_DONT_FREE_DATA | SLAP_ATTR_DONT_FREE_VALS; j = entry_getlen(&ptr); a->a_numvals = j; a->a_vals = bptr; while (j) { i = entry_getlen(&ptr); bptr->bv_len = i; bptr->bv_val = (char *)ptr; ptr += i+1; bptr++; j--; } bptr->bv_val = NULL; bptr->bv_len = 0; bptr++; j = entry_getlen(&ptr); if (j) { a->a_nvals = bptr; while (j) { i = entry_getlen(&ptr); bptr->bv_len = i; bptr->bv_val = (char *)ptr; ptr += i+1; bptr++; j--; } bptr->bv_val = NULL; bptr->bv_len = 0; bptr++; } else { a->a_nvals = a->a_vals; } /* FIXME: This is redundant once a sorted entry is saved into the DB */ if ( a->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) { rc = slap_sort_vals( (Modifications *)a, &text, &j, NULL ); if ( rc == LDAP_SUCCESS ) { a->a_flags |= SLAP_ATTR_SORTED_VALS; } else if ( rc == LDAP_TYPE_OR_VALUE_EXISTS ) { /* should never happen */ Debug( LDAP_DEBUG_ANY, "entry_decode: attributeType %s value #%d provided more than once\n", a->a_desc->ad_cname.bv_val, j ); return rc; } } a = a->a_next; nattrs--; if ( !nattrs ) break; } Debug(LDAP_DEBUG_TRACE, "<= entry_decode(%s)\n", x->e_dn ); *e = x; return 0; }