]> git.sur5r.net Git - openldap/blob - servers/slapd/value.c
More header work toward draft-ietf-ldapext-ldap-c-api-01.
[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 #define LDAP_MIN( a, b )        ((a) < (b) ? (a) : (b) )
107
108 int
109 value_cmp(
110     struct berval       *v1,
111     struct berval       *v2,
112     int                 syntax,
113     int                 normalize       /* 1 => arg 1; 2 => arg 2; 3 => both */
114 )
115 {
116         int             rc;
117         struct stat     st1, st2;
118
119         if ( normalize & 1 ) {
120                 v1 = ber_bvdup( v1 );
121                 value_normalize( v1->bv_val, syntax );
122         }
123         if ( normalize & 2 ) {
124                 v2 = ber_bvdup( v2 );
125                 value_normalize( v2->bv_val, syntax );
126         }
127
128         switch ( syntax ) {
129         case SYNTAX_CIS:
130         case (SYNTAX_CIS | SYNTAX_TEL):
131         case (SYNTAX_CIS | SYNTAX_DN):
132                 rc = strcasecmp( v1->bv_val, v2->bv_val );
133                 break;
134
135         case SYNTAX_CES:
136                 rc = strcmp( v1->bv_val, v2->bv_val );
137                 break;
138
139         case SYNTAX_BIN:
140                 rc = memcmp( v1->bv_val, v2->bv_val, LDAP_MIN( v1->bv_len,
141                     v2->bv_len ) );
142                 break;
143         }
144
145         if ( normalize & 1 ) {
146                 ber_bvfree( v1 );
147         }
148         if ( normalize & 2 ) {
149                 ber_bvfree( v2 );
150         }
151
152         return( rc );
153 }
154
155 int
156 value_ncmp(
157     struct berval       *v1,
158     struct berval       *v2,
159     int                 syntax,
160     int                 len,
161     int                 normalize
162 )
163 {
164         int     rc;
165
166         if ( normalize & 1 ) {
167                 v1 = ber_bvdup( v1 );
168                 value_normalize( v1->bv_val, syntax );
169         }
170         if ( normalize & 2 ) {
171                 v2 = ber_bvdup( v2 );
172                 value_normalize( v2->bv_val, syntax );
173         }
174
175         switch ( syntax ) {
176         case SYNTAX_CIS:
177         case (SYNTAX_CIS | SYNTAX_TEL):
178                 rc = strncasecmp( v1->bv_val, v2->bv_val, len );
179                 break;
180
181         case SYNTAX_CES:
182                 rc = strncmp( v1->bv_val, v2->bv_val, len );
183                 break;
184
185         case SYNTAX_BIN:
186                 rc = memcmp( v1->bv_val, v2->bv_val, len );
187         }
188
189         if ( normalize & 1 ) {
190                 ber_bvfree( v1 );
191         }
192         if ( normalize & 2 ) {
193                 ber_bvfree( v2 );
194         }
195
196         return( rc );
197 }
198
199 int
200 value_find(
201     struct berval       **vals,
202     struct berval       *v,
203     int                 syntax,
204     int                 normalize
205 )
206 {
207         int     i;
208
209         for ( i = 0; vals[i] != NULL; i++ ) {
210                 if ( value_cmp( vals[i], v, syntax, normalize ) == 0 ) {
211                         return( 0 );
212                 }
213         }
214
215         return( 1 );
216 }