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