]> git.sur5r.net Git - openldap/blob - libraries/liblber/options.c
mostly revert previous commit
[openldap] / libraries / liblber / options.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1998-2005 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
23 char ber_pvt_opt_on;    /* used to get a non-NULL address for *_OPT_ON */
24
25 struct lber_options ber_int_options = {
26         LBER_UNINITIALIZED, 0, 0, 0 };
27
28 int
29 ber_get_option(
30         void    *item,
31         int             option,
32         void    *outvalue)
33 {
34         const BerElement *ber;
35         const Sockbuf *sb;
36
37         ber_int_options.lbo_valid = LBER_INITIALIZED;
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_options.lbo_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
118 int
119 ber_set_option(
120         void    *item,
121         int             option,
122         LDAP_CONST void *invalue)
123 {
124         BerElement *ber;
125         Sockbuf *sb;
126
127         if( (ber_int_options.lbo_valid == LBER_UNINITIALIZED)
128                 && ( ber_int_memory_fns == NULL )
129                 && ( option == LBER_OPT_MEMORY_FNS )
130                 && ( invalue != NULL ) )
131         {
132                 const BerMemoryFunctions *f =
133                         (const BerMemoryFunctions *) invalue;
134                 /* make sure all functions are provided */
135                 if(!( f->bmf_malloc && f->bmf_calloc
136                         && f->bmf_realloc && f->bmf_free ))
137                 {
138                         ber_errno = LBER_ERROR_PARAM;
139                         return LBER_OPT_ERROR;
140                 }
141
142                 ber_int_memory_fns = (BerMemoryFunctions *)
143                         (*(f->bmf_malloc))(sizeof(BerMemoryFunctions), NULL);
144
145                 if ( ber_int_memory_fns == NULL ) {
146                         ber_errno = LBER_ERROR_MEMORY;
147                         return LBER_OPT_ERROR;
148                 }
149
150                 AC_MEMCPY(ber_int_memory_fns, f, sizeof(BerMemoryFunctions));
151
152                 ber_int_options.lbo_valid = LBER_INITIALIZED;
153                 return LBER_OPT_SUCCESS;
154         }
155
156         if ( option == LBER_OPT_MEMORY_FNS ) {
157                 if ( ber_int_options.lbo_valid != LBER_INITIALIZED ) {
158                         return LBER_OPT_ERROR;
159                 }
160
161                 if ( invalue != NULL ) {
162                         return LBER_OPT_ERROR;
163                 }
164
165                 if ( ber_int_memory_fns == NULL ) {     
166                         return LBER_OPT_ERROR;
167                 }
168                         
169                 ber_int_memory_fns->bmf_free( ber_int_memory_fns, NULL );
170                 ber_int_memory_fns = NULL;
171                 return LBER_OPT_SUCCESS;
172         }
173
174         ber_int_options.lbo_valid = LBER_INITIALIZED;
175
176         if(invalue == NULL) {
177                 /* no place to set from */
178                 ber_errno = LBER_ERROR_PARAM;
179                 return LBER_OPT_ERROR;
180         }
181
182         if(item == NULL) {
183                 switch ( option ) {
184                 case LBER_OPT_BER_DEBUG:
185                         ber_int_debug = * (const int *) invalue;
186                         return LBER_OPT_SUCCESS;
187
188                 case LBER_OPT_LOG_PRINT_FN:
189                         ber_pvt_log_print = (BER_LOG_PRINT_FN) invalue;
190                         return LBER_OPT_SUCCESS;
191
192                 case LBER_OPT_LOG_PRINT_FILE:
193                         ber_pvt_err_file = (void *) invalue;
194                         return LBER_OPT_SUCCESS;
195
196                 case LBER_OPT_MEMORY_INUSE:
197                         /* The memory inuse is a global variable on kernal implementations.
198                          * This means that memory debug is shared by all LDAP processes
199                          * so for this variable to have much meaning, only one LDAP process
200                          * should be running and memory inuse should be initialized to zero
201                          * using the lber_set_option() function during startup.
202                          * The counter is not accurate for multithreaded applications.
203                          */
204 #ifdef LDAP_MEMORY_DEBUG
205                         ber_int_options.lbo_meminuse = * (int *) invalue;
206                         return LBER_OPT_SUCCESS;
207 #else
208                         return LBER_OPT_ERROR;
209 #endif
210                 case LBER_OPT_LOG_PROC:
211                         ber_int_log_proc = (BER_LOG_FN)invalue;
212                         return LBER_OPT_SUCCESS;
213                 }
214
215                 ber_errno = LBER_ERROR_PARAM;
216                 return LBER_OPT_ERROR;
217         }
218
219         ber = item;
220         sb = item;
221
222         switch(option) {
223         case LBER_OPT_BER_OPTIONS:
224                 assert( LBER_VALID( ber ) );
225                 ber->ber_options = * (const int *) invalue;
226                 return LBER_OPT_SUCCESS;
227
228         case LBER_OPT_BER_DEBUG:
229                 assert( LBER_VALID( ber ) );
230                 ber->ber_debug = * (const int *) invalue;
231                 return LBER_OPT_SUCCESS;
232
233         case LBER_OPT_BER_REMAINING_BYTES:
234                 assert( LBER_VALID( ber ) );
235                 ber->ber_end = &ber->ber_ptr[* (const ber_len_t *) invalue];
236                 return LBER_OPT_SUCCESS;
237
238         case LBER_OPT_BER_TOTAL_BYTES:
239                 assert( LBER_VALID( ber ) );
240                 ber->ber_end = &ber->ber_buf[* (const ber_len_t *) invalue];
241                 return LBER_OPT_SUCCESS;
242
243         case LBER_OPT_BER_BYTES_TO_WRITE:
244                 assert( LBER_VALID( ber ) );
245                 ber->ber_ptr = &ber->ber_buf[* (const ber_len_t *) invalue];
246                 return LBER_OPT_SUCCESS;
247
248         case LBER_OPT_BER_MEMCTX:
249                 assert( LBER_VALID( ber ) );
250                 ber->ber_memctx = *(void **)invalue;
251                 return LBER_OPT_SUCCESS;
252
253         default:
254                 /* bad param */
255                 ber_errno = LBER_ERROR_PARAM;
256                 break;
257         }
258
259         return LBER_OPT_ERROR;
260 }