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