+int
+attr_valadd(
+ Attribute *a,
+ BerVarray vals,
+ BerVarray nvals,
+ int nn )
+{
+ int i;
+ BerVarray v2;
+
+ v2 = (BerVarray) SLAP_REALLOC( (char *) a->a_vals,
+ (a->a_numvals + nn + 1) * sizeof(struct berval) );
+ if( v2 == NULL ) {
+ Debug(LDAP_DEBUG_TRACE,
+ "attr_valadd: SLAP_REALLOC failed.\n", 0, 0, 0 );
+ return LBER_ERROR_MEMORY;
+ }
+ a->a_vals = v2;
+ if ( nvals ) {
+ v2 = (BerVarray) SLAP_REALLOC( (char *) a->a_nvals,
+ (a->a_numvals + nn + 1) * sizeof(struct berval) );
+ if( v2 == NULL ) {
+ Debug(LDAP_DEBUG_TRACE,
+ "attr_valadd: SLAP_REALLOC failed.\n", 0, 0, 0 );
+ return LBER_ERROR_MEMORY;
+ }
+ a->a_nvals = v2;
+ } else {
+ a->a_nvals = a->a_vals;
+ }
+
+ /* If sorted and old vals exist, must insert */
+ if (( a->a_flags & SLAP_ATTR_SORTED_VALS ) && a->a_numvals ) {
+ unsigned slot;
+ int j, rc;
+ v2 = nvals ? nvals : vals;
+ for ( i = 0; i < nn; i++ ) {
+ rc = attr_valfind( a, SLAP_MR_EQUALITY | SLAP_MR_VALUE_OF_ASSERTION_SYNTAX |
+ SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH | SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH,
+ &v2[i], &slot, NULL );
+ if ( rc != LDAP_NO_SUCH_ATTRIBUTE ) {
+ /* should never happen */
+ if ( rc == LDAP_SUCCESS )
+ rc = LDAP_TYPE_OR_VALUE_EXISTS;
+ return rc;
+ }
+ for ( j = a->a_numvals; j >= (int)slot; j-- ) {
+ a->a_vals[j+1] = a->a_vals[j];
+ if ( nvals )
+ a->a_nvals[j+1] = a->a_nvals[j];
+ }
+ ber_dupbv( &a->a_nvals[slot], &v2[i] );
+ if ( nvals )
+ ber_dupbv( &a->a_vals[slot], &vals[i] );
+ a->a_numvals++;
+ }
+ BER_BVZERO( &a->a_vals[a->a_numvals] );
+ if ( a->a_vals != a->a_nvals )
+ BER_BVZERO( &a->a_nvals[a->a_numvals] );
+ } else {
+ v2 = &a->a_vals[a->a_numvals];
+ for ( i = 0 ; i < nn; i++ ) {
+ ber_dupbv( &v2[i], &vals[i] );
+ if ( BER_BVISNULL( &v2[i] ) ) break;
+ }
+ BER_BVZERO( &v2[i] );