X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibrewrite%2Fvar.c;h=5e13b4d242f25a7265c55385b1cd53ecd35955cf;hb=fe8e3b7efa1a3abd22f3c9ebf4b82ae28f270d74;hp=ca39ed13db2556205b8ec2bcda9810bb0ef71cff;hpb=74fa239a201cd2d785fe34bdbaf6804161bdb231;p=openldap diff --git a/libraries/librewrite/var.c b/libraries/librewrite/var.c index ca39ed13db..5e13b4d242 100644 --- a/libraries/librewrite/var.c +++ b/libraries/librewrite/var.c @@ -1,26 +1,21 @@ -/****************************************************************************** +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . * - * Copyright (C) 2000 Pierangelo Masarati, + * Copyright 2000-2006 The OpenLDAP Foundation. * All rights reserved. * - * Permission is granted to anyone to use this software for any purpose - * on any computer system, and to alter it and redistribute it, subject - * to the following restrictions: + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. * - * 1. The author is not responsible for the consequences of use of this - * software, no matter how awful, even if they arise from flaws in it. - * - * 2. The origin of this software must not be misrepresented, either by - * explicit claim or by omission. Since few users ever read sources, - * credits should appear in the documentation. - * - * 3. Altered versions must be plainly marked as such, and must not be - * misrepresented as being the original software. Since few users - * ever read sources, credits should appear in the documentation. - * - * 4. This notice may not be removed or altered. - * - ******************************************************************************/ + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ +/* ACKNOWLEDGEMENT: + * This work was initially developed by Pierangelo Masarati for + * inclusion in OpenLDAP Software. + */ #include @@ -37,8 +32,8 @@ rewrite_var_cmp( { const struct rewrite_var *v1, *v2; - v1 = ( struct rewrite_var * )c1; - v2 = ( struct rewrite_var * )c2; + v1 = ( const struct rewrite_var * )c1; + v2 = ( const struct rewrite_var * )c2; assert( v1 != NULL ); assert( v2 != NULL ); @@ -70,6 +65,39 @@ rewrite_var_dup( return ( strcasecmp( v1->lv_name, v2->lv_name ) == 0 ? -1 : 0 ); } +/* + * Frees a var + */ +static void +rewrite_var_free( + void *v_var +) +{ + struct rewrite_var *var = v_var; + assert( var != NULL ); + + assert( var->lv_name != NULL ); + assert( var->lv_value.bv_val != NULL ); + + if ( var->lv_flags & REWRITE_VAR_COPY_NAME ) + free( var->lv_name ); + if ( var->lv_flags & REWRITE_VAR_COPY_VALUE ) + free( var->lv_value.bv_val ); + free( var ); +} + +/* + * Deletes a var tree + */ +int +rewrite_var_delete( + Avlnode *tree +) +{ + avl_free( tree, rewrite_var_free ); + return REWRITE_SUCCESS; +} + /* * Finds a var */ @@ -88,46 +116,113 @@ rewrite_var_find( ( caddr_t )&var, rewrite_var_cmp ); } +int +rewrite_var_replace( + struct rewrite_var *var, + const char *value, + int flags +) +{ + ber_len_t len = strlen( value ); + + if ( var->lv_flags & REWRITE_VAR_COPY_VALUE ) { + if ( flags & REWRITE_VAR_COPY_VALUE ) { + if ( len <= var->lv_value.bv_len ) { + AC_MEMCPY(var->lv_value.bv_val, value, len + 1); + + } else { + free( var->lv_value.bv_val ); + var->lv_value.bv_val = strdup( value ); + } + + } else { + free( var->lv_value.bv_val ); + var->lv_value.bv_val = (char *)value; + var->lv_flags &= ~REWRITE_VAR_COPY_VALUE; + } + + } else { + if ( flags & REWRITE_VAR_COPY_VALUE ) { + var->lv_value.bv_val = strdup( value ); + var->lv_flags |= REWRITE_VAR_COPY_VALUE; + + } else { + var->lv_value.bv_val = (char *)value; + } + } + + var->lv_value.bv_len = len; + + return 0; +} + /* * Inserts a newly created var */ struct rewrite_var * -rewrite_var_insert( +rewrite_var_insert_f( Avlnode **tree, const char *name, - const char *value + const char *value, + int flags ) { struct rewrite_var *var; - int rc; + int rc = 0; assert( tree != NULL ); assert( name != NULL ); assert( value != NULL ); + var = rewrite_var_find( *tree, name ); + if ( var != NULL ) { + if ( flags & REWRITE_VAR_UPDATE ) { + (void)rewrite_var_replace( var, value, flags ); + goto cleanup; + } + rc = -1; + goto cleanup; + } + var = calloc( sizeof( struct rewrite_var ), 1 ); if ( var == NULL ) { return NULL; } - var->lv_name = ( char * )strdup( name ); - if ( var->lv_name == NULL ) { - free( var ); - return NULL; + + memset( var, 0, sizeof( struct rewrite_var ) ); + + if ( flags & REWRITE_VAR_COPY_NAME ) { + var->lv_name = strdup( name ); + if ( var->lv_name == NULL ) { + rc = -1; + goto cleanup; + } + var->lv_flags |= REWRITE_VAR_COPY_NAME; + + } else { + var->lv_name = (char *)name; } - var->lv_value.bv_val = strdup( value ); - if ( var->lv_value.bv_val == NULL ) { - free( var ); - free( var->lv_name ); - return NULL; + + if ( flags & REWRITE_VAR_COPY_VALUE ) { + var->lv_value.bv_val = strdup( value ); + if ( var->lv_value.bv_val == NULL ) { + rc = -1; + goto cleanup; + } + var->lv_flags |= REWRITE_VAR_COPY_VALUE; + + } else { + var->lv_value.bv_val = (char *)value; } var->lv_value.bv_len = strlen( value ); rc = avl_insert( tree, ( caddr_t )var, rewrite_var_cmp, rewrite_var_dup ); - if ( rc != 0 ) { - free( var ); - free( var->lv_name ); - free( var->lv_value.bv_val ); - return NULL; + +cleanup:; + if ( rc != 0 && var ) { + avl_delete( tree, ( caddr_t )var, rewrite_var_cmp ); + rewrite_var_free( var ); + var = NULL; } return var; @@ -137,11 +232,11 @@ rewrite_var_insert( * Sets/inserts a var */ struct rewrite_var * -rewrite_var_set( +rewrite_var_set_f( Avlnode **tree, const char *name, const char *value, - int insert + int flags ) { struct rewrite_var *var; @@ -152,48 +247,19 @@ rewrite_var_set( var = rewrite_var_find( *tree, name ); if ( var == NULL ) { - if ( insert ) { - return rewrite_var_insert( tree, name, value ); + if ( flags & REWRITE_VAR_INSERT ) { + return rewrite_var_insert_f( tree, name, value, flags ); + } else { return NULL; } + } else { assert( var->lv_value.bv_val != NULL ); - free( var->lv_value.bv_val ); - var->lv_value.bv_val = ( char * )value; - var->lv_value.bv_len = strlen( value ); + (void)rewrite_var_replace( var, value, flags ); } return var; } -/* - * Frees a var - */ -static void -rewrite_var_free( - struct rewrite_var *var -) -{ - assert( var != NULL ); - - assert( var->lv_name != NULL ); - assert( var->lv_value.bv_val != NULL ); - - free( var->lv_name ); - free( var->lv_value.bv_val ); -} - -/* - * Deletes a var tree - */ -int -rewrite_var_delete( - Avlnode *tree -) -{ - avl_free( tree, ( AVL_FREE )rewrite_var_free ); - return REWRITE_SUCCESS; -} -