var.c revision 1.1.1.1
1/* $OpenLDAP: pkg/ldap/libraries/librewrite/var.c,v 1.13.2.3 2008/02/11 23:26:43 kurt Exp $ */
2/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3 *
4 * Copyright 2000-2008 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 */
27static int
28rewrite_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 */
49static int
50rewrite_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 */
71static void
72rewrite_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 */
92int
93rewrite_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 */
104struct rewrite_var *
105rewrite_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
119int
120rewrite_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 */
162struct rewrite_var *
163rewrite_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
221cleanup:;
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 */
234struct rewrite_var *
235rewrite_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
266