]> git.sur5r.net Git - openldap/blob - libraries/librewrite/var.c
From HEAD
[openldap] / libraries / librewrite / var.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 2000-2004 The OpenLDAP Foundation.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted only as authorized by the OpenLDAP
9  * Public License.
10  *
11  * A copy of this license is available in the file LICENSE in the
12  * top-level directory of the distribution or, alternatively, at
13  * <http://www.OpenLDAP.org/license.html>.
14  */
15 /* ACKNOWLEDGEMENT:
16  * This work was initially developed by Pierangelo Masarati for
17  * inclusion in OpenLDAP Software.
18  */
19
20 #include <portable.h>
21
22 #include "rewrite-int.h"
23
24 /*
25  * Compares two vars
26  */
27 static int
28 rewrite_var_cmp(
29                 const void *c1,
30                 const void *c2
31 )
32 {
33         const struct rewrite_var *v1, *v2;
34
35         v1 = ( const struct rewrite_var * )c1;
36         v2 = ( const struct rewrite_var * )c2;
37         
38         assert( v1 != NULL );
39         assert( v2 != NULL );
40         assert( v1->lv_name != NULL );
41         assert( v2->lv_name != NULL );
42
43         return strcasecmp( v1->lv_name, v2->lv_name );
44 }
45
46 /*
47  * Duplicate var ?
48  */
49 static int
50 rewrite_var_dup(
51                 void *c1,
52                 void *c2
53 )
54 {
55         struct rewrite_var *v1, *v2;
56
57         v1 = ( struct rewrite_var * )c1;
58         v2 = ( struct rewrite_var * )c2;
59
60         assert( v1 != NULL );
61         assert( v2 != NULL );
62         assert( v1->lv_name != NULL );
63         assert( v2->lv_name != NULL );
64
65         return ( strcasecmp( v1->lv_name, v2->lv_name ) == 0 ? -1 : 0 );
66 }
67
68 /*
69  * Frees a var
70  */
71 static void 
72 rewrite_var_free(
73                 void *v_var
74 )
75 {
76         struct rewrite_var *var = v_var;
77         assert( var != NULL );
78
79         assert( var->lv_name != NULL );
80         assert( var->lv_value.bv_val != NULL );
81
82         if ( var->lv_flags & REWRITE_VAR_COPY_NAME )
83                 free( var->lv_name );
84         if ( var->lv_flags & REWRITE_VAR_COPY_VALUE )
85                 free( var->lv_value.bv_val );
86         free( var );
87 }
88
89 /*
90  * Deletes a var tree
91  */
92 int
93 rewrite_var_delete(
94                 Avlnode *tree
95 )
96 {
97         avl_free( tree, rewrite_var_free );
98         return REWRITE_SUCCESS;
99 }
100
101 /*
102  * Finds a var
103  */
104 struct rewrite_var *
105 rewrite_var_find(
106                 Avlnode *tree,
107                 const char *name
108 )
109 {
110         struct rewrite_var var;
111
112         assert( name != NULL );
113
114         var.lv_name = ( char * )name;
115         return ( struct rewrite_var * )avl_find( tree, 
116                         ( caddr_t )&var, rewrite_var_cmp );
117 }
118
119 int
120 rewrite_var_replace(
121                 struct rewrite_var *var,
122                 const char *value,
123                 int flags
124 )
125 {
126         ber_len_t       len = strlen( value );
127
128         if ( var->lv_flags & REWRITE_VAR_COPY_VALUE ) {
129                 if ( flags & REWRITE_VAR_COPY_VALUE ) {
130                         if ( len <= var->lv_value.bv_len ) {
131                                 AC_MEMCPY(var->lv_value.bv_val, value, len + 1);
132
133                         } else {
134                                 free( var->lv_value.bv_val );
135                                 var->lv_value.bv_val = strdup( value );
136                         }
137
138                 } else {
139                         free( var->lv_value.bv_val );
140                         var->lv_value.bv_val = (char *)value;
141                         var->lv_flags &= ~REWRITE_VAR_COPY_VALUE;
142                 }
143
144         } else {
145                 if ( flags & REWRITE_VAR_COPY_VALUE ) {
146                         var->lv_value.bv_val = strdup( value );
147                         var->lv_flags |= REWRITE_VAR_COPY_VALUE;
148
149                 } else {
150                         var->lv_value.bv_val = (char *)value;
151                 }
152         }
153
154         var->lv_value.bv_len = len;
155
156         return 0;
157 }
158
159 /*
160  * Inserts a newly created var
161  */
162 struct rewrite_var *
163 rewrite_var_insert_f(
164                 Avlnode **tree,
165                 const char *name,
166                 const char *value,
167                 int flags
168 )
169 {
170         struct rewrite_var *var;
171         int rc = 0;
172
173         assert( tree != NULL );
174         assert( name != NULL );
175         assert( value != NULL );
176         
177         var = rewrite_var_find( *tree, name );
178         if ( var != NULL ) {
179                 if ( flags & REWRITE_VAR_UPDATE ) {
180                         (void)rewrite_var_replace( var, value, flags );
181                         goto cleanup;
182                 }
183                 rc = -1;
184                 goto cleanup;
185         }
186
187         var = calloc( sizeof( struct rewrite_var ), 1 );
188         if ( var == NULL ) {
189                 return NULL;
190         }
191
192         memset( var, 0, sizeof( struct rewrite_var ) );
193
194         if ( flags & REWRITE_VAR_COPY_NAME ) {
195                 var->lv_name = strdup( name );
196                 if ( var->lv_name == NULL ) {
197                         rc = -1;
198                         goto cleanup;
199                 }
200                 var->lv_flags |= REWRITE_VAR_COPY_NAME;
201
202         } else {
203                 var->lv_name = (char *)name;
204         }
205
206         if ( flags & REWRITE_VAR_COPY_VALUE ) {
207                 var->lv_value.bv_val = strdup( value );
208                 if ( var->lv_value.bv_val == NULL ) {
209                         rc = -1;
210                         goto cleanup;
211                 }
212                 var->lv_flags |= REWRITE_VAR_COPY_VALUE;
213                 
214         } else {
215                 var->lv_value.bv_val = (char *)value;
216         }
217         var->lv_value.bv_len = strlen( value );
218         rc = avl_insert( tree, ( caddr_t )var,
219                         rewrite_var_cmp, rewrite_var_dup );
220
221 cleanup:;
222         if ( rc != 0 && var ) {
223                 avl_delete( tree, ( caddr_t )var, rewrite_var_cmp );
224                 rewrite_var_free( var );
225                 var = NULL;
226         }
227
228         return var;
229 }
230
231 /*
232  * Sets/inserts a var
233  */
234 struct rewrite_var *
235 rewrite_var_set_f(
236                 Avlnode **tree,
237                 const char *name,
238                 const char *value,
239                 int flags
240 )
241 {
242         struct rewrite_var *var;
243
244         assert( tree != NULL );
245         assert( name != NULL );
246         assert( value != NULL );
247         
248         var = rewrite_var_find( *tree, name );
249         if ( var == NULL ) {
250                 if ( flags & REWRITE_VAR_INSERT ) {
251                         return rewrite_var_insert_f( tree, name, value, flags );
252
253                 } else {
254                         return NULL;
255                 }
256
257         } else {
258                 assert( var->lv_value.bv_val != NULL );
259
260                 (void)rewrite_var_replace( var, value, flags );
261         }
262
263         return var;
264 }
265