1/* $OpenLDAP$ */ 2/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 3 * 4 * Copyright 1998-2011 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 16#include "portable.h" 17 18#include <ac/stdlib.h> 19#include <ac/string.h> 20#include <ac/stdarg.h> 21#include "lber-int.h" 22 23char ber_pvt_opt_on; /* used to get a non-NULL address for *_OPT_ON */ 24 25struct lber_options ber_int_options = { 26 LBER_UNINITIALIZED, 0, 0 }; 27 28static BerMemoryFunctions ber_int_memory_fns_datum; 29 30int 31ber_get_option( 32 void *item, 33 int option, 34 void *outvalue) 35{ 36 const BerElement *ber; 37 const Sockbuf *sb; 38 39 if(outvalue == NULL) { 40 /* no place to get to */ 41 ber_errno = LBER_ERROR_PARAM; 42 return LBER_OPT_ERROR; 43 } 44 45 if(item == NULL) { 46 switch ( option ) { 47 case LBER_OPT_BER_DEBUG: 48 * (int *) outvalue = ber_int_debug; 49 return LBER_OPT_SUCCESS; 50 51 case LBER_OPT_MEMORY_INUSE: 52 /* The memory inuse is a global variable on kernal implementations. 53 * This means that memory debug is shared by all LDAP processes 54 * so for this variable to have much meaning, only one LDAP process 55 * should be running and memory inuse should be initialized to zero 56 * using the lber_set_option() function during startup. 57 * The counter is not accurate for multithreaded ldap applications. 58 */ 59#ifdef LDAP_MEMORY_DEBUG 60 * (int *) outvalue = ber_int_meminuse; 61 return LBER_OPT_SUCCESS; 62#else 63 return LBER_OPT_ERROR; 64#endif 65 66 case LBER_OPT_LOG_PRINT_FILE: 67 *((FILE**)outvalue) = (FILE*)ber_pvt_err_file; 68 return LBER_OPT_SUCCESS; 69 } 70 71 ber_errno = LBER_ERROR_PARAM; 72 return LBER_OPT_ERROR; 73 } 74 75 ber = item; 76 sb = item; 77 78 switch(option) { 79 case LBER_OPT_BER_OPTIONS: 80 assert( LBER_VALID( ber ) ); 81 * (int *) outvalue = ber->ber_options; 82 return LBER_OPT_SUCCESS; 83 84 case LBER_OPT_BER_DEBUG: 85 assert( LBER_VALID( ber ) ); 86 * (int *) outvalue = ber->ber_debug; 87 return LBER_OPT_SUCCESS; 88 89 case LBER_OPT_BER_REMAINING_BYTES: 90 assert( LBER_VALID( ber ) ); 91 *((ber_len_t *) outvalue) = ber_pvt_ber_remaining(ber); 92 return LBER_OPT_SUCCESS; 93 94 case LBER_OPT_BER_TOTAL_BYTES: 95 assert( LBER_VALID( ber ) ); 96 *((ber_len_t *) outvalue) = ber_pvt_ber_total(ber); 97 return LBER_OPT_SUCCESS; 98 99 case LBER_OPT_BER_BYTES_TO_WRITE: 100 assert( LBER_VALID( ber ) ); 101 *((ber_len_t *) outvalue) = ber_pvt_ber_write(ber); 102 return LBER_OPT_SUCCESS; 103 104 case LBER_OPT_BER_MEMCTX: 105 assert( LBER_VALID( ber ) ); 106 *((void **) outvalue) = ber->ber_memctx; 107 return LBER_OPT_SUCCESS; 108 109 default: 110 /* bad param */ 111 ber_errno = LBER_ERROR_PARAM; 112 break; 113 } 114 115 return LBER_OPT_ERROR; 116} 117 118int 119ber_set_option( 120 void *item, 121 int option, 122 LDAP_CONST void *invalue) 123{ 124 BerElement *ber; 125 Sockbuf *sb; 126 127 if(invalue == NULL) { 128 /* no place to set from */ 129 ber_errno = LBER_ERROR_PARAM; 130 return LBER_OPT_ERROR; 131 } 132 133 if(item == NULL) { 134 switch ( option ) { 135 case LBER_OPT_BER_DEBUG: 136 ber_int_debug = * (const int *) invalue; 137 return LBER_OPT_SUCCESS; 138 139 case LBER_OPT_LOG_PRINT_FN: 140 ber_pvt_log_print = (BER_LOG_PRINT_FN) invalue; 141 return LBER_OPT_SUCCESS; 142 143 case LBER_OPT_LOG_PRINT_FILE: 144 ber_pvt_err_file = (void *) invalue; 145 return LBER_OPT_SUCCESS; 146 147 case LBER_OPT_MEMORY_INUSE: 148 /* The memory inuse is a global variable on kernal implementations. 149 * This means that memory debug is shared by all LDAP processes 150 * so for this variable to have much meaning, only one LDAP process 151 * should be running and memory inuse should be initialized to zero 152 * using the lber_set_option() function during startup. 153 * The counter is not accurate for multithreaded applications. 154 */ 155#ifdef LDAP_MEMORY_DEBUG 156 ber_int_meminuse = * (int *) invalue; 157 return LBER_OPT_SUCCESS; 158#else 159 return LBER_OPT_ERROR; 160#endif 161 case LBER_OPT_MEMORY_FNS: 162 if ( ber_int_memory_fns == NULL ) 163 { 164 const BerMemoryFunctions *f = 165 (const BerMemoryFunctions *) invalue; 166 /* make sure all functions are provided */ 167 if(!( f->bmf_malloc && f->bmf_calloc 168 && f->bmf_realloc && f->bmf_free )) 169 { 170 ber_errno = LBER_ERROR_PARAM; 171 return LBER_OPT_ERROR; 172 } 173 174 ber_int_memory_fns = &ber_int_memory_fns_datum; 175 176 AC_MEMCPY(ber_int_memory_fns, f, 177 sizeof(BerMemoryFunctions)); 178 179 return LBER_OPT_SUCCESS; 180 } 181 break; 182 183 case LBER_OPT_LOG_PROC: 184 ber_int_log_proc = (BER_LOG_FN)invalue; 185 return LBER_OPT_SUCCESS; 186 } 187 188 ber_errno = LBER_ERROR_PARAM; 189 return LBER_OPT_ERROR; 190 } 191 192 ber = item; 193 sb = item; 194 195 switch(option) { 196 case LBER_OPT_BER_OPTIONS: 197 assert( LBER_VALID( ber ) ); 198 ber->ber_options = * (const int *) invalue; 199 return LBER_OPT_SUCCESS; 200 201 case LBER_OPT_BER_DEBUG: 202 assert( LBER_VALID( ber ) ); 203 ber->ber_debug = * (const int *) invalue; 204 return LBER_OPT_SUCCESS; 205 206 case LBER_OPT_BER_REMAINING_BYTES: 207 assert( LBER_VALID( ber ) ); 208 ber->ber_end = &ber->ber_ptr[* (const ber_len_t *) invalue]; 209 return LBER_OPT_SUCCESS; 210 211 case LBER_OPT_BER_TOTAL_BYTES: 212 assert( LBER_VALID( ber ) ); 213 ber->ber_end = &ber->ber_buf[* (const ber_len_t *) invalue]; 214 return LBER_OPT_SUCCESS; 215 216 case LBER_OPT_BER_BYTES_TO_WRITE: 217 assert( LBER_VALID( ber ) ); 218 ber->ber_ptr = &ber->ber_buf[* (const ber_len_t *) invalue]; 219 return LBER_OPT_SUCCESS; 220 221 case LBER_OPT_BER_MEMCTX: 222 assert( LBER_VALID( ber ) ); 223 ber->ber_memctx = *(void **)invalue; 224 return LBER_OPT_SUCCESS; 225 226 default: 227 /* bad param */ 228 ber_errno = LBER_ERROR_PARAM; 229 break; 230 } 231 232 return LBER_OPT_ERROR; 233} 234