1 /* entry.c - routines for dealing with entries */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/entry.c,v 1.148.2.7 2008/02/11 23:43:39 quanah Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1998-2008 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
16 /* Portions Copyright (c) 1995 Regents of the University of Michigan.
17 * All rights reserved.
19 * Redistribution and use in source and binary forms are permitted
20 * provided that this notice is preserved and that due credit is given
21 * to the University of Michigan at Ann Arbor. The name of the University
22 * may not be used to endorse or promote products derived from this
23 * software without specific prior written permission. This software
24 * is provided ``as is'' without express or implied warranty.
33 #include <ac/socket.h>
34 #include <ac/string.h>
39 static char *ebuf
; /* buf returned by entry2str */
40 static char *ecur
; /* pointer to end of currently used ebuf */
41 static int emaxsize
;/* max size of ebuf */
46 const Entry slap_entry_root
= {
47 NOID
, { 0, "" }, { 0, "" }, NULL
, 0, { 0, "" }, NULL
51 * these mutexes must be used when calling the entry2str()
52 * routine since it returns a pointer to static data.
54 ldap_pvt_thread_mutex_t entry2str_mutex
;
56 static const struct berval dn_bv
= BER_BVC("dn");
61 * Allocate in chunks, minimum of 1000 at a time.
63 #define CHUNK_SIZE 1000
64 typedef struct slap_list
{
65 struct slap_list
*next
;
67 static slap_list
*entry_chunks
;
68 static Entry
*entry_list
;
69 static ldap_pvt_thread_mutex_t entry_mutex
;
71 int entry_destroy(void)
74 if ( ebuf
) free( ebuf
);
79 for ( e
=entry_chunks
; e
; e
=entry_chunks
) {
80 entry_chunks
= e
->next
;
84 ldap_pvt_thread_mutex_destroy( &entry_mutex
);
85 ldap_pvt_thread_mutex_destroy( &entry2str_mutex
);
86 return attr_destroy();
92 ldap_pvt_thread_mutex_init( &entry2str_mutex
);
93 ldap_pvt_thread_mutex_init( &entry_mutex
);
100 return str2entry2( s
, 1 );
103 #define bvcasematch(bv1, bv2) (ber_bvstrcasecmp(bv1, bv2) == 0)
106 str2entry2( char *s
, int checkvals
)
110 struct berval
*type
, *vals
, *nvals
;
112 AttributeDescription
*ad
, *ad_prev
;
117 Attribute ahead
, *atail
;
120 * LDIF is used as the string format.
121 * An entry looks like this:
124 * [<attr>:[:] <value>\n]
125 * [<tab><continuedvalue>\n]*
128 * If a double colon is used after a type, it means the
129 * following value is encoded as a base 64 string. This
130 * happens if the value contains a non-printing character
134 Debug( LDAP_DEBUG_TRACE
, "=> str2entry: \"%s\"\n",
135 s
? s
: "NULL", 0, 0 );
140 Debug( LDAP_DEBUG_ANY
,
141 "<= str2entry NULL (entry allocation failed)\n",
146 /* initialize entry */
149 /* dn + attributes */
157 lines
= ldif_countlines( s
);
158 type
= ch_calloc( 1, (lines
+1)*3*sizeof(struct berval
)+lines
);
160 nvals
= vals
+lines
+1;
161 freeval
= (char *)(nvals
+lines
+1);
164 /* parse into individual values, record DN */
165 while ( (s
= ldif_getline( &next
)) != NULL
) {
167 if ( *s
== '\n' || *s
== '\0' ) {
172 Debug( LDAP_DEBUG_TRACE
,
173 "<= str2entry ran past end of entry\n", 0, 0, 0 );
177 rc
= ldif_parse_line2( s
, type
+i
, vals
+i
, &freev
);
180 Debug( LDAP_DEBUG_TRACE
,
181 "<= str2entry NULL (parse_line)\n", 0, 0, 0 );
185 if ( bvcasematch( &type
[i
], &dn_bv
) ) {
186 if ( e
->e_dn
!= NULL
) {
187 Debug( LDAP_DEBUG_ANY
, "str2entry: "
188 "entry %ld has multiple DNs \"%s\" and \"%s\"\n",
189 (long) e
->e_id
, e
->e_dn
, vals
[i
].bv_val
);
193 rc
= dnPrettyNormal( NULL
, &vals
[i
], &e
->e_name
, &e
->e_nname
, NULL
);
194 if( rc
!= LDAP_SUCCESS
) {
195 Debug( LDAP_DEBUG_ANY
, "str2entry: "
196 "entry %ld has invalid DN \"%s\"\n",
197 (long) e
->e_id
, vals
[i
].bv_val
, 0 );
200 if ( freeval
[i
] ) free( vals
[i
].bv_val
);
201 vals
[i
].bv_val
= NULL
;
208 /* check to make sure there was a dn: line */
209 if ( BER_BVISNULL( &e
->e_name
)) {
210 Debug( LDAP_DEBUG_ANY
, "str2entry: entry %ld has no dn\n",
211 (long) e
->e_id
, 0, 0 );
215 /* Make sure all attributes with multiple values are contiguous */
221 for (i
=0; i
<lines
; i
++) {
222 for ( j
=i
+1; j
<lines
; j
++ ) {
223 if ( bvcasematch( type
+i
, type
+j
)) {
224 /* out of order, move intervening attributes down */
228 for ( k
=j
; k
>i
; k
-- ) {
231 freeval
[k
] = freeval
[k
-1];
245 for ( i
=0; i
<=lines
; i
++ ) {
247 if ( !ad
|| ( i
<lines
&& !bvcasematch( type
+i
, &ad
->ad_cname
))) {
249 rc
= slap_bv2ad( type
+i
, &ad
, &text
);
251 if( rc
!= LDAP_SUCCESS
) {
252 Debug( slapMode
& SLAP_TOOL_MODE
253 ? LDAP_DEBUG_ANY
: LDAP_DEBUG_TRACE
,
254 "<= str2entry: str2ad(%s): %s\n", type
[i
].bv_val
, text
, 0 );
255 if( slapMode
& SLAP_TOOL_MODE
) {
259 rc
= slap_bv2undef_ad( type
+i
, &ad
, &text
, 0 );
260 if( rc
!= LDAP_SUCCESS
) {
261 Debug( LDAP_DEBUG_ANY
,
262 "<= str2entry: slap_str2undef_ad(%s): %s\n",
263 type
[i
].bv_val
, text
, 0 );
268 /* require ';binary' when appropriate (ITS#5071) */
269 if ( slap_syntax_is_binary( ad
->ad_type
->sat_syntax
) && !slap_ad_is_binary( ad
) ) {
270 Debug( LDAP_DEBUG_ANY
,
271 "str2entry: attributeType %s #%d: "
272 "needs ';binary' transfer as per syntax %s\n",
273 ad
->ad_cname
.bv_val
, 0,
274 ad
->ad_type
->sat_syntax
->ssyn_oid
);
279 if (( ad_prev
&& ad
!= ad_prev
) || ( i
== lines
)) {
281 /* FIXME: we only need this when migrating from an unsorted DB */
282 if ( atail
!= &ahead
&& atail
->a_desc
->ad_type
->sat_flags
& SLAP_AT_SORTED_VAL
) {
283 rc
= slap_sort_vals( (Modifications
*)atail
, &text
, &j
, NULL
);
284 if ( rc
== LDAP_SUCCESS
) {
285 atail
->a_flags
|= SLAP_ATTR_SORTED_VALS
;
286 } else if ( rc
== LDAP_TYPE_OR_VALUE_EXISTS
) {
287 Debug( LDAP_DEBUG_ANY
,
288 "str2entry: attributeType %s value #%d provided more than once\n",
289 atail
->a_desc
->ad_cname
.bv_val
, j
, 0 );
293 atail
->a_next
= attr_alloc( NULL
);
294 atail
= atail
->a_next
;
296 atail
->a_numvals
= attr_cnt
;
297 atail
->a_desc
= ad_prev
;
298 atail
->a_vals
= ch_malloc( (attr_cnt
+ 1) * sizeof(struct berval
));
299 if( ad_prev
->ad_type
->sat_equality
&&
300 ad_prev
->ad_type
->sat_equality
->smr_normalize
)
301 atail
->a_nvals
= ch_malloc( (attr_cnt
+ 1) * sizeof(struct berval
));
303 atail
->a_nvals
= NULL
;
305 for ( j
=0; j
<attr_cnt
; j
++ ) {
307 atail
->a_vals
[j
] = vals
[k
];
309 ber_dupbv( atail
->a_vals
+j
, &vals
[k
] );
310 vals
[k
].bv_val
= NULL
;
311 if ( atail
->a_nvals
) {
312 atail
->a_nvals
[j
] = nvals
[k
];
313 nvals
[k
].bv_val
= NULL
;
317 BER_BVZERO( &atail
->a_vals
[j
] );
318 if ( atail
->a_nvals
) {
319 BER_BVZERO( &atail
->a_nvals
[j
] );
321 atail
->a_nvals
= atail
->a_vals
;
324 if ( i
== lines
) break;
327 if ( BER_BVISNULL( &vals
[i
] ) ) {
328 Debug( LDAP_DEBUG_ANY
,
329 "str2entry: attributeType %s #%d: "
331 ad
->ad_cname
.bv_val
, attr_cnt
, 0 );
335 if( slapMode
& SLAP_TOOL_MODE
) {
337 slap_syntax_validate_func
*validate
=
338 ad
->ad_type
->sat_syntax
->ssyn_validate
;
339 slap_syntax_transform_func
*pretty
=
340 ad
->ad_type
->sat_syntax
->ssyn_pretty
;
343 rc
= ordered_value_pretty( ad
,
344 &vals
[i
], &pval
, NULL
);
346 } else if ( validate
) {
348 * validate value per syntax
350 rc
= ordered_value_validate( ad
, &vals
[i
], LDAP_MOD_ADD
);
353 Debug( LDAP_DEBUG_ANY
,
354 "str2entry: attributeType %s #%d: "
355 "no validator for syntax %s\n",
356 ad
->ad_cname
.bv_val
, attr_cnt
,
357 ad
->ad_type
->sat_syntax
->ssyn_oid
);
362 Debug( LDAP_DEBUG_ANY
,
363 "str2entry: invalid value "
364 "for attributeType %s #%d (syntax %s)\n",
365 ad
->ad_cname
.bv_val
, attr_cnt
,
366 ad
->ad_type
->sat_syntax
->ssyn_oid
);
371 if ( freeval
[i
] ) free( vals
[i
].bv_val
);
377 if ( ad
->ad_type
->sat_equality
&&
378 ad
->ad_type
->sat_equality
->smr_normalize
)
380 rc
= ordered_value_normalize(
381 SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX
,
383 ad
->ad_type
->sat_equality
,
384 &vals
[i
], &nvals
[i
], NULL
);
387 Debug( LDAP_DEBUG_ANY
,
388 "<= str2entry NULL (smr_normalize %s %d)\n", ad
->ad_cname
.bv_val
, rc
, 0 );
398 atail
->a_next
= NULL
;
399 e
->e_attrs
= ahead
.a_next
;
401 Debug(LDAP_DEBUG_TRACE
, "<= str2entry(%s) -> 0x%lx\n",
402 e
->e_dn
, (unsigned long) e
, 0 );
406 for ( i
=0; i
<lines
; i
++ ) {
407 if ( freeval
[i
] ) free( vals
[i
].bv_val
);
408 free( nvals
[i
].bv_val
);
416 #define GRABSIZE BUFSIZ
418 #define MAKE_SPACE( n ) { \
419 while ( ecur + (n) > ebuf + emaxsize ) { \
421 offset = (int) (ecur - ebuf); \
422 ebuf = ch_realloc( ebuf, \
423 emaxsize + GRABSIZE ); \
424 emaxsize += GRABSIZE; \
425 ecur = ebuf + offset; \
442 * In string format, an entry looks like this:
444 * [<attr>: <value>\n]*
450 if ( e
->e_dn
!= NULL
) {
452 tmplen
= e
->e_name
.bv_len
;
453 MAKE_SPACE( LDIF_SIZE_NEEDED( 2, tmplen
));
454 ldif_sput( &ecur
, LDIF_PUT_VALUE
, "dn", e
->e_dn
, tmplen
);
457 /* put the attributes */
458 for ( a
= e
->e_attrs
; a
!= NULL
; a
= a
->a_next
) {
459 /* put "<type>:[:] <value>" line for each value */
460 for ( i
= 0; a
->a_vals
[i
].bv_val
!= NULL
; i
++ ) {
462 tmplen
= a
->a_desc
->ad_cname
.bv_len
;
463 MAKE_SPACE( LDIF_SIZE_NEEDED( tmplen
, bv
->bv_len
));
464 ldif_sput( &ecur
, LDIF_PUT_VALUE
,
465 a
->a_desc
->ad_cname
.bv_val
,
466 bv
->bv_val
, bv
->bv_len
);
477 entry_clean( Entry
*e
)
479 /* free an entry structure */
482 /* e_private must be freed by the caller */
483 assert( e
->e_private
== NULL
);
488 if ( !BER_BVISNULL( &e
->e_name
) ) {
489 free( e
->e_name
.bv_val
);
490 BER_BVZERO( &e
->e_name
);
492 if ( !BER_BVISNULL( &e
->e_nname
) ) {
493 free( e
->e_nname
.bv_val
);
494 BER_BVZERO( &e
->e_nname
);
497 if ( !BER_BVISNULL( &e
->e_bv
) ) {
498 free( e
->e_bv
.bv_val
);
499 BER_BVZERO( &e
->e_bv
);
502 /* free attributes */
504 attrs_free( e
->e_attrs
);
512 entry_free( Entry
*e
)
516 ldap_pvt_thread_mutex_lock( &entry_mutex
);
517 e
->e_private
= entry_list
;
519 ldap_pvt_thread_mutex_unlock( &entry_mutex
);
522 /* These parameters work well on AMD64 */
530 #define STRIDE_FACTOR (STRIDE*STRIPE)
533 entry_prealloc( int num
)
535 Entry
*e
, **prev
, *tmp
;
541 #if STRIDE_FACTOR > 1
542 /* Round up to our stride factor */
543 num
+= STRIDE_FACTOR
-1;
544 num
/= STRIDE_FACTOR
;
545 num
*= STRIDE_FACTOR
;
548 s
= ch_calloc( 1, sizeof(slap_list
) + num
* sizeof(Entry
));
549 s
->next
= entry_chunks
;
553 for (i
=0; i
<STRIPE
; i
++) {
556 for (j
=i
; j
<num
; j
+= STRIDE
) {
558 prev
= (Entry
**)&e
->e_private
;
563 entry_list
= (Entry
*)(s
+1);
573 ldap_pvt_thread_mutex_lock( &entry_mutex
);
575 entry_prealloc( CHUNK_SIZE
);
577 entry_list
= e
->e_private
;
579 ldap_pvt_thread_mutex_unlock( &entry_mutex
);
586 * These routines are used only by Backend.
588 * the Entry has three entry points (ways to find things):
590 * by entry e.g., if you already have an entry from the cache
591 * and want to delete it. (really by entry ptr)
592 * by dn e.g., when looking for the base object of a search
593 * by id e.g., for search candidates
595 * these correspond to three different avl trees that are maintained.
599 entry_cmp( Entry
*e1
, Entry
*e2
)
601 return SLAP_PTRCMP( e1
, e2
);
605 entry_dn_cmp( const void *v_e1
, const void *v_e2
)
607 /* compare their normalized UPPERCASED dn's */
608 const Entry
*e1
= v_e1
, *e2
= v_e2
;
610 return ber_bvcmp( &e1
->e_nname
, &e2
->e_nname
);
614 entry_id_cmp( const void *v_e1
, const void *v_e2
)
616 const Entry
*e1
= v_e1
, *e2
= v_e2
;
617 return( e1
->e_id
< e2
->e_id
? -1 : (e1
->e_id
> e2
->e_id
? 1 : 0) );
620 /* This is like a ber_len */
621 #define entry_lenlen(l) (((l) < 0x80) ? 1 : ((l) < 0x100) ? 2 : \
622 ((l) < 0x10000) ? 3 : ((l) < 0x1000000) ? 4 : 5)
625 entry_putlen(unsigned char **buf
, ber_len_t len
)
627 ber_len_t lenlen
= entry_lenlen(len
);
630 **buf
= (unsigned char) len
;
633 **buf
= 0x80 | ((unsigned char) lenlen
- 1);
634 for (i
=lenlen
-1; i
>0; i
--) {
635 (*buf
)[i
] = (unsigned char) len
;
643 entry_getlen(unsigned char **buf
)
660 /* Count up the sizes of the components of an entry */
661 void entry_partsize(Entry
*e
, ber_len_t
*plen
,
662 int *pnattrs
, int *pnvals
, int norm
)
664 ber_len_t len
, dnlen
, ndnlen
;
665 int i
, nat
= 0, nval
= 0;
668 dnlen
= e
->e_name
.bv_len
;
669 len
= dnlen
+ 1; /* trailing NUL byte */
670 len
+= entry_lenlen(dnlen
);
672 ndnlen
= e
->e_nname
.bv_len
;
674 len
+= entry_lenlen(ndnlen
);
676 for (a
=e
->e_attrs
; a
; a
=a
->a_next
) {
677 /* For AttributeDesc, we only store the attr name */
679 len
+= a
->a_desc
->ad_cname
.bv_len
+1;
680 len
+= entry_lenlen(a
->a_desc
->ad_cname
.bv_len
);
681 for (i
=0; a
->a_vals
[i
].bv_val
; i
++) {
683 len
+= a
->a_vals
[i
].bv_len
+ 1;
684 len
+= entry_lenlen(a
->a_vals
[i
].bv_len
);
686 len
+= entry_lenlen(i
);
687 nval
++; /* empty berval at end */
688 if (norm
&& a
->a_nvals
!= a
->a_vals
) {
689 for (i
=0; a
->a_nvals
[i
].bv_val
; i
++) {
691 len
+= a
->a_nvals
[i
].bv_len
+ 1;
692 len
+= entry_lenlen(a
->a_nvals
[i
].bv_len
);
694 len
+= entry_lenlen(i
); /* i nvals */
697 len
+= entry_lenlen(0); /* 0 nvals */
700 len
+= entry_lenlen(nat
);
701 len
+= entry_lenlen(nval
);
707 /* Add up the size of the entry for a flattened buffer */
708 ber_len_t
entry_flatsize(Entry
*e
, int norm
)
713 entry_partsize(e
, &len
, &nattrs
, &nvals
, norm
);
714 len
+= sizeof(Entry
) + (nattrs
* sizeof(Attribute
)) +
715 (nvals
* sizeof(struct berval
));
719 /* Flatten an Entry into a buffer. The buffer is filled with just the
720 * strings/bervals of all the entry components. Each field is preceded
721 * by its length, encoded the way ber_put_len works. Every field is NUL
722 * terminated. The entire buffer size is precomputed so that a single
723 * malloc can be performed. The entry size is also recorded,
724 * to aid in entry_decode.
726 int entry_encode(Entry
*e
, struct berval
*bv
)
728 ber_len_t len
, dnlen
, ndnlen
;
729 int i
, nattrs
, nvals
;
733 Debug( LDAP_DEBUG_TRACE
, "=> entry_encode(0x%08lx): %s\n",
734 (long) e
->e_id
, e
->e_dn
, 0 );
735 dnlen
= e
->e_name
.bv_len
;
736 ndnlen
= e
->e_nname
.bv_len
;
738 entry_partsize( e
, &len
, &nattrs
, &nvals
, 1 );
741 bv
->bv_val
= ch_malloc(len
);
742 ptr
= (unsigned char *)bv
->bv_val
;
743 entry_putlen(&ptr
, nattrs
);
744 entry_putlen(&ptr
, nvals
);
745 entry_putlen(&ptr
, dnlen
);
746 AC_MEMCPY(ptr
, e
->e_dn
, dnlen
);
749 entry_putlen(&ptr
, ndnlen
);
750 AC_MEMCPY(ptr
, e
->e_ndn
, ndnlen
);
754 for (a
=e
->e_attrs
; a
; a
=a
->a_next
) {
755 entry_putlen(&ptr
, a
->a_desc
->ad_cname
.bv_len
);
756 AC_MEMCPY(ptr
, a
->a_desc
->ad_cname
.bv_val
,
757 a
->a_desc
->ad_cname
.bv_len
);
758 ptr
+= a
->a_desc
->ad_cname
.bv_len
;
761 for (i
=0; a
->a_vals
[i
].bv_val
; i
++);
762 assert( i
== a
->a_numvals
);
763 entry_putlen(&ptr
, i
);
764 for (i
=0; a
->a_vals
[i
].bv_val
; i
++) {
765 entry_putlen(&ptr
, a
->a_vals
[i
].bv_len
);
766 AC_MEMCPY(ptr
, a
->a_vals
[i
].bv_val
,
767 a
->a_vals
[i
].bv_len
);
768 ptr
+= a
->a_vals
[i
].bv_len
;
771 if (a
->a_nvals
!= a
->a_vals
) {
772 entry_putlen(&ptr
, i
);
773 for (i
=0; a
->a_nvals
[i
].bv_val
; i
++) {
774 entry_putlen(&ptr
, a
->a_nvals
[i
].bv_len
);
775 AC_MEMCPY(ptr
, a
->a_nvals
[i
].bv_val
,
776 a
->a_nvals
[i
].bv_len
);
777 ptr
+= a
->a_nvals
[i
].bv_len
;
781 entry_putlen(&ptr
, 0);
788 /* Retrieve an Entry that was stored using entry_encode above.
789 * First entry_header must be called to decode the size of the entry.
790 * Then a single block of memory must be malloc'd to accomodate the
791 * bervals and the bulk data. Next the bulk data is retrieved from
792 * the DB and parsed by entry_decode.
794 * Note: everything is stored in a single contiguous block, so
795 * you can not free individual attributes or names from this
796 * structure. Attempting to do so will likely corrupt memory.
798 int entry_header(EntryHeader
*eh
)
800 unsigned char *ptr
= (unsigned char *)eh
->bv
.bv_val
;
802 eh
->nattrs
= entry_getlen(&ptr
);
804 Debug( LDAP_DEBUG_ANY
,
805 "entry_header: attribute count was zero\n", 0, 0, 0);
808 eh
->nvals
= entry_getlen(&ptr
);
810 Debug( LDAP_DEBUG_ANY
,
811 "entry_header: value count was zero\n", 0, 0, 0);
814 eh
->data
= (char *)ptr
;
818 #ifdef SLAP_ZONE_ALLOC
819 int entry_decode(EntryHeader
*eh
, Entry
**e
, void *ctx
)
821 int entry_decode(EntryHeader
*eh
, Entry
**e
)
824 int i
, j
, nattrs
, nvals
;
829 AttributeDescription
*ad
;
830 unsigned char *ptr
= (unsigned char *)eh
->bv
.bv_val
;
836 x
->e_attrs
= attrs_alloc( nattrs
);
837 ptr
= (unsigned char *)eh
->data
;
838 i
= entry_getlen(&ptr
);
839 x
->e_name
.bv_val
= (char *) ptr
;
840 x
->e_name
.bv_len
= i
;
842 i
= entry_getlen(&ptr
);
843 x
->e_nname
.bv_val
= (char *) ptr
;
844 x
->e_nname
.bv_len
= i
;
846 Debug( LDAP_DEBUG_TRACE
,
847 "entry_decode: \"%s\"\n",
852 bptr
= (BerVarray
)eh
->bv
.bv_val
;
854 while ((i
= entry_getlen(&ptr
))) {
857 bv
.bv_val
= (char *) ptr
;
859 rc
= slap_bv2ad( &bv
, &ad
, &text
);
861 if( rc
!= LDAP_SUCCESS
) {
862 Debug( LDAP_DEBUG_TRACE
,
863 "<= entry_decode: str2ad(%s): %s\n", ptr
, text
, 0 );
864 rc
= slap_bv2undef_ad( &bv
, &ad
, &text
, 0 );
866 if( rc
!= LDAP_SUCCESS
) {
867 Debug( LDAP_DEBUG_ANY
,
868 "<= entry_decode: slap_str2undef_ad(%s): %s\n",
875 a
->a_flags
= SLAP_ATTR_DONT_FREE_DATA
| SLAP_ATTR_DONT_FREE_VALS
;
876 j
= entry_getlen(&ptr
);
881 i
= entry_getlen(&ptr
);
883 bptr
->bv_val
= (char *)ptr
;
892 j
= entry_getlen(&ptr
);
896 i
= entry_getlen(&ptr
);
898 bptr
->bv_val
= (char *)ptr
;
907 a
->a_nvals
= a
->a_vals
;
909 /* FIXME: This is redundant once a sorted entry is saved into the DB */
910 if ( a
->a_desc
->ad_type
->sat_flags
& SLAP_AT_SORTED_VAL
) {
911 rc
= slap_sort_vals( (Modifications
*)a
, &text
, &j
, NULL
);
912 if ( rc
== LDAP_SUCCESS
) {
913 a
->a_flags
|= SLAP_ATTR_SORTED_VALS
;
914 } else if ( rc
== LDAP_TYPE_OR_VALUE_EXISTS
) {
915 /* should never happen */
916 Debug( LDAP_DEBUG_ANY
,
917 "entry_decode: attributeType %s value #%d provided more than once\n",
918 a
->a_desc
->ad_cname
.bv_val
, j
, 0 );
928 Debug(LDAP_DEBUG_TRACE
, "<= entry_decode(%s)\n",
934 Entry
*entry_dup( Entry
*e
)
941 ber_dupbv( &ret
->e_name
, &e
->e_name
);
942 ber_dupbv( &ret
->e_nname
, &e
->e_nname
);
943 ret
->e_attrs
= attrs_dup( e
->e_attrs
);
944 ret
->e_ocflags
= e
->e_ocflags
;
950 /* Duplicates an entry using a single malloc. Saves CPU time, increases
951 * heap usage because a single large malloc is harder to satisfy than
952 * lots of small ones, and the freed space isn't as easily reusable.
954 * Probably not worth using this function.
956 Entry
*entry_dup_bv( Entry
*e
)
963 Attribute
*src
, *dst
;
967 entry_partsize(e
, &len
, &nattrs
, &nvals
, 1);
969 ret
->e_attrs
= attrs_alloc( nattrs
);
970 ret
->e_ocflags
= e
->e_ocflags
;
971 ret
->e_bv
.bv_len
= len
+ nvals
* sizeof(struct berval
);
972 ret
->e_bv
.bv_val
= ch_malloc( ret
->e_bv
.bv_len
);
974 bvl
= (struct berval
*)ret
->e_bv
.bv_val
;
975 ptr
= (char *)(bvl
+ nvals
);
977 ret
->e_name
.bv_len
= e
->e_name
.bv_len
;
978 ret
->e_name
.bv_val
= ptr
;
979 AC_MEMCPY( ptr
, e
->e_name
.bv_val
, e
->e_name
.bv_len
);
980 ptr
+= e
->e_name
.bv_len
;
983 ret
->e_nname
.bv_len
= e
->e_nname
.bv_len
;
984 ret
->e_nname
.bv_val
= ptr
;
985 AC_MEMCPY( ptr
, e
->e_nname
.bv_val
, e
->e_nname
.bv_len
);
986 ptr
+= e
->e_name
.bv_len
;
990 for (src
= e
->e_attrs
; src
; src
=src
->a_next
,dst
=dst
->a_next
) {
992 dst
->a_desc
= src
->a_desc
;
993 dst
->a_flags
= SLAP_ATTR_DONT_FREE_DATA
| SLAP_ATTR_DONT_FREE_VALS
;
995 dst
->a_numvals
= src
->a_numvals
;
996 for ( i
=0; src
->a_vals
[i
].bv_val
; i
++ ) {
997 bvl
->bv_len
= src
->a_vals
[i
].bv_len
;
999 AC_MEMCPY( ptr
, src
->a_vals
[i
].bv_val
, bvl
->bv_len
);
1006 if ( src
->a_vals
!= src
->a_nvals
) {
1008 for ( i
=0; src
->a_nvals
[i
].bv_val
; i
++ ) {
1009 bvl
->bv_len
= src
->a_nvals
[i
].bv_len
;
1011 AC_MEMCPY( ptr
, src
->a_nvals
[i
].bv_val
, bvl
->bv_len
);