1193326Sed/*	$NetBSD: options.c,v 1.3 2021/08/14 16:14:55 christos Exp $	*/
2193326Sed
3193326Sed/* $OpenLDAP$ */
4193326Sed/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5193326Sed *
6193326Sed * Copyright 1998-2021 The OpenLDAP Foundation.
7193326Sed * All rights reserved.
8193326Sed *
9193326Sed * Redistribution and use in source and binary forms, with or without
10193326Sed * modification, are permitted only as authorized by the OpenLDAP
11193326Sed * Public License.
12193326Sed *
13226890Sdim * A copy of this license is available in the file LICENSE in the
14252723Sdim * top-level directory of the distribution or, alternatively, at
15193326Sed * <http://www.OpenLDAP.org/license.html>.
16193326Sed */
17263509Sdim
18263509Sdim#include <sys/cdefs.h>
19193326Sed__RCSID("$NetBSD: options.c,v 1.3 2021/08/14 16:14:55 christos Exp $");
20193326Sed
21252723Sdim#include "portable.h"
22193326Sed
23252723Sdim#include <ac/stdlib.h>
24252723Sdim#include <ac/string.h>
25252723Sdim#include <ac/stdarg.h>
26193326Sed#include "lber-int.h"
27226890Sdim
28193326Sedchar ber_pvt_opt_on;	/* used to get a non-NULL address for *_OPT_ON */
29193326Sed
30193326Sedstruct lber_options ber_int_options = {
31193326Sed	LBER_UNINITIALIZED, 0, 0 };
32193326Sed
33static BerMemoryFunctions	ber_int_memory_fns_datum;
34
35int
36ber_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
127int
128ber_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