Back to index

lightning-sunbird  0.9+nobinonly
setoption.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Mozilla Communicator client code, released
00015  * March 31, 1998.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 /*
00038  * setoption.c - ldap_set_option implementation 
00039  */
00040 
00041 #include "ldap-int.h"
00042 
00043 #define LDAP_SETCLR_BITOPT( ld, bit, optdata ) \
00044        if ( optdata != NULL ) {           \
00045               (ld)->ld_options |= bit;    \
00046        } else {                           \
00047               (ld)->ld_options &= ~bit;   \
00048        }
00049 
00050 
00051 int
00052 LDAP_CALL
00053 ldap_set_option( LDAP *ld, int option, const void *optdata )
00054 {
00055        int           rc, i;
00056        char          *matched, *errstr;
00057 
00058        if ( !nsldapi_initialized ) {
00059               nsldapi_initialize_defaults();
00060        }
00061 
00062        /*
00063         * process global options (not associated with an LDAP session handle)
00064         */
00065        if ( option == LDAP_OPT_MEMALLOC_FN_PTRS ) {
00066               struct lber_memalloc_fns    memalloc_fns;
00067 
00068               /* set libldap ones via a struct copy */
00069               nsldapi_memalloc_fns = *((struct ldap_memalloc_fns *)optdata);
00070 
00071               /* also set liblber memory allocation callbacks */
00072               memalloc_fns.lbermem_malloc =
00073                   nsldapi_memalloc_fns.ldapmem_malloc;
00074               memalloc_fns.lbermem_calloc =
00075                   nsldapi_memalloc_fns.ldapmem_calloc;
00076               memalloc_fns.lbermem_realloc =
00077                   nsldapi_memalloc_fns.ldapmem_realloc;
00078               memalloc_fns.lbermem_free =
00079                   nsldapi_memalloc_fns.ldapmem_free;
00080               if ( ber_set_option( NULL, LBER_OPT_MEMALLOC_FN_PTRS,
00081                   &memalloc_fns ) != 0 ) {
00082                      return( -1 );
00083               }
00084 
00085               return( 0 );
00086        }
00087        /* 
00088      * LDAP_OPT_DEBUG_LEVEL is global 
00089      */
00090     if (LDAP_OPT_DEBUG_LEVEL == option) 
00091     {
00092 #ifdef LDAP_DEBUG      
00093         ldap_debug = *((int *) optdata);
00094 #endif
00095         return 0;
00096     }
00097 
00098        /*
00099         * if ld is NULL, arrange to modify our default settings
00100         */
00101        if ( ld == NULL ) {
00102               ld = &nsldapi_ld_defaults;
00103 #ifdef LDAP_DEBUG
00104               ldap_debug = 0;
00105 #endif
00106 
00107        }
00108 
00109        /*
00110         * process options that are associated with an LDAP session handle
00111         */
00112        if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
00113               return( -1 ); /* punt */
00114        }
00115 
00116        rc = 0;
00117        if ( ld != &nsldapi_ld_defaults
00118               && option != LDAP_OPT_EXTRA_THREAD_FN_PTRS
00119               && option != LDAP_OPT_THREAD_FN_PTRS ) {
00120            LDAP_MUTEX_LOCK( ld, LDAP_OPTION_LOCK );
00121        }
00122        switch( option ) {
00123        /* options that can be turned on and off */
00124 #ifdef LDAP_DNS
00125        case LDAP_OPT_DNS:
00126               LDAP_SETCLR_BITOPT( ld, LDAP_BITOPT_DNS, optdata );
00127               break;
00128 #endif
00129 
00130        case LDAP_OPT_REFERRALS:
00131               LDAP_SETCLR_BITOPT( ld, LDAP_BITOPT_REFERRALS, optdata );
00132               break;
00133 
00134        case LDAP_OPT_SSL:
00135               LDAP_SETCLR_BITOPT( ld, LDAP_BITOPT_SSL, optdata );
00136               break;
00137 
00138        case LDAP_OPT_RESTART:
00139               LDAP_SETCLR_BITOPT( ld, LDAP_BITOPT_RESTART, optdata );
00140               break;
00141 
00142        case LDAP_OPT_RECONNECT:
00143               LDAP_SETCLR_BITOPT( ld, LDAP_BITOPT_RECONNECT, optdata );
00144               break;
00145 
00146 #ifdef LDAP_ASYNC_IO
00147        case LDAP_OPT_ASYNC_CONNECT:
00148               LDAP_SETCLR_BITOPT(ld, LDAP_BITOPT_ASYNC, optdata );
00149               break;
00150 #endif /* LDAP_ASYNC_IO */
00151 
00152        /* fields in the LDAP structure */
00153        case LDAP_OPT_DEREF:
00154               ld->ld_deref = *((int *) optdata);
00155               break;
00156        case LDAP_OPT_SIZELIMIT:
00157               ld->ld_sizelimit = *((int *) optdata);
00158                 break;  
00159        case LDAP_OPT_TIMELIMIT:
00160               ld->ld_timelimit = *((int *) optdata);
00161                 break;
00162        case LDAP_OPT_REFERRAL_HOP_LIMIT:
00163               ld->ld_refhoplimit = *((int *) optdata);
00164               break;
00165        case LDAP_OPT_PROTOCOL_VERSION:
00166               ld->ld_version = *((int *) optdata);
00167               if ( ld->ld_defconn != NULL ) {    /* also set in default conn. */
00168                      ld->ld_defconn->lconn_version = ld->ld_version;
00169               }
00170               break;
00171        case LDAP_OPT_SERVER_CONTROLS:
00172               /* nsldapi_dup_controls returns -1 and sets lderrno on error */
00173               rc = nsldapi_dup_controls( ld, &ld->ld_servercontrols,
00174                   (LDAPControl **)optdata );
00175               break;
00176        case LDAP_OPT_CLIENT_CONTROLS:
00177               /* nsldapi_dup_controls returns -1 and sets lderrno on error */
00178               rc = nsldapi_dup_controls( ld, &ld->ld_clientcontrols,
00179                   (LDAPControl **)optdata );
00180               break;
00181 
00182        /* rebind proc */
00183        case LDAP_OPT_REBIND_FN:
00184               ld->ld_rebind_fn = (LDAP_REBINDPROC_CALLBACK *) optdata;
00185               break;
00186        case LDAP_OPT_REBIND_ARG:
00187               ld->ld_rebind_arg = (void *) optdata;
00188               break;
00189 
00190        /* i/o function pointers */
00191        case LDAP_OPT_IO_FN_PTRS:
00192               if (( rc = nsldapi_install_compat_io_fns( ld,
00193                   (struct ldap_io_fns *)optdata )) != LDAP_SUCCESS ) {
00194                      LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
00195                      rc = -1;
00196               }
00197               break;
00198 
00199        /* extended i/o function pointers */
00200        case LDAP_X_OPT_EXTIO_FN_PTRS:
00201          /* denotes use of old iofns struct (no writev) */
00202          if (((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_size == LDAP_X_EXTIO_FNS_SIZE_REV0) {
00203            ld->ld_extio_size = LDAP_X_EXTIO_FNS_SIZE;
00204            ld->ld_extclose_fn = ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_close;
00205            ld->ld_extconnect_fn = ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_connect;
00206            ld->ld_extread_fn = ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_read;
00207            ld->ld_extwrite_fn = ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_write;
00208            ld->ld_extpoll_fn = ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_poll;
00209            ld->ld_extnewhandle_fn = ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_newhandle;
00210            ld->ld_extdisposehandle_fn = ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_disposehandle;
00211            ld->ld_ext_session_arg = ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_session_arg;
00212            ld->ld_extwritev_fn = NULL;
00213            if ( ber_sockbuf_set_option( ld->ld_sbp, LBER_SOCKBUF_OPT_EXT_IO_FNS,
00214                                     &(ld->ld_ext_io_fns) ) != 0 ) {
00215              return( LDAP_LOCAL_ERROR );
00216            }
00217          }
00218          else {
00219            /* struct copy */
00220            ld->ld_ext_io_fns = *((struct ldap_x_ext_io_fns *) optdata);
00221          }
00222          if (( rc = nsldapi_install_lber_extiofns( ld, ld->ld_sbp ))
00223              != LDAP_SUCCESS ) {
00224            LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
00225            rc = -1;
00226          }
00227          break;
00228 
00229        /* thread function pointers */
00230        case LDAP_OPT_THREAD_FN_PTRS:
00231               /*
00232                * It is only safe to set the thread function pointers
00233                * when one thread is using the LDAP session handle.
00234                */
00235               /* free existing mutexes (some are allocated by ldap_init()) */
00236               nsldapi_mutex_free_all( ld );
00237 
00238               /* struct copy */
00239               ld->ld_thread = *((struct ldap_thread_fns *) optdata);
00240 
00241               /* allocate new mutexes */
00242               nsldapi_mutex_alloc_all( ld );
00243 
00244               /* LDAP_OPTION_LOCK was never locked... so just return */
00245               return (rc);
00246 
00247        /* extra thread function pointers */
00248        case LDAP_OPT_EXTRA_THREAD_FN_PTRS:
00249        /* The extra thread funcs will only pick up the threadid */
00250            ld->ld_thread2  = *((struct ldap_extra_thread_fns *) optdata);
00251            
00252        /* Reset the rest of the structure preserving the threadid fn */
00253            ld->ld_mutex_trylock_fn =  (LDAP_TF_MUTEX_TRYLOCK_CALLBACK *)NULL;
00254            ld->ld_sema_alloc_fn = (LDAP_TF_SEMA_ALLOC_CALLBACK *) NULL;
00255            ld->ld_sema_free_fn = (LDAP_TF_SEMA_FREE_CALLBACK *) NULL;
00256            ld->ld_sema_wait_fn = (LDAP_TF_SEMA_WAIT_CALLBACK *) NULL;
00257            ld->ld_sema_post_fn = (LDAP_TF_SEMA_POST_CALLBACK *) NULL;
00258 
00259        /* We assume that only one thread is active when replacing */
00260        /* the threadid function.  We will now proceed and reset all */
00261        /* of the threadid/refcounts */
00262            for( i=0; i<LDAP_MAX_LOCK; i++ ) {
00263                 ld->ld_mutex_threadid[i] = (void *) -1;
00264                 ld->ld_mutex_refcnt[i] = 0;
00265             }
00266 
00267        /* LDAP_OPTION_LOCK was never locked... so just return */
00268            return (rc);
00269 
00270        /* DNS function pointers */
00271        case LDAP_OPT_DNS_FN_PTRS:
00272               /* struct copy */
00273               ld->ld_dnsfn = *((struct ldap_dns_fns *) optdata);
00274               break;
00275 
00276        /* cache function pointers */
00277        case LDAP_OPT_CACHE_FN_PTRS:
00278               /* struct copy */
00279               ld->ld_cache = *((struct ldap_cache_fns *) optdata);
00280               break;
00281        case LDAP_OPT_CACHE_STRATEGY:
00282               ld->ld_cache_strategy = *((int *) optdata);
00283               break;
00284        case LDAP_OPT_CACHE_ENABLE:
00285               ld->ld_cache_on = *((int *) optdata);
00286               break;
00287 
00288        case LDAP_OPT_ERROR_NUMBER:
00289               LDAP_GET_LDERRNO( ld, &matched, &errstr );
00290               matched = nsldapi_strdup( matched );
00291               errstr = nsldapi_strdup( errstr );
00292               LDAP_SET_LDERRNO( ld, *((int *) optdata), matched, errstr );
00293               break;
00294 
00295        case LDAP_OPT_ERROR_STRING:
00296               rc = LDAP_GET_LDERRNO( ld, &matched, NULL );
00297               matched = nsldapi_strdup( matched );
00298               LDAP_SET_LDERRNO( ld, rc, matched,
00299                   nsldapi_strdup((char *) optdata));
00300               rc = LDAP_SUCCESS;
00301               break;
00302 
00303        case LDAP_OPT_MATCHED_DN:
00304               rc = LDAP_GET_LDERRNO( ld, NULL, &errstr );
00305               errstr = nsldapi_strdup( errstr );
00306               LDAP_SET_LDERRNO( ld, rc,
00307                   nsldapi_strdup((char *) optdata), errstr );
00308               rc = LDAP_SUCCESS;
00309               break;
00310 
00311        case LDAP_OPT_PREFERRED_LANGUAGE:
00312               if ( NULL != ld->ld_preferred_language ) {
00313                      NSLDAPI_FREE(ld->ld_preferred_language);
00314               }
00315               ld->ld_preferred_language = nsldapi_strdup((char *) optdata);
00316               break;
00317 
00318        case LDAP_OPT_HOST_NAME:
00319               if ( NULL != ld->ld_defhost ) {
00320                      NSLDAPI_FREE(ld->ld_defhost);
00321               }
00322               ld->ld_defhost = nsldapi_strdup((char *) optdata);
00323               break;
00324 
00325        case LDAP_X_OPT_CONNECT_TIMEOUT:
00326               ld->ld_connect_timeout = *((int *) optdata);
00327               break;
00328 
00329        default:
00330               LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
00331               rc = -1;
00332        }
00333 
00334        if ( ld != &nsldapi_ld_defaults ) {
00335            LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK );
00336        }
00337        return( rc );
00338 }