dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / libldap5 / sources / ldap / common / open.c
blobca6e1fe4364a59b965d41ffd1e841d953bf6a565
1 /*
2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
7 /*
8 * The contents of this file are subject to the Netscape Public
9 * License Version 1.1 (the "License"); you may not use this file
10 * except in compliance with the License. You may obtain a copy of
11 * the License at http://www.mozilla.org/NPL/
13 * Software distributed under the License is distributed on an "AS
14 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
15 * implied. See the License for the specific language governing
16 * rights and limitations under the License.
18 * The Original Code is Mozilla Communicator client code, released
19 * March 31, 1998.
21 * The Initial Developer of the Original Code is Netscape
22 * Communications Corporation. Portions created by Netscape are
23 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
24 * Rights Reserved.
26 * Contributor(s):
29 * Copyright (c) 1995 Regents of the University of Michigan.
30 * All rights reserved.
33 * open.c
36 #if 0
37 static char copyright[] = "@(#) Copyright (c) 1995 Regents of the University of Michigan.\nAll rights reserved.\n";
38 #endif
40 #include "ldap-int.h"
41 #ifdef LDAP_SASLIO_HOOKS
42 /* Valid for any ANSI C compiler */
43 #include <limits.h>
44 #endif
46 #define VI_PRODUCTVERSION 3
48 #ifndef INADDR_LOOPBACK
49 #define INADDR_LOOPBACK ((unsigned long) 0x7f000001)
50 #endif
52 #ifndef MAXHOSTNAMELEN
53 #define MAXHOSTNAMELEN 64
54 #endif
56 #ifdef LDAP_DEBUG
57 int ldap_debug;
58 #endif
62 * global defaults for callbacks are stored here. callers of the API set
63 * these by passing a NULL "ld" to ldap_set_option(). Everything in
64 * nsldapi_ld_defaults can be overridden on a per-ld basis as well (the
65 * memory allocation functions are global to all ld's).
67 struct ldap nsldapi_ld_defaults;
68 struct ldap_memalloc_fns nsldapi_memalloc_fns = { 0, 0, 0, 0 };
69 int nsldapi_initialized = 0;
71 #ifndef _WINDOWS
72 #include <pthread.h>
73 static pthread_key_t nsldapi_key;
75 struct nsldapi_ldap_error {
76 int le_errno;
77 char *le_matched;
78 char *le_errmsg;
80 #else
81 __declspec ( thread ) int nsldapi_gldaperrno;
82 __declspec ( thread ) char *nsldapi_gmatched = NULL;
83 __declspec ( thread ) char *nsldapi_gldaperror = NULL;
84 #endif /* _WINDOWS */
86 #ifdef _WINDOWS
87 #define LDAP_MUTEX_T HANDLE
89 int
90 pthread_mutex_init( LDAP_MUTEX_T *mp, void *attr)
92 if ( (*mp = CreateMutex(NULL, FALSE, NULL)) == NULL )
93 return( 1 );
94 else
95 return( 0 );
98 static void *
99 pthread_mutex_alloc( void )
101 LDAP_MUTEX_T *mutexp;
103 if ( (mutexp = malloc( sizeof(LDAP_MUTEX_T) )) != NULL ) {
104 pthread_mutex_init( mutexp, NULL );
106 return( mutexp );
110 pthread_mutex_destroy( LDAP_MUTEX_T *mp )
112 if ( !(CloseHandle(*mp)) )
113 return( 1 );
114 else
115 return( 0 );
118 static void
119 pthread_mutex_free( void *mutexp )
121 pthread_mutex_destroy( (LDAP_MUTEX_T *) mutexp );
122 free( mutexp );
126 pthread_mutex_lock( LDAP_MUTEX_T *mp )
128 if ( (WaitForSingleObject(*mp, INFINITE) != WAIT_OBJECT_0) )
129 return( 1 );
130 else
131 return( 0 );
135 pthread_mutex_unlock( LDAP_MUTEX_T *mp )
137 if ( !(ReleaseMutex(*mp)) )
138 return( 1 );
139 else
140 return( 0 );
143 static int
144 get_errno( void )
146 return errno;
149 static void
150 set_errno( int Errno )
152 errno = Errno;
155 static int
156 get_ld_error( char **LDMatched, char **LDError, void * Args )
158 if ( LDMatched != NULL )
160 *LDMatched = nsldapi_gmatched;
162 if ( LDError != NULL )
164 *LDError = nsldapi_gldaperror;
166 return nsldapi_gldaperrno;
169 static void
170 set_ld_error( int LDErrno, char * LDMatched, char * LDError,
171 void * Args )
173 /* Clean up any previous string storage. */
174 if ( nsldapi_gmatched != NULL )
176 ldap_memfree( nsldapi_gmatched );
178 if ( nsldapi_gldaperror != NULL )
180 ldap_memfree( nsldapi_gldaperror );
183 nsldapi_gldaperrno = LDErrno;
184 nsldapi_gmatched = LDMatched;
185 nsldapi_gldaperror = LDError;
187 #else
188 static void *
189 pthread_mutex_alloc( void )
191 pthread_mutex_t *mutexp;
193 if ( (mutexp = malloc( sizeof(pthread_mutex_t) )) != NULL ) {
194 pthread_mutex_init( mutexp, NULL );
196 return( mutexp );
199 static void
200 pthread_mutex_free( void *mutexp )
202 pthread_mutex_destroy( (pthread_mutex_t *) mutexp );
203 free( mutexp );
206 static void
207 set_ld_error( int err, char *matched, char *errmsg, void *dummy )
209 struct nsldapi_ldap_error *le;
210 void *tsd;
212 le = pthread_getspecific( nsldapi_key );
214 if (le == NULL) {
215 tsd = (void *)calloc(1, sizeof(struct nsldapi_ldap_error));
216 pthread_setspecific( nsldapi_key, tsd );
219 le = pthread_getspecific( nsldapi_key );
221 if (le == NULL) {
222 free(tsd);
223 return;
226 le->le_errno = err;
228 if ( le->le_matched != NULL ) {
229 ldap_memfree( le->le_matched );
231 le->le_matched = matched;
233 if ( le->le_errmsg != NULL ) {
234 ldap_memfree( le->le_errmsg );
236 le->le_errmsg = errmsg;
239 static int
240 get_ld_error( char **matched, char **errmsg, void *dummy )
242 struct nsldapi_ldap_error *le;
244 le = pthread_getspecific( nsldapi_key );
245 if (le != NULL) {
246 if ( matched != NULL ) {
247 *matched = le->le_matched;
249 if ( errmsg != NULL ) {
250 *errmsg = le->le_errmsg;
252 return( le->le_errno );
253 } else {
254 if ( matched != NULL )
255 *matched = NULL;
256 if ( errmsg != NULL )
257 *errmsg = NULL;
259 return (LDAP_SUCCESS);
262 static void
263 set_errno( int err )
265 errno = err;
268 static int
269 get_errno( void )
271 return( errno );
273 #endif /* _WINDOWS */
275 static struct ldap_thread_fns
276 nsldapi_default_thread_fns = {
277 (void *(*)(void))pthread_mutex_alloc,
278 (void (*)(void *))pthread_mutex_free,
279 (int (*)(void *))pthread_mutex_lock,
280 (int (*)(void *))pthread_mutex_unlock,
281 (int (*)(void))get_errno,
282 (void (*)(int))set_errno,
283 (int (*)(char **, char **, void *))get_ld_error,
284 (void (*)(int, char *, char *, void *))set_ld_error,
285 0 };
287 static struct ldap_extra_thread_fns
288 nsldapi_default_extra_thread_fns = {
289 0, 0, 0, 0, 0,
290 #ifdef _WINDOWS
292 #else
293 (void *(*)(void))pthread_self
294 #endif /* _WINDOWS */
297 void
298 nsldapi_initialize_defaults( void )
301 if ( nsldapi_initialized ) {
302 return;
304 #ifdef _SOLARIS_SDK
306 * This has to be called before nsldapi_initialized is set to 1
307 * because nsldapi_initialized does not have mutex protection
309 prldap_nspr_init();
310 #endif
312 #ifndef _WINDOWS
313 if ( pthread_key_create(&nsldapi_key, free ) != 0) {
314 perror("pthread_key_create");
316 #endif /* _WINDOWS */
318 nsldapi_initialized = 1;
319 memset( &nsldapi_memalloc_fns, 0, sizeof( nsldapi_memalloc_fns ));
320 memset( &nsldapi_ld_defaults, 0, sizeof( nsldapi_ld_defaults ));
321 nsldapi_ld_defaults.ld_options = LDAP_BITOPT_REFERRALS;
322 nsldapi_ld_defaults.ld_version = LDAP_VERSION2;
323 nsldapi_ld_defaults.ld_lberoptions = LBER_OPT_USE_DER;
324 nsldapi_ld_defaults.ld_refhoplimit = LDAP_DEFAULT_REFHOPLIMIT;
326 #ifdef LDAP_SASLIO_HOOKS
327 /* SASL default option settings */
328 nsldapi_ld_defaults.ld_def_sasl_mech = NULL;
329 nsldapi_ld_defaults.ld_def_sasl_realm = NULL;
330 nsldapi_ld_defaults.ld_def_sasl_authcid = NULL;
331 nsldapi_ld_defaults.ld_def_sasl_authzid = NULL;
332 /* SASL Security properties */
333 nsldapi_ld_defaults.ld_sasl_secprops.max_ssf = UINT_MAX;
334 nsldapi_ld_defaults.ld_sasl_secprops.maxbufsize = SASL_MAX_BUFF_SIZE;
335 nsldapi_ld_defaults.ld_sasl_secprops.security_flags =
336 SASL_SEC_NOPLAINTEXT | SASL_SEC_NOANONYMOUS;
337 #endif
339 #if defined( STR_TRANSLATION ) && defined( LDAP_DEFAULT_CHARSET )
340 nsldapi_ld_defaults.ld_lberoptions |= LBER_OPT_TRANSLATE_STRINGS;
341 #if LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET
342 ldap_set_string_translators( &nsldapi_ld_defaults, ldap_8859_to_t61,
343 ldap_t61_to_8859 );
344 #endif /* LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET */
345 #endif /* STR_TRANSLATION && LDAP_DEFAULT_CHARSET */
347 /* set default connect timeout (in milliseconds) */
348 /* this was picked as it is the standard tcp timeout as well */
349 nsldapi_ld_defaults.ld_connect_timeout = LDAP_X_IO_TIMEOUT_NO_TIMEOUT;
351 /* load up default platform specific locking routines */
352 if (ldap_set_option( NULL, LDAP_OPT_THREAD_FN_PTRS,
353 (void *)&nsldapi_default_thread_fns) != LDAP_SUCCESS) {
354 return;
357 #ifndef _WINDOWS
358 /* load up default threadid function */
359 if (ldap_set_option( NULL, LDAP_OPT_EXTRA_THREAD_FN_PTRS,
360 (void *)&nsldapi_default_extra_thread_fns) != LDAP_SUCCESS) {
361 return;
363 #endif /* _WINDOWS */
368 * ldap_version - report version levels for important properties
369 * This function is deprecated. Use ldap_get_option( ..., LDAP_OPT_API_INFO,
370 * ... ) instead.
372 * Example:
373 * LDAPVersion ver;
374 * ldap_version( &ver );
375 * if ( (ver.sdk_version < 100) || (ver.SSL_version < 300) )
376 * fprintf( stderr, "LDAP SDK level insufficient\n" );
378 * or:
379 * if ( ldap_version(NULL) < 100 )
380 * fprintf( stderr, "LDAP SDK level insufficient\n" );
385 LDAP_CALL
386 ldap_version( LDAPVersion *ver )
388 if ( NULL != ver )
390 memset( ver, 0, sizeof(*ver) );
391 ver->sdk_version = (int)(VI_PRODUCTVERSION * 100);
392 ver->protocol_version = LDAP_VERSION_MAX * 100;
393 ver->SSL_version = SSL_VERSION * 100;
395 * set security to none by default
398 ver->security_level = LDAP_SECURITY_NONE;
399 #if defined(LINK_SSL)
400 ver->security_level = 128;
401 #endif
404 return (int)(VI_PRODUCTVERSION * 100);
408 * ldap_open - initialize and connect to an ldap server. A magic cookie to
409 * be used for future communication is returned on success, NULL on failure.
410 * "host" may be a space-separated list of hosts or IP addresses
412 * Example:
413 * LDAP *ld;
414 * ld = ldap_open( hostname, port );
417 LDAP *
418 LDAP_CALL
419 ldap_open( const char *host, int port )
421 LDAP *ld;
423 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_open\n", 0, 0, 0 );
425 if (( ld = ldap_init( host, port )) == NULL ) {
426 return( NULL );
429 LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK );
430 if ( nsldapi_open_ldap_defconn( ld ) < 0 ) {
431 LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
432 ldap_ld_free( ld, NULL, NULL, 0 );
433 return( NULL );
436 LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
437 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_open successful, ld_host is %s\n",
438 ( ld->ld_host == NULL ) ? "(null)" : ld->ld_host, 0, 0 );
440 return( ld );
445 * ldap_init - initialize the LDAP library. A magic cookie to be used for
446 * future communication is returned on success, NULL on failure.
447 * "defhost" may be a space-separated list of hosts or IP addresses
449 * Example:
450 * LDAP *ld;
451 * ld = ldap_init( default_hostname, default_port );
453 LDAP *
454 LDAP_CALL
455 ldap_init( const char *defhost, int defport )
457 LDAP *ld;
459 if ( !nsldapi_initialized ) {
460 nsldapi_initialize_defaults();
463 if ( defport < 0 || defport > LDAP_PORT_MAX ) {
464 LDAPDebug( LDAP_DEBUG_ANY,
465 "ldap_init: port %d is invalid (port numbers must range from 1 to %d)\n",
466 defport, LDAP_PORT_MAX, 0 );
467 #if !defined( macintosh ) && !defined( DOS )
468 errno = EINVAL;
469 #endif
470 return( NULL );
473 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_init\n", 0, 0, 0 );
475 if ( (ld = (LDAP*)NSLDAPI_MALLOC( sizeof(struct ldap) )) == NULL ) {
476 return( NULL );
479 /* copy defaults */
480 SAFEMEMCPY( ld, &nsldapi_ld_defaults, sizeof( struct ldap ));
481 if ( nsldapi_ld_defaults.ld_io_fns_ptr != NULL ) {
482 if (( ld->ld_io_fns_ptr = (struct ldap_io_fns *)NSLDAPI_MALLOC(
483 sizeof( struct ldap_io_fns ))) == NULL ) {
484 NSLDAPI_FREE( (char *)ld );
485 return( NULL );
487 /* struct copy */
488 *(ld->ld_io_fns_ptr) = *(nsldapi_ld_defaults.ld_io_fns_ptr);
491 /* call the new handle I/O callback if one is defined */
492 if ( ld->ld_extnewhandle_fn != NULL ) {
494 * We always pass the session extended I/O argument to
495 * the new handle callback.
497 if ( ld->ld_extnewhandle_fn( ld, ld->ld_ext_session_arg )
498 != LDAP_SUCCESS ) {
499 NSLDAPI_FREE( (char*)ld );
500 return( NULL );
504 /* allocate session-specific resources */
505 if (( ld->ld_sbp = ber_sockbuf_alloc()) == NULL ||
506 ( defhost != NULL &&
507 ( ld->ld_defhost = nsldapi_strdup( defhost )) == NULL ) ||
508 ((ld->ld_mutex = (void **) NSLDAPI_CALLOC( LDAP_MAX_LOCK, sizeof(void *))) == NULL )) {
509 if ( ld->ld_sbp != NULL ) {
510 ber_sockbuf_free( ld->ld_sbp );
512 if( ld->ld_mutex != NULL ) {
513 NSLDAPI_FREE( ld->ld_mutex );
515 NSLDAPI_FREE( (char*)ld );
516 return( NULL );
519 /* install Sockbuf I/O functions if set in LDAP * */
520 if ( ld->ld_extread_fn != NULL || ld->ld_extwrite_fn != NULL ) {
521 struct lber_x_ext_io_fns lberiofns;
523 memset( &lberiofns, 0, sizeof( lberiofns ));
525 lberiofns.lbextiofn_size = LBER_X_EXTIO_FNS_SIZE;
526 lberiofns.lbextiofn_read = ld->ld_extread_fn;
527 lberiofns.lbextiofn_write = ld->ld_extwrite_fn;
528 lberiofns.lbextiofn_writev = ld->ld_extwritev_fn;
529 lberiofns.lbextiofn_socket_arg = NULL;
530 ber_sockbuf_set_option( ld->ld_sbp, LBER_SOCKBUF_OPT_EXT_IO_FNS,
531 (void *)&lberiofns );
534 #ifdef _SOLARIS_SDK
535 /* Install the functions for IPv6 support */
536 /* code sequencing is critical from here to nsldapi_mutex_alloc_all */
537 if ( prldap_install_thread_functions( ld, 1 ) != 0 ||
538 prldap_install_io_functions( ld, 1 ) != 0 ||
539 prldap_install_dns_functions( ld ) != 0 ) {
540 /* go through ld and free resources */
541 ldap_unbind( ld );
542 ld = NULL;
543 return( NULL );
545 #else
547 /* allocate mutexes */
548 nsldapi_mutex_alloc_all( ld );
549 #endif
551 /* set default port */
552 ld->ld_defport = ( defport == 0 ) ? LDAP_PORT : defport;
554 return( ld );
557 void
558 nsldapi_mutex_alloc_all( LDAP *ld )
560 int i;
562 if ( ld != &nsldapi_ld_defaults && ld->ld_mutex != NULL ) {
563 for ( i = 0; i<LDAP_MAX_LOCK; i++ ) {
564 ld->ld_mutex[i] = LDAP_MUTEX_ALLOC( ld );
565 ld->ld_mutex_threadid[i] = (void *) -1;
566 ld->ld_mutex_refcnt[i] = 0;
572 void
573 nsldapi_mutex_free_all( LDAP *ld )
575 int i;
577 if ( ld != &nsldapi_ld_defaults && ld->ld_mutex != NULL ) {
578 for ( i = 0; i<LDAP_MAX_LOCK; i++ ) {
579 LDAP_MUTEX_FREE( ld, ld->ld_mutex[i] );
584 /* returns 0 if connection opened and -1 if an error occurs */
586 nsldapi_open_ldap_defconn( LDAP *ld )
588 LDAPServer *srv;
590 if (( srv = (LDAPServer *)NSLDAPI_CALLOC( 1, sizeof( LDAPServer ))) ==
591 NULL || ( ld->ld_defhost != NULL && ( srv->lsrv_host =
592 nsldapi_strdup( ld->ld_defhost )) == NULL )) {
593 LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
594 return( -1 );
596 srv->lsrv_port = ld->ld_defport;
598 #ifdef LDAP_SSLIO_HOOKS
599 if (( ld->ld_options & LDAP_BITOPT_SSL ) != 0 ) {
600 srv->lsrv_options |= LDAP_SRV_OPT_SECURE;
602 #endif
604 if (( ld->ld_defconn = nsldapi_new_connection( ld, &srv, 1, 1, 0 ))
605 == NULL ) {
606 if ( ld->ld_defhost != NULL ) {
607 NSLDAPI_FREE( srv->lsrv_host );
609 NSLDAPI_FREE( (char *)srv );
610 return( -1 );
612 ++ld->ld_defconn->lconn_refcnt; /* so it never gets closed/freed */
614 return( 0 );
618 struct ldap_x_hostlist_status {
619 char *lhs_hostlist;
620 char *lhs_nexthost;
621 int lhs_defport;
625 * Return the first host and port in hostlist (setting *hostp and *portp).
626 * Return value is an LDAP API error code (LDAP_SUCCESS if all goes well).
627 * Note that a NULL or zero-length hostlist causes the host "127.0.0.1" to
628 * be returned.
630 int LDAP_CALL
631 ldap_x_hostlist_first( const char *hostlist, int defport, char **hostp,
632 int *portp, struct ldap_x_hostlist_status **statusp )
635 if ( NULL == hostp || NULL == portp || NULL == statusp ) {
636 return( LDAP_PARAM_ERROR );
639 if ( NULL == hostlist || *hostlist == '\0' ) {
640 *hostp = nsldapi_strdup( "127.0.0.1" );
641 if ( NULL == *hostp ) {
642 return( LDAP_NO_MEMORY );
644 *portp = defport;
645 *statusp = NULL;
646 return( LDAP_SUCCESS );
649 *statusp = NSLDAPI_CALLOC( 1, sizeof( struct ldap_x_hostlist_status ));
650 if ( NULL == *statusp ) {
651 return( LDAP_NO_MEMORY );
653 (*statusp)->lhs_hostlist = nsldapi_strdup( hostlist );
654 if ( NULL == (*statusp)->lhs_hostlist ) {
655 return( LDAP_NO_MEMORY );
657 (*statusp)->lhs_nexthost = (*statusp)->lhs_hostlist;
658 (*statusp)->lhs_defport = defport;
659 return( ldap_x_hostlist_next( hostp, portp, *statusp ));
663 * Return the next host and port in hostlist (setting *hostp and *portp).
664 * Return value is an LDAP API error code (LDAP_SUCCESS if all goes well).
665 * If no more hosts are available, LDAP_SUCCESS is returned but *hostp is set
666 * to NULL.
668 int LDAP_CALL
669 ldap_x_hostlist_next( char **hostp, int *portp,
670 struct ldap_x_hostlist_status *status )
672 char *q;
673 int squarebrackets = 0;
675 if ( NULL == hostp || NULL == portp ) {
676 return( LDAP_PARAM_ERROR );
679 if ( NULL == status || NULL == status->lhs_nexthost ) {
680 *hostp = NULL;
681 return( LDAP_SUCCESS );
685 * skip past leading '[' if present (IPv6 addresses may be surrounded
686 * with square brackets, e.g., [fe80::a00:20ff:fee5:c0b4]:389
688 if ( status->lhs_nexthost[0] == '[' ) {
689 ++status->lhs_nexthost;
690 squarebrackets = 1;
693 /* copy host into *hostp */
694 if ( NULL != ( q = strchr( status->lhs_nexthost, ' ' ))) {
695 size_t len = q - status->lhs_nexthost;
696 *hostp = NSLDAPI_MALLOC( len + 1 );
697 if ( NULL == *hostp ) {
698 return( LDAP_NO_MEMORY );
700 strncpy( *hostp, status->lhs_nexthost, len );
701 (*hostp)[len] = '\0';
702 status->lhs_nexthost += ( len + 1 );
703 } else { /* last host */
704 *hostp = nsldapi_strdup( status->lhs_nexthost );
705 if ( NULL == *hostp ) {
706 return( LDAP_NO_MEMORY );
708 status->lhs_nexthost = NULL;
712 * Look for closing ']' and skip past it before looking for port.
714 if ( squarebrackets && NULL != ( q = strchr( *hostp, ']' ))) {
715 *q++ = '\0';
716 } else {
717 q = *hostp;
720 /* determine and set port */
721 if ( NULL != ( q = strchr( q, ':' ))) {
722 *q++ = '\0';
723 *portp = atoi( q );
724 } else {
725 *portp = status->lhs_defport;
728 return( LDAP_SUCCESS );
732 void LDAP_CALL
733 ldap_x_hostlist_statusfree( struct ldap_x_hostlist_status *status )
735 if ( NULL != status ) {
736 if ( NULL != status->lhs_hostlist ) {
737 NSLDAPI_FREE( status->lhs_hostlist );
739 NSLDAPI_FREE( status );
746 * memory allocation functions. we include these in open.c since every
747 * LDAP application is likely to pull the rest of the code in this file
748 * in anyways.
750 void *
751 ldap_x_malloc( size_t size )
753 return( nsldapi_memalloc_fns.ldapmem_malloc == NULL ?
754 malloc( size ) :
755 nsldapi_memalloc_fns.ldapmem_malloc( size ));
759 void *
760 ldap_x_calloc( size_t nelem, size_t elsize )
762 return( nsldapi_memalloc_fns.ldapmem_calloc == NULL ?
763 calloc( nelem, elsize ) :
764 nsldapi_memalloc_fns.ldapmem_calloc( nelem, elsize ));
768 void *
769 ldap_x_realloc( void *ptr, size_t size )
771 return( nsldapi_memalloc_fns.ldapmem_realloc == NULL ?
772 realloc( ptr, size ) :
773 nsldapi_memalloc_fns.ldapmem_realloc( ptr, size ));
777 void
778 ldap_x_free( void *ptr )
780 if ( nsldapi_memalloc_fns.ldapmem_free == NULL ) {
781 free( ptr );
782 } else {
783 nsldapi_memalloc_fns.ldapmem_free( ptr );
788 /* if s is NULL, returns NULL */
789 char *
790 nsldapi_strdup( const char *s )
792 char *p;
794 if ( s == NULL ||
795 (p = (char *)NSLDAPI_MALLOC( strlen( s ) + 1 )) == NULL )
796 return( NULL );
798 strcpy( p, s );
800 return( p );