1 1.3 christos /* $NetBSD: var.c,v 1.4 2025/09/05 21:16:23 christos Exp $ */ 2 1.2 christos 3 1.2 christos /* $OpenLDAP$ */ 4 1.1 lukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 5 1.1 lukem * 6 1.4 christos * Copyright 2000-2024 The OpenLDAP Foundation. 7 1.1 lukem * All rights reserved. 8 1.1 lukem * 9 1.1 lukem * Redistribution and use in source and binary forms, with or without 10 1.1 lukem * modification, are permitted only as authorized by the OpenLDAP 11 1.1 lukem * Public License. 12 1.1 lukem * 13 1.1 lukem * A copy of this license is available in the file LICENSE in the 14 1.1 lukem * top-level directory of the distribution or, alternatively, at 15 1.1 lukem * <http://www.OpenLDAP.org/license.html>. 16 1.1 lukem */ 17 1.1 lukem /* ACKNOWLEDGEMENT: 18 1.1 lukem * This work was initially developed by Pierangelo Masarati for 19 1.1 lukem * inclusion in OpenLDAP Software. 20 1.1 lukem */ 21 1.1 lukem 22 1.1 lukem #include <portable.h> 23 1.1 lukem 24 1.1 lukem #include "rewrite-int.h" 25 1.1 lukem 26 1.1 lukem /* 27 1.1 lukem * Compares two vars 28 1.1 lukem */ 29 1.1 lukem static int 30 1.1 lukem rewrite_var_cmp( 31 1.1 lukem const void *c1, 32 1.1 lukem const void *c2 33 1.1 lukem ) 34 1.1 lukem { 35 1.1 lukem const struct rewrite_var *v1, *v2; 36 1.1 lukem 37 1.1 lukem v1 = ( const struct rewrite_var * )c1; 38 1.1 lukem v2 = ( const struct rewrite_var * )c2; 39 1.1 lukem 40 1.1 lukem assert( v1 != NULL ); 41 1.1 lukem assert( v2 != NULL ); 42 1.1 lukem assert( v1->lv_name != NULL ); 43 1.1 lukem assert( v2->lv_name != NULL ); 44 1.1 lukem 45 1.1 lukem return strcasecmp( v1->lv_name, v2->lv_name ); 46 1.1 lukem } 47 1.1 lukem 48 1.1 lukem /* 49 1.1 lukem * Duplicate var ? 50 1.1 lukem */ 51 1.1 lukem static int 52 1.1 lukem rewrite_var_dup( 53 1.1 lukem void *c1, 54 1.1 lukem void *c2 55 1.1 lukem ) 56 1.1 lukem { 57 1.1 lukem struct rewrite_var *v1, *v2; 58 1.1 lukem 59 1.1 lukem v1 = ( struct rewrite_var * )c1; 60 1.1 lukem v2 = ( struct rewrite_var * )c2; 61 1.1 lukem 62 1.1 lukem assert( v1 != NULL ); 63 1.1 lukem assert( v2 != NULL ); 64 1.1 lukem assert( v1->lv_name != NULL ); 65 1.1 lukem assert( v2->lv_name != NULL ); 66 1.1 lukem 67 1.1 lukem return ( strcasecmp( v1->lv_name, v2->lv_name ) == 0 ? -1 : 0 ); 68 1.1 lukem } 69 1.1 lukem 70 1.1 lukem /* 71 1.1 lukem * Frees a var 72 1.1 lukem */ 73 1.1 lukem static void 74 1.1 lukem rewrite_var_free( 75 1.1 lukem void *v_var 76 1.1 lukem ) 77 1.1 lukem { 78 1.1 lukem struct rewrite_var *var = v_var; 79 1.1 lukem assert( var != NULL ); 80 1.1 lukem 81 1.1 lukem assert( var->lv_name != NULL ); 82 1.1 lukem assert( var->lv_value.bv_val != NULL ); 83 1.1 lukem 84 1.1 lukem if ( var->lv_flags & REWRITE_VAR_COPY_NAME ) 85 1.1 lukem free( var->lv_name ); 86 1.1 lukem if ( var->lv_flags & REWRITE_VAR_COPY_VALUE ) 87 1.1 lukem free( var->lv_value.bv_val ); 88 1.1 lukem free( var ); 89 1.1 lukem } 90 1.1 lukem 91 1.1 lukem /* 92 1.1 lukem * Deletes a var tree 93 1.1 lukem */ 94 1.1 lukem int 95 1.1 lukem rewrite_var_delete( 96 1.1 lukem Avlnode *tree 97 1.1 lukem ) 98 1.1 lukem { 99 1.3 christos ldap_avl_free( tree, rewrite_var_free ); 100 1.1 lukem return REWRITE_SUCCESS; 101 1.1 lukem } 102 1.1 lukem 103 1.1 lukem /* 104 1.1 lukem * Finds a var 105 1.1 lukem */ 106 1.1 lukem struct rewrite_var * 107 1.1 lukem rewrite_var_find( 108 1.1 lukem Avlnode *tree, 109 1.1 lukem const char *name 110 1.1 lukem ) 111 1.1 lukem { 112 1.1 lukem struct rewrite_var var; 113 1.1 lukem 114 1.1 lukem assert( name != NULL ); 115 1.1 lukem 116 1.1 lukem var.lv_name = ( char * )name; 117 1.3 christos return ( struct rewrite_var * )ldap_avl_find( tree, 118 1.1 lukem ( caddr_t )&var, rewrite_var_cmp ); 119 1.1 lukem } 120 1.1 lukem 121 1.1 lukem int 122 1.1 lukem rewrite_var_replace( 123 1.1 lukem struct rewrite_var *var, 124 1.1 lukem const char *value, 125 1.1 lukem int flags 126 1.1 lukem ) 127 1.1 lukem { 128 1.2 christos ber_len_t len; 129 1.2 christos 130 1.2 christos assert( value != NULL ); 131 1.2 christos 132 1.2 christos len = strlen( value ); 133 1.1 lukem 134 1.1 lukem if ( var->lv_flags & REWRITE_VAR_COPY_VALUE ) { 135 1.1 lukem if ( flags & REWRITE_VAR_COPY_VALUE ) { 136 1.1 lukem if ( len <= var->lv_value.bv_len ) { 137 1.1 lukem AC_MEMCPY(var->lv_value.bv_val, value, len + 1); 138 1.1 lukem 139 1.1 lukem } else { 140 1.1 lukem free( var->lv_value.bv_val ); 141 1.1 lukem var->lv_value.bv_val = strdup( value ); 142 1.1 lukem } 143 1.1 lukem 144 1.1 lukem } else { 145 1.1 lukem free( var->lv_value.bv_val ); 146 1.1 lukem var->lv_value.bv_val = (char *)value; 147 1.1 lukem var->lv_flags &= ~REWRITE_VAR_COPY_VALUE; 148 1.1 lukem } 149 1.1 lukem 150 1.1 lukem } else { 151 1.1 lukem if ( flags & REWRITE_VAR_COPY_VALUE ) { 152 1.1 lukem var->lv_value.bv_val = strdup( value ); 153 1.1 lukem var->lv_flags |= REWRITE_VAR_COPY_VALUE; 154 1.1 lukem 155 1.1 lukem } else { 156 1.1 lukem var->lv_value.bv_val = (char *)value; 157 1.1 lukem } 158 1.1 lukem } 159 1.1 lukem 160 1.2 christos if ( var->lv_value.bv_val == NULL ) { 161 1.2 christos return -1; 162 1.2 christos } 163 1.2 christos 164 1.1 lukem var->lv_value.bv_len = len; 165 1.1 lukem 166 1.1 lukem return 0; 167 1.1 lukem } 168 1.1 lukem 169 1.1 lukem /* 170 1.1 lukem * Inserts a newly created var 171 1.1 lukem */ 172 1.1 lukem struct rewrite_var * 173 1.1 lukem rewrite_var_insert_f( 174 1.1 lukem Avlnode **tree, 175 1.1 lukem const char *name, 176 1.1 lukem const char *value, 177 1.1 lukem int flags 178 1.1 lukem ) 179 1.1 lukem { 180 1.1 lukem struct rewrite_var *var; 181 1.1 lukem int rc = 0; 182 1.1 lukem 183 1.1 lukem assert( tree != NULL ); 184 1.1 lukem assert( name != NULL ); 185 1.1 lukem assert( value != NULL ); 186 1.1 lukem 187 1.1 lukem var = rewrite_var_find( *tree, name ); 188 1.1 lukem if ( var != NULL ) { 189 1.1 lukem if ( flags & REWRITE_VAR_UPDATE ) { 190 1.1 lukem (void)rewrite_var_replace( var, value, flags ); 191 1.1 lukem goto cleanup; 192 1.1 lukem } 193 1.1 lukem rc = -1; 194 1.1 lukem goto cleanup; 195 1.1 lukem } 196 1.1 lukem 197 1.1 lukem var = calloc( sizeof( struct rewrite_var ), 1 ); 198 1.1 lukem if ( var == NULL ) { 199 1.1 lukem return NULL; 200 1.1 lukem } 201 1.1 lukem 202 1.1 lukem memset( var, 0, sizeof( struct rewrite_var ) ); 203 1.1 lukem 204 1.1 lukem if ( flags & REWRITE_VAR_COPY_NAME ) { 205 1.1 lukem var->lv_name = strdup( name ); 206 1.1 lukem if ( var->lv_name == NULL ) { 207 1.1 lukem rc = -1; 208 1.1 lukem goto cleanup; 209 1.1 lukem } 210 1.1 lukem var->lv_flags |= REWRITE_VAR_COPY_NAME; 211 1.1 lukem 212 1.1 lukem } else { 213 1.1 lukem var->lv_name = (char *)name; 214 1.1 lukem } 215 1.1 lukem 216 1.1 lukem if ( flags & REWRITE_VAR_COPY_VALUE ) { 217 1.1 lukem var->lv_value.bv_val = strdup( value ); 218 1.1 lukem if ( var->lv_value.bv_val == NULL ) { 219 1.1 lukem rc = -1; 220 1.1 lukem goto cleanup; 221 1.1 lukem } 222 1.1 lukem var->lv_flags |= REWRITE_VAR_COPY_VALUE; 223 1.1 lukem 224 1.1 lukem } else { 225 1.1 lukem var->lv_value.bv_val = (char *)value; 226 1.1 lukem } 227 1.1 lukem var->lv_value.bv_len = strlen( value ); 228 1.3 christos rc = ldap_avl_insert( tree, ( caddr_t )var, 229 1.1 lukem rewrite_var_cmp, rewrite_var_dup ); 230 1.1 lukem 231 1.1 lukem cleanup:; 232 1.1 lukem if ( rc != 0 && var ) { 233 1.3 christos ldap_avl_delete( tree, ( caddr_t )var, rewrite_var_cmp ); 234 1.1 lukem rewrite_var_free( var ); 235 1.1 lukem var = NULL; 236 1.1 lukem } 237 1.1 lukem 238 1.1 lukem return var; 239 1.1 lukem } 240 1.1 lukem 241 1.1 lukem /* 242 1.1 lukem * Sets/inserts a var 243 1.1 lukem */ 244 1.1 lukem struct rewrite_var * 245 1.1 lukem rewrite_var_set_f( 246 1.1 lukem Avlnode **tree, 247 1.1 lukem const char *name, 248 1.1 lukem const char *value, 249 1.1 lukem int flags 250 1.1 lukem ) 251 1.1 lukem { 252 1.1 lukem struct rewrite_var *var; 253 1.1 lukem 254 1.1 lukem assert( tree != NULL ); 255 1.1 lukem assert( name != NULL ); 256 1.1 lukem assert( value != NULL ); 257 1.1 lukem 258 1.1 lukem var = rewrite_var_find( *tree, name ); 259 1.1 lukem if ( var == NULL ) { 260 1.1 lukem if ( flags & REWRITE_VAR_INSERT ) { 261 1.1 lukem return rewrite_var_insert_f( tree, name, value, flags ); 262 1.1 lukem 263 1.1 lukem } else { 264 1.1 lukem return NULL; 265 1.1 lukem } 266 1.1 lukem 267 1.1 lukem } else { 268 1.1 lukem assert( var->lv_value.bv_val != NULL ); 269 1.1 lukem 270 1.1 lukem (void)rewrite_var_replace( var, value, flags ); 271 1.1 lukem } 272 1.1 lukem 273 1.1 lukem return var; 274 1.1 lukem } 275 1.1 lukem 276