]> git.sur5r.net Git - openldap/blob - servers/slapd/value.c
Fix dbcache/entry lock deadlock. If dbcache lock is held, it's
[openldap] / servers / slapd / value.c
1 /* value.c - routines for dealing with values */
2
3 #include "portable.h"
4
5 #include <stdio.h>
6
7 #include <ac/ctype.h>
8 #include <ac/socket.h>
9 #include <ac/string.h>
10 #include <ac/time.h>
11
12 #include <sys/stat.h>
13
14 #include "slap.h"
15
16 int
17 value_add_fast( 
18     struct berval       ***vals,
19     struct berval       **addvals,
20     int                 nvals,
21     int                 naddvals,
22     int                 *maxvals
23 )
24 {
25         int     need, i, j;
26
27         if ( *maxvals == 0 ) {
28                 *maxvals = 1;
29         }
30         need = nvals + naddvals + 1;
31         while ( *maxvals < need ) {
32                 *maxvals *= 2;
33                 *vals = (struct berval **) ch_realloc( (char *) *vals,
34                     *maxvals * sizeof(struct berval *) );
35         }
36
37         for ( i = 0, j = 0; i < naddvals; i++, j++ ) {
38                 if ( addvals[i]->bv_len > 0 ) {
39                         (*vals)[nvals + j] = ber_bvdup( addvals[i] );
40                 }
41         }
42         (*vals)[nvals + j] = NULL;
43
44         return( 0 );
45 }
46
47 int
48 value_add( 
49     struct berval       ***vals,
50     struct berval       **addvals
51 )
52 {
53         int     n, nn, i, j;
54
55         for ( nn = 0; addvals != NULL && addvals[nn] != NULL; nn++ )
56                 ;       /* NULL */
57
58         if ( *vals == NULL ) {
59                 *vals = (struct berval **) ch_malloc( (nn + 1)
60                     * sizeof(struct berval *) );
61                 n = 0;
62         } else {
63                 for ( n = 0; (*vals)[n] != NULL; n++ )
64                         ;       /* NULL */
65                 *vals = (struct berval **) ch_realloc( (char *) *vals,
66                     (n + nn + 1) * sizeof(struct berval *) );
67         }
68
69         for ( i = 0, j = 0; i < nn; i++ ) {
70                 if ( addvals[i]->bv_len > 0 ) {
71                         (*vals)[n + j++] = ber_bvdup( addvals[i] );
72                 }
73         }
74         (*vals)[n + j] = NULL;
75
76         return( 0 );
77 }
78
79 void
80 value_normalize(
81     char        *s,
82     int         syntax
83 )
84 {
85         char    *d, *save;
86
87         if ( ! (syntax & SYNTAX_CIS) ) {
88                 return;
89         }
90
91         if ( syntax & SYNTAX_DN ) {
92                 (void) dn_normalize_case( s );
93                 return;
94         }
95
96         save = s;
97         for ( d = s; *s; s++ ) {
98                 if ( (syntax & SYNTAX_TEL) && (*s == ' ' || *s == '-') ) {
99                         continue;
100                 }
101                 *d++ = TOUPPER( *s );
102         }
103         *d = '\0';
104 }
105
106 int
107 value_cmp(
108     struct berval       *v1,
109     struct berval       *v2,
110     int                 syntax,
111     int                 normalize       /* 1 => arg 1; 2 => arg 2; 3 => both */
112 )
113 {
114         int             rc;
115         struct stat     st1, st2;
116
117         if ( normalize & 1 ) {
118                 v1 = ber_bvdup( v1 );
119                 value_normalize( v1->bv_val, syntax );
120         }
121         if ( normalize & 2 ) {
122                 v2 = ber_bvdup( v2 );
123                 value_normalize( v2->bv_val, syntax );
124         }
125
126         switch ( syntax ) {
127         case SYNTAX_CIS:
128         case (SYNTAX_CIS | SYNTAX_TEL):
129         case (SYNTAX_CIS | SYNTAX_DN):
130                 rc = strcasecmp( v1->bv_val, v2->bv_val );
131                 break;
132
133         case SYNTAX_CES:
134                 rc = strcmp( v1->bv_val, v2->bv_val );
135                 break;
136
137         case SYNTAX_BIN:
138                 rc = ( v1->bv_len == v2->bv_len ) ? memcmp( v1->bv_val, 
139                     v2->bv_val, v1->bv_len ) : v1->bv_len - v2->bv_len ;
140                 break;
141         }
142
143         if ( normalize & 1 ) {
144                 ber_bvfree( v1 );
145         }
146         if ( normalize & 2 ) {
147                 ber_bvfree( v2 );
148         }
149
150         return( rc );
151 }
152
153 int
154 value_find(
155     struct berval       **vals,
156     struct berval       *v,
157     int                 syntax,
158     int                 normalize
159 )
160 {
161         int     i;
162
163         for ( i = 0; vals[i] != NULL; i++ ) {
164                 if ( value_cmp( vals[i], v, syntax, normalize ) == 0 ) {
165                         return( 0 );
166                 }
167         }
168
169         return( 1 );
170 }