]> git.sur5r.net Git - openldap/blob - libraries/librewrite/var.c
47ac3a1a6cb873c1760155aa6250fd0f98d8e718
[openldap] / libraries / librewrite / var.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 2000-2017 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;
127
128         assert( value != NULL );
129
130         len = strlen( value );
131
132         if ( var->lv_flags & REWRITE_VAR_COPY_VALUE ) {
133                 if ( flags & REWRITE_VAR_COPY_VALUE ) {
134                         if ( len <= var->lv_value.bv_len ) {
135                                 AC_MEMCPY(var->lv_value.bv_val, value, len + 1);
136
137                         } else {
138                                 free( var->lv_value.bv_val );
139                                 var->lv_value.bv_val = strdup( value );
140                         }
141
142                 } else {
143                         free( var->lv_value.bv_val );
144                         var->lv_value.bv_val = (char *)value;
145                         var->lv_flags &= ~REWRITE_VAR_COPY_VALUE;
146                 }
147
148         } else {
149                 if ( flags & REWRITE_VAR_COPY_VALUE ) {
150                         var->lv_value.bv_val = strdup( value );
151                         var->lv_flags |= REWRITE_VAR_COPY_VALUE;
152
153                 } else {
154                         var->lv_value.bv_val = (char *)value;
155                 }
156         }
157
158         if ( var->lv_value.bv_val == NULL ) {
159                 return -1;
160         }
161
162         var->lv_value.bv_len = len;
163
164         return 0;
165 }
166
167 /*
168  * Inserts a newly created var
169  */
170 struct rewrite_var *
171 rewrite_var_insert_f(
172                 Avlnode **tree,
173                 const char *name,
174                 const char *value,
175                 int flags
176 )
177 {
178         struct rewrite_var *var;
179         int rc = 0;
180
181         assert( tree != NULL );
182         assert( name != NULL );
183         assert( value != NULL );
184         
185         var = rewrite_var_find( *tree, name );
186         if ( var != NULL ) {
187                 if ( flags & REWRITE_VAR_UPDATE ) {
188                         (void)rewrite_var_replace( var, value, flags );
189                         goto cleanup;
190                 }
191                 rc = -1;
192                 goto cleanup;
193         }
194
195         var = calloc( sizeof( struct rewrite_var ), 1 );
196         if ( var == NULL ) {
197                 return NULL;
198         }
199
200         memset( var, 0, sizeof( struct rewrite_var ) );
201
202         if ( flags & REWRITE_VAR_COPY_NAME ) {
203                 var->lv_name = strdup( name );
204                 if ( var->lv_name == NULL ) {
205                         rc = -1;
206                         goto cleanup;
207                 }
208                 var->lv_flags |= REWRITE_VAR_COPY_NAME;
209
210         } else {
211                 var->lv_name = (char *)name;
212         }
213
214         if ( flags & REWRITE_VAR_COPY_VALUE ) {
215                 var->lv_value.bv_val = strdup( value );
216                 if ( var->lv_value.bv_val == NULL ) {
217                         rc = -1;
218                         goto cleanup;
219                 }
220                 var->lv_flags |= REWRITE_VAR_COPY_VALUE;
221                 
222         } else {
223                 var->lv_value.bv_val = (char *)value;
224         }
225         var->lv_value.bv_len = strlen( value );
226         rc = avl_insert( tree, ( caddr_t )var,
227                         rewrite_var_cmp, rewrite_var_dup );
228
229 cleanup:;
230         if ( rc != 0 && var ) {
231                 avl_delete( tree, ( caddr_t )var, rewrite_var_cmp );
232                 rewrite_var_free( var );
233                 var = NULL;
234         }
235
236         return var;
237 }
238
239 /*
240  * Sets/inserts a var
241  */
242 struct rewrite_var *
243 rewrite_var_set_f(
244                 Avlnode **tree,
245                 const char *name,
246                 const char *value,
247                 int flags
248 )
249 {
250         struct rewrite_var *var;
251
252         assert( tree != NULL );
253         assert( name != NULL );
254         assert( value != NULL );
255         
256         var = rewrite_var_find( *tree, name );
257         if ( var == NULL ) {
258                 if ( flags & REWRITE_VAR_INSERT ) {
259                         return rewrite_var_insert_f( tree, name, value, flags );
260
261                 } else {
262                         return NULL;
263                 }
264
265         } else {
266                 assert( var->lv_value.bv_val != NULL );
267
268                 (void)rewrite_var_replace( var, value, flags );
269         }
270
271         return var;
272 }
273