Back to index

openldap  2.4.31
var.c
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 2000-2012 The OpenLDAP Foundation.
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted only as authorized by the OpenLDAP
00009  * Public License.
00010  *
00011  * A copy of this license is available in the file LICENSE in the
00012  * top-level directory of the distribution or, alternatively, at
00013  * <http://www.OpenLDAP.org/license.html>.
00014  */
00015 /* ACKNOWLEDGEMENT:
00016  * This work was initially developed by Pierangelo Masarati for
00017  * inclusion in OpenLDAP Software.
00018  */
00019 
00020 #include <portable.h>
00021 
00022 #include "rewrite-int.h"
00023 
00024 /*
00025  * Compares two vars
00026  */
00027 static int
00028 rewrite_var_cmp(
00029               const void *c1,
00030               const void *c2
00031 )
00032 {
00033        const struct rewrite_var *v1, *v2;
00034 
00035        v1 = ( const struct rewrite_var * )c1;
00036        v2 = ( const struct rewrite_var * )c2;
00037        
00038        assert( v1 != NULL );
00039        assert( v2 != NULL );
00040        assert( v1->lv_name != NULL );
00041        assert( v2->lv_name != NULL );
00042 
00043        return strcasecmp( v1->lv_name, v2->lv_name );
00044 }
00045 
00046 /*
00047  * Duplicate var ?
00048  */
00049 static int
00050 rewrite_var_dup(
00051               void *c1,
00052               void *c2
00053 )
00054 {
00055        struct rewrite_var *v1, *v2;
00056 
00057        v1 = ( struct rewrite_var * )c1;
00058        v2 = ( struct rewrite_var * )c2;
00059 
00060        assert( v1 != NULL );
00061        assert( v2 != NULL );
00062        assert( v1->lv_name != NULL );
00063        assert( v2->lv_name != NULL );
00064 
00065        return ( strcasecmp( v1->lv_name, v2->lv_name ) == 0 ? -1 : 0 );
00066 }
00067 
00068 /*
00069  * Frees a var
00070  */
00071 static void 
00072 rewrite_var_free(
00073               void *v_var
00074 )
00075 {
00076        struct rewrite_var *var = v_var;
00077        assert( var != NULL );
00078 
00079        assert( var->lv_name != NULL );
00080        assert( var->lv_value.bv_val != NULL );
00081 
00082        if ( var->lv_flags & REWRITE_VAR_COPY_NAME )
00083               free( var->lv_name );
00084        if ( var->lv_flags & REWRITE_VAR_COPY_VALUE )
00085               free( var->lv_value.bv_val );
00086        free( var );
00087 }
00088 
00089 /*
00090  * Deletes a var tree
00091  */
00092 int
00093 rewrite_var_delete(
00094               Avlnode *tree
00095 )
00096 {
00097        avl_free( tree, rewrite_var_free );
00098        return REWRITE_SUCCESS;
00099 }
00100 
00101 /*
00102  * Finds a var
00103  */
00104 struct rewrite_var *
00105 rewrite_var_find(
00106               Avlnode *tree,
00107               const char *name
00108 )
00109 {
00110        struct rewrite_var var;
00111 
00112        assert( name != NULL );
00113 
00114        var.lv_name = ( char * )name;
00115        return ( struct rewrite_var * )avl_find( tree, 
00116                      ( caddr_t )&var, rewrite_var_cmp );
00117 }
00118 
00119 int
00120 rewrite_var_replace(
00121               struct rewrite_var *var,
00122               const char *value,
00123               int flags
00124 )
00125 {
00126        ber_len_t     len;
00127 
00128        assert( value != NULL );
00129 
00130        len = strlen( value );
00131 
00132        if ( var->lv_flags & REWRITE_VAR_COPY_VALUE ) {
00133               if ( flags & REWRITE_VAR_COPY_VALUE ) {
00134                      if ( len <= var->lv_value.bv_len ) {
00135                             AC_MEMCPY(var->lv_value.bv_val, value, len + 1);
00136 
00137                      } else {
00138                             free( var->lv_value.bv_val );
00139                             var->lv_value.bv_val = strdup( value );
00140                      }
00141 
00142               } else {
00143                      free( var->lv_value.bv_val );
00144                      var->lv_value.bv_val = (char *)value;
00145                      var->lv_flags &= ~REWRITE_VAR_COPY_VALUE;
00146               }
00147 
00148        } else {
00149               if ( flags & REWRITE_VAR_COPY_VALUE ) {
00150                      var->lv_value.bv_val = strdup( value );
00151                      var->lv_flags |= REWRITE_VAR_COPY_VALUE;
00152 
00153               } else {
00154                      var->lv_value.bv_val = (char *)value;
00155               }
00156        }
00157 
00158        if ( var->lv_value.bv_val == NULL ) {
00159               return -1;
00160        }
00161 
00162        var->lv_value.bv_len = len;
00163 
00164        return 0;
00165 }
00166 
00167 /*
00168  * Inserts a newly created var
00169  */
00170 struct rewrite_var *
00171 rewrite_var_insert_f(
00172               Avlnode **tree,
00173               const char *name,
00174               const char *value,
00175               int flags
00176 )
00177 {
00178        struct rewrite_var *var;
00179        int rc = 0;
00180 
00181        assert( tree != NULL );
00182        assert( name != NULL );
00183        assert( value != NULL );
00184        
00185        var = rewrite_var_find( *tree, name );
00186        if ( var != NULL ) {
00187               if ( flags & REWRITE_VAR_UPDATE ) {
00188                      (void)rewrite_var_replace( var, value, flags );
00189                      goto cleanup;
00190               }
00191               rc = -1;
00192               goto cleanup;
00193        }
00194 
00195        var = calloc( sizeof( struct rewrite_var ), 1 );
00196        if ( var == NULL ) {
00197               return NULL;
00198        }
00199 
00200        memset( var, 0, sizeof( struct rewrite_var ) );
00201 
00202        if ( flags & REWRITE_VAR_COPY_NAME ) {
00203               var->lv_name = strdup( name );
00204               if ( var->lv_name == NULL ) {
00205                      rc = -1;
00206                      goto cleanup;
00207               }
00208               var->lv_flags |= REWRITE_VAR_COPY_NAME;
00209 
00210        } else {
00211               var->lv_name = (char *)name;
00212        }
00213 
00214        if ( flags & REWRITE_VAR_COPY_VALUE ) {
00215               var->lv_value.bv_val = strdup( value );
00216               if ( var->lv_value.bv_val == NULL ) {
00217                      rc = -1;
00218                      goto cleanup;
00219               }
00220               var->lv_flags |= REWRITE_VAR_COPY_VALUE;
00221               
00222        } else {
00223               var->lv_value.bv_val = (char *)value;
00224        }
00225        var->lv_value.bv_len = strlen( value );
00226        rc = avl_insert( tree, ( caddr_t )var,
00227                      rewrite_var_cmp, rewrite_var_dup );
00228 
00229 cleanup:;
00230        if ( rc != 0 && var ) {
00231               avl_delete( tree, ( caddr_t )var, rewrite_var_cmp );
00232               rewrite_var_free( var );
00233               var = NULL;
00234        }
00235 
00236        return var;
00237 }
00238 
00239 /*
00240  * Sets/inserts a var
00241  */
00242 struct rewrite_var *
00243 rewrite_var_set_f(
00244               Avlnode **tree,
00245               const char *name,
00246               const char *value,
00247               int flags
00248 )
00249 {
00250        struct rewrite_var *var;
00251 
00252        assert( tree != NULL );
00253        assert( name != NULL );
00254        assert( value != NULL );
00255        
00256        var = rewrite_var_find( *tree, name );
00257        if ( var == NULL ) {
00258               if ( flags & REWRITE_VAR_INSERT ) {
00259                      return rewrite_var_insert_f( tree, name, value, flags );
00260 
00261               } else {
00262                      return NULL;
00263               }
00264 
00265        } else {
00266               assert( var->lv_value.bv_val != NULL );
00267 
00268               (void)rewrite_var_replace( var, value, flags );
00269        }
00270 
00271        return var;
00272 }
00273