X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibrewrite%2Fvar.c;h=9138b175c99be0c84b389b45bede82aaa00cf48e;hb=d34fffcaf9edc00262209fbe6e04bb15805dbd37;hp=6f8469789459bf1c01b6cce0e0db82c2c0ee016f;hpb=fbba83b20f3a645b2dc19b8ec4a0026f71f5b15c;p=openldap diff --git a/libraries/librewrite/var.c b/libraries/librewrite/var.c index 6f84697894..9138b175c9 100644 --- a/libraries/librewrite/var.c +++ b/libraries/librewrite/var.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2000-2003 The OpenLDAP Foundation. + * Copyright 2000-2005 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -65,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 */ @@ -83,51 +116,112 @@ 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; } + memset( var, 0, sizeof( struct rewrite_var ) ); - var->lv_name = strdup( name ); - if ( var->lv_name == NULL ) { - rc = -1; - goto cleanup; + + 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 ) { - rc = -1; - goto cleanup; + + 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 ) { - rc = -1; - goto cleanup; - } cleanup:; - if ( rc != 0 ) { - free( var->lv_name ); - free( var->lv_value.bv_val ); - free( var ); + if ( rc != 0 && var ) { + avl_delete( tree, ( caddr_t )var, rewrite_var_cmp ); + rewrite_var_free( var ); var = NULL; } @@ -138,11 +232,11 @@ cleanup:; * 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; @@ -153,50 +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( - void *v_var -) -{ - struct rewrite_var *var = v_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 ); - free( var ); -} - -/* - * Deletes a var tree - */ -int -rewrite_var_delete( - Avlnode *tree -) -{ - avl_free( tree, rewrite_var_free ); - return REWRITE_SUCCESS; -} -