var.c revision 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