mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-18 11:05:48 +08:00
-lldap reentrantancy improvements from Bart Hartgers <A.Hartgers@phys.tue.nl>
including use of ctime_r, gethostby*_r, etc.. Also reworked ldap_sort_entries to be reentrant. Need to add code to properly set LDAP_API_FEATURE_THREAD_SAFE.
This commit is contained in:
parent
b5e50eff5e
commit
0024cf2f4b
@ -22,7 +22,8 @@ lint5: lint5-local FORCE
|
||||
$(5LINT) $(DEFS) $(DEFINES) $(SRCS)
|
||||
|
||||
clean-common: FORCE
|
||||
$(RM) $(LIBRARY) ../$(LIBRARY) $(PROGRAMS) $(XPROGRAMS) $(XSRCS) \
|
||||
$(RM) $(LIBRARY) ../$(LIBRARY) $(XLIBRARY) \
|
||||
$(PROGRAMS) $(XPROGRAMS) $(XSRCS) \
|
||||
*.o *.lo a.out core version.c .libs/*
|
||||
|
||||
depend-common: FORCE
|
||||
|
48
configure.in
48
configure.in
@ -803,24 +803,37 @@ int x = errno;
|
||||
LTHREAD_LIBS=""
|
||||
fi
|
||||
|
||||
dnl check for reentrant/threadsafe functions
|
||||
dnl When in thread environment, use
|
||||
dnl #if defined( HAVE_REENTRANT_FUNCTIONS ) \
|
||||
dnl || defined( HAVE_FUNC_R )
|
||||
dnl func_r(...);
|
||||
dnl #else
|
||||
dnl func(...);
|
||||
dnl #endif
|
||||
dnl
|
||||
dnl note: these should only be used when linking
|
||||
dnl with $LTHREAD_LIBS
|
||||
dnl HAVE_REENTRANT_FUNCTIONS is derived from:
|
||||
dnl _POSIX_REENTRANT_FUNCTIONS
|
||||
dnl _POSIX_THREAD_SAFE_FUNCTIONS
|
||||
dnl _POSIX_THREADSAFE_FUNCTIONS
|
||||
dnl
|
||||
save_CPPFLAGS="$CPPFLAGS"
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="$LTHREAD_LIBS $LIBS"
|
||||
AC_CHECK_FUNCS( \
|
||||
strtok_r \
|
||||
gmtime_r \
|
||||
gethostbyaddr_r gethostbyname_r \
|
||||
feof_unlocked unlocked_feof \
|
||||
putc_unlocked unlocked_putc \
|
||||
flockfile ftrylockfile \
|
||||
)
|
||||
CPPFLAGS="$save_CPPFLAGS"
|
||||
LIBS="$save_LIBS"
|
||||
dnl dnl check for reentrant/threadsafe functions
|
||||
dnl dnl
|
||||
dnl dnl note: these should only be used when linking
|
||||
dnl dnl with $LTHREAD_LIBS
|
||||
dnl dnl
|
||||
dnl save_CPPFLAGS="$CPPFLAGS"
|
||||
dnl save_LIBS="$LIBS"
|
||||
dnl LIBS="$LTHREAD_LIBS $LIBS"
|
||||
dnl AC_CHECK_FUNCS( \
|
||||
dnl strtok_r \
|
||||
dnl gmtime_r \
|
||||
dnl gethostbyaddr_r gethostbyname_r \
|
||||
dnl feof_unlocked unlocked_feof \
|
||||
dnl putc_unlocked unlocked_putc \
|
||||
dnl flockfile ftrylockfile \
|
||||
dnl )
|
||||
dnl CPPFLAGS="$save_CPPFLAGS"
|
||||
dnl LIBS="$save_LIBS"
|
||||
fi
|
||||
|
||||
dnl ----------------------------------------------------------------
|
||||
@ -1103,9 +1116,11 @@ AC_FUNC_WAIT3
|
||||
|
||||
AC_CHECK_FUNCS( \
|
||||
bcopy \
|
||||
ctime_r \
|
||||
flock \
|
||||
getdtablesize \
|
||||
gethostname \
|
||||
gethostbyaddr_r gethostbyname_r \
|
||||
getpwuid \
|
||||
gettimeofday \
|
||||
lockf \
|
||||
@ -1126,6 +1141,7 @@ AC_CHECK_FUNCS( \
|
||||
strsep \
|
||||
strstr \
|
||||
strtok \
|
||||
strtok_r \
|
||||
strtol \
|
||||
strtoul \
|
||||
sysconf \
|
||||
|
@ -279,18 +279,12 @@ is provided ``as is'' without express or implied warranty.
|
||||
/* Define if you have the bcopy function. */
|
||||
#undef HAVE_BCOPY
|
||||
|
||||
/* Define if you have the feof_unlocked function. */
|
||||
#undef HAVE_FEOF_UNLOCKED
|
||||
/* Define if you have the ctime_r function. */
|
||||
#undef HAVE_CTIME_R
|
||||
|
||||
/* Define if you have the flock function. */
|
||||
#undef HAVE_FLOCK
|
||||
|
||||
/* Define if you have the flockfile function. */
|
||||
#undef HAVE_FLOCKFILE
|
||||
|
||||
/* Define if you have the ftrylockfile function. */
|
||||
#undef HAVE_FTRYLOCKFILE
|
||||
|
||||
/* Define if you have the getdtablesize function. */
|
||||
#undef HAVE_GETDTABLESIZE
|
||||
|
||||
@ -312,9 +306,6 @@ is provided ``as is'' without express or implied warranty.
|
||||
/* Define if you have the gettimeofday function. */
|
||||
#undef HAVE_GETTIMEOFDAY
|
||||
|
||||
/* Define if you have the gmtime_r function. */
|
||||
#undef HAVE_GMTIME_R
|
||||
|
||||
/* Define if you have the lockf function. */
|
||||
#undef HAVE_LOCKF
|
||||
|
||||
@ -354,9 +345,6 @@ is provided ``as is'' without express or implied warranty.
|
||||
/* Define if you have the pthread_yield function. */
|
||||
#undef HAVE_PTHREAD_YIELD
|
||||
|
||||
/* Define if you have the putc_unlocked function. */
|
||||
#undef HAVE_PUTC_UNLOCKED
|
||||
|
||||
/* Define if you have the res_search function. */
|
||||
#undef HAVE_RES_SEARCH
|
||||
|
||||
@ -423,12 +411,6 @@ is provided ``as is'' without express or implied warranty.
|
||||
/* Define if you have the thr_setconcurrency function. */
|
||||
#undef HAVE_THR_SETCONCURRENCY
|
||||
|
||||
/* Define if you have the unlocked_feof function. */
|
||||
#undef HAVE_UNLOCKED_FEOF
|
||||
|
||||
/* Define if you have the unlocked_putc function. */
|
||||
#undef HAVE_UNLOCKED_PUTC
|
||||
|
||||
/* Define if you have the vsnprintf function. */
|
||||
#undef HAVE_VSNPRINTF
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
##
|
||||
|
||||
LIBRARY = liblber.la
|
||||
XLIBRARY = ../liblber.a
|
||||
|
||||
SRCS= decode.c encode.c io.c bprint.c
|
||||
OBJS= decode.lo encode.lo io.lo bprint.lo
|
||||
|
@ -2,6 +2,8 @@
|
||||
## Makefile.in for LDAP -lldap
|
||||
##
|
||||
LIBRARY = libldap.la
|
||||
XLIBRARY = ../libldap.a
|
||||
|
||||
PROGRAMS = apitest ltest ttest
|
||||
|
||||
SRCS = bind.c open.c result.c error.c compare.c search.c \
|
||||
@ -10,14 +12,14 @@ SRCS = bind.c open.c result.c error.c compare.c search.c \
|
||||
free.c disptmpl.c srchpref.c dsparse.c tmplout.c sort.c \
|
||||
getdn.c getentry.c getattr.c getvalues.c addentry.c \
|
||||
request.c getdxbyname.c os-ip.c url.c charset.c \
|
||||
init.c options.c strdup.c
|
||||
init.c options.c strdup.c util-int.c
|
||||
OBJS = bind.lo open.lo result.lo error.lo compare.lo search.lo \
|
||||
modify.lo add.lo modrdn.lo delete.lo abandon.lo ufn.lo cache.lo \
|
||||
getfilter.lo sbind.lo kbind.lo unbind.lo friendly.lo cldap.lo \
|
||||
free.lo disptmpl.lo srchpref.lo dsparse.lo tmplout.lo sort.lo \
|
||||
getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \
|
||||
request.lo getdxbyname.lo os-ip.lo url.lo charset.lo \
|
||||
init.lo options.lo strdup.lo
|
||||
init.lo options.lo strdup.lo util-int.lo
|
||||
|
||||
LDAP_INCDIR= ../../include
|
||||
LDAP_LIBDIR= ../../libraries
|
||||
|
@ -64,6 +64,13 @@ cldap_open( char *host, int port )
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
/* buffers for ldap_int_gethostbyname_a ... */
|
||||
struct hostent he_buf;
|
||||
int local_h_errno;
|
||||
char *ha_buf=NULL;
|
||||
|
||||
#define DO_RETURN(x) if (ha_buf) free(ha_buf); return (x);
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_open\n", 0, 0, 0 );
|
||||
|
||||
if ( (s = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) {
|
||||
@ -110,7 +117,9 @@ cldap_open( char *host, int port )
|
||||
/* This was just a test for -1 until OSF1 let inet_addr return
|
||||
unsigned int, which is narrower than 'unsigned long address' */
|
||||
if ( address == 0xffffffff || address == (unsigned long) -1 ) {
|
||||
if ( (hp = gethostbyname( host )) == NULL ) {
|
||||
if ((ldap_int_gethostbyname_a( host, &he_buf, &ha_buf,
|
||||
&hp,&local_h_errno)<0) ||
|
||||
(hp==NULL)) {
|
||||
errno = EHOSTUNREACH;
|
||||
continue;
|
||||
}
|
||||
@ -121,7 +130,7 @@ cldap_open( char *host, int port )
|
||||
sizeof(sock.sin_addr.s_addr));
|
||||
if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) {
|
||||
ldap_ld_free( ld, 1 );
|
||||
return( NULL );
|
||||
DO_RETURN( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,7 +138,7 @@ cldap_open( char *host, int port )
|
||||
sock.sin_addr.s_addr = address;
|
||||
if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) {
|
||||
ldap_ld_free( ld, 1 );
|
||||
return( NULL );
|
||||
DO_RETURN( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,13 +146,12 @@ cldap_open( char *host, int port )
|
||||
ld->ld_host = ldap_strdup( host );
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
address = INADDR_LOOPBACK;
|
||||
sock.sin_addr.s_addr = htonl( address );
|
||||
if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) {
|
||||
ldap_ld_free( ld, 1 );
|
||||
return( NULL );
|
||||
DO_RETURN( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,7 +161,7 @@ cldap_open( char *host, int port )
|
||||
#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */
|
||||
) {
|
||||
ldap_ld_free( ld, 0 );
|
||||
return( NULL );
|
||||
DO_RETURN( NULL );
|
||||
}
|
||||
|
||||
ld->ld_sb.sb_useaddr = ld->ld_sb.sb_addrs[ 0 ];
|
||||
@ -168,10 +176,10 @@ cldap_open( char *host, int port )
|
||||
}
|
||||
#endif
|
||||
|
||||
return( ld );
|
||||
DO_RETURN( ld );
|
||||
}
|
||||
|
||||
|
||||
#undef DO_RETURN
|
||||
|
||||
void
|
||||
cldap_close( LDAP *ld )
|
||||
|
@ -124,6 +124,7 @@ ldap_explode_dns( char *dn )
|
||||
int ncomps, maxcomps;
|
||||
char *s;
|
||||
char **rdns;
|
||||
char *tok_r;
|
||||
|
||||
if ( (rdns = (char **) malloc( 8 * sizeof(char *) )) == NULL ) {
|
||||
return( NULL );
|
||||
@ -131,7 +132,8 @@ ldap_explode_dns( char *dn )
|
||||
|
||||
maxcomps = 8;
|
||||
ncomps = 0;
|
||||
for ( s = strtok( dn, "@." ); s != NULL; s = strtok( NULL, "@." ) ) {
|
||||
for ( s = ldap_int_strtok( dn, "@.", &tok_r ); s != NULL;
|
||||
s = ldap_int_strtok( NULL, "@.", &tok_r ) ) {
|
||||
if ( ncomps == maxcomps ) {
|
||||
maxcomps *= 2;
|
||||
if ( (rdns = (char **) realloc( rdns, maxcomps *
|
||||
|
@ -405,6 +405,7 @@ break_into_words( char *str, char *delims, char ***wordsp )
|
||||
{
|
||||
char *word, **words;
|
||||
int count;
|
||||
char *tok_r;
|
||||
|
||||
if (( words = (char **)calloc( 1, sizeof( char * ))) == NULL ) {
|
||||
return( -1 );
|
||||
@ -412,7 +413,7 @@ break_into_words( char *str, char *delims, char ***wordsp )
|
||||
count = 0;
|
||||
words[ count ] = NULL;
|
||||
|
||||
word = strtok( str, delims );
|
||||
word = ldap_int_strtok( str, delims, &tok_r );
|
||||
while ( word != NULL ) {
|
||||
if (( words = (char **)realloc( words,
|
||||
( count + 2 ) * sizeof( char * ))) == NULL ) {
|
||||
@ -421,7 +422,7 @@ break_into_words( char *str, char *delims, char ***wordsp )
|
||||
|
||||
words[ count ] = word;
|
||||
words[ ++count ] = NULL;
|
||||
word = strtok( NULL, delims );
|
||||
word = ldap_int_strtok( NULL, delims, &tok_r );
|
||||
}
|
||||
|
||||
*wordsp = words;
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "../liblber/lber-int.h"
|
||||
#include "ldap_log.h"
|
||||
#include "ldap.h"
|
||||
#include <time.h>
|
||||
#include <netdb.h>
|
||||
|
||||
LDAP_BEGIN_DECL
|
||||
|
||||
@ -273,6 +275,28 @@ int ldap_8859_to_t61( char **bufp, unsigned long *buflenp, int free_input );
|
||||
#endif /* LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET */
|
||||
#endif /* STR_TRANSLATION && LDAP_DEFAULT_CHARSET */
|
||||
|
||||
/*
|
||||
* in util_r.c
|
||||
*
|
||||
*/
|
||||
|
||||
extern char *ldap_int_strtok( char *str, const char *delim, char **pos );
|
||||
extern char *ldap_int_ctime( const time_t *tp, char *buf );
|
||||
extern int ldap_int_gethostbyname_a(
|
||||
const char *name,
|
||||
struct hostent *resbuf,
|
||||
char **buf,
|
||||
struct hostent **result,
|
||||
int *herrno_ptr );
|
||||
extern int ldap_int_gethostbyaddr_a(
|
||||
const char *addr,
|
||||
int len,
|
||||
int type,
|
||||
struct hostent *resbuf,
|
||||
char **buf,
|
||||
struct hostent **result,
|
||||
int *herrno_ptr );
|
||||
|
||||
LDAP_END_DECL
|
||||
|
||||
#endif /* _LDAP_INT_H */
|
||||
|
@ -49,6 +49,12 @@ ldap_connect_to_host( Sockbuf *sb, char *host, unsigned long address,
|
||||
#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */
|
||||
#endif /* notyet */
|
||||
|
||||
/* buffers for ldap_int_gethostbyname_a */
|
||||
struct hostent he_buf;
|
||||
int local_h_errno;
|
||||
char *ha_buf=NULL;
|
||||
#define DO_RETURN(x) if (ha_buf) free(ha_buf); return (x);
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "ldap_connect_to_host: %s:%d\n",
|
||||
( host == NULL ) ? "(by address)" : host, (int) ntohs( (short) port ), 0 );
|
||||
|
||||
@ -59,13 +65,15 @@ ldap_connect_to_host( Sockbuf *sb, char *host, unsigned long address,
|
||||
/* This was just a test for -1 until OSF1 let inet_addr return
|
||||
unsigned int, which is narrower than 'unsigned long address' */
|
||||
if ( address == 0xffffffff || address == (unsigned long) -1 ) {
|
||||
if ( (hp = gethostbyname( host )) == NULL ) {
|
||||
if ( ( ldap_int_gethostbyname_a( host, &he_buf, &ha_buf,
|
||||
&hp, &local_h_errno) < 0) || (hp==NULL))
|
||||
{
|
||||
#ifdef HAVE_WINSOCK
|
||||
errno = WSAGetLastError();
|
||||
#else
|
||||
errno = EHOSTUNREACH; /* not exactly right, but... */
|
||||
#endif
|
||||
return( -1 );
|
||||
DO_RETURN( -1 );
|
||||
}
|
||||
use_hp = 1;
|
||||
}
|
||||
@ -74,7 +82,7 @@ ldap_connect_to_host( Sockbuf *sb, char *host, unsigned long address,
|
||||
rc = -1;
|
||||
for ( i = 0; !use_hp || ( hp->h_addr_list[ i ] != 0 ); i++ ) {
|
||||
if (( s = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) {
|
||||
return( -1 );
|
||||
DO_RETURN( -1 );
|
||||
}
|
||||
#ifdef notyet
|
||||
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
|
||||
@ -145,9 +153,13 @@ ldap_connect_to_host( Sockbuf *sb, char *host, unsigned long address,
|
||||
s, (char *) inet_ntoa( sin.sin_addr ), 0 );
|
||||
}
|
||||
|
||||
return( rc );
|
||||
DO_RETURN( rc );
|
||||
|
||||
|
||||
}
|
||||
|
||||
#undef DO_RETURN
|
||||
|
||||
|
||||
void
|
||||
ldap_close_connection( Sockbuf *sb )
|
||||
@ -165,6 +177,12 @@ ldap_host_connected_to( Sockbuf *sb )
|
||||
int len;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
/* buffers for gethostbyaddr_r */
|
||||
struct hostent he_buf;
|
||||
int local_h_errno;
|
||||
char *ha_buf=NULL;
|
||||
#define DO_RETURN(x) if (ha_buf) free(ha_buf); return (x);
|
||||
|
||||
(void)memset( (char *)&sin, 0, sizeof( struct sockaddr_in ));
|
||||
len = sizeof( sin );
|
||||
if ( getpeername( sb->sb_sd, (struct sockaddr *)&sin, &len ) == -1 ) {
|
||||
@ -176,15 +194,20 @@ ldap_host_connected_to( Sockbuf *sb )
|
||||
* this is necessary for kerberos to work right, since the official
|
||||
* hostname is used as the kerberos instance.
|
||||
*/
|
||||
if (( hp = gethostbyaddr( (char *) &sin.sin_addr,
|
||||
sizeof( sin.sin_addr ), AF_INET )) != NULL ) {
|
||||
if ((ldap_int_gethostbyaddr_a( (char *) &sin.sin_addr,
|
||||
sizeof( sin.sin_addr ),
|
||||
AF_INET, &he_buf, &ha_buf,
|
||||
&hp,&local_h_errno ) ==0 ) && (hp != NULL) )
|
||||
{
|
||||
if ( hp->h_name != NULL ) {
|
||||
return( ldap_strdup( hp->h_name ));
|
||||
DO_RETURN( ldap_strdup( hp->h_name ));
|
||||
}
|
||||
}
|
||||
|
||||
return( NULL );
|
||||
DO_RETURN( NULL );
|
||||
}
|
||||
#undef DO_RETURN
|
||||
|
||||
#endif /* HAVE_KERBEROS */
|
||||
|
||||
|
||||
|
@ -442,6 +442,7 @@ void
|
||||
ldap_dump_connection( LDAP *ld, LDAPConn *lconns, int all )
|
||||
{
|
||||
LDAPConn *lc;
|
||||
char timebuf[32];
|
||||
|
||||
fprintf( stderr, "** Connection%s:\n", all ? "s" : "" );
|
||||
for ( lc = lconns; lc != NULL; lc = lc->lconn_next ) {
|
||||
@ -457,7 +458,7 @@ ldap_dump_connection( LDAP *ld, LDAPConn *lconns, int all )
|
||||
"NeedSocket" : ( lc->lconn_status ==
|
||||
LDAP_CONNST_CONNECTING ) ? "Connecting" : "Connected" );
|
||||
fprintf( stderr, " last used: %s\n",
|
||||
ctime( &lc->lconn_lastused ));
|
||||
ldap_int_ctime( &lc->lconn_lastused, timebuf ));
|
||||
if ( !all ) {
|
||||
break;
|
||||
}
|
||||
|
@ -27,9 +27,9 @@
|
||||
struct entrything {
|
||||
char **et_vals;
|
||||
LDAPMessage *et_msg;
|
||||
int (*et_cmp_fn) LDAP_P((const char *a, const char *b));
|
||||
};
|
||||
|
||||
static int (*et_cmp_fn) LDAP_P(( const char *a, const char *b ));
|
||||
static int et_cmp LDAP_P(( const void *aa, const void *bb));
|
||||
|
||||
|
||||
@ -60,8 +60,7 @@ et_cmp(
|
||||
return( 1 );
|
||||
|
||||
for ( i = 0; a->et_vals[i] && b->et_vals[i]; i++ ) {
|
||||
if ( (rc = (*et_cmp_fn)( a->et_vals[i], b->et_vals[i] ))
|
||||
!= 0 ) {
|
||||
if ( (rc = a->et_cmp_fn( a->et_vals[i], b->et_vals[i] )) != 0 ) {
|
||||
return( rc );
|
||||
}
|
||||
}
|
||||
@ -96,6 +95,7 @@ ldap_sort_entries(
|
||||
|
||||
e = *chain;
|
||||
for ( i = 0; i < count; i++ ) {
|
||||
et[i].et_cmp_fn = cmp;
|
||||
et[i].et_msg = e;
|
||||
if ( attr == NULL ) {
|
||||
char *dn;
|
||||
@ -111,7 +111,6 @@ ldap_sort_entries(
|
||||
}
|
||||
last = e;
|
||||
|
||||
et_cmp_fn = cmp;
|
||||
qsort( et, count, sizeof(struct entrything), et_cmp );
|
||||
|
||||
ep = chain;
|
||||
|
@ -874,6 +874,7 @@ time2text( char *ldtimestr, int dateonly )
|
||||
struct tm t;
|
||||
char *p, *timestr, zone, *fmterr = "badly formatted time";
|
||||
time_t gmttime;
|
||||
char timebuf[32];
|
||||
|
||||
memset( (char *)&t, 0, sizeof( struct tm ));
|
||||
if ( (int) strlen( ldtimestr ) < 13 ) {
|
||||
@ -899,7 +900,8 @@ time2text( char *ldtimestr, int dateonly )
|
||||
}
|
||||
|
||||
gmttime = gtime( &t );
|
||||
timestr = ctime( &gmttime );
|
||||
|
||||
timestr = ldap_int_ctime( &gmttime, timebuf );
|
||||
|
||||
timestr[ strlen( timestr ) - 1 ] = zone; /* replace trailing newline */
|
||||
if ( dateonly ) {
|
||||
|
141
libraries/libldap/util-int.c
Normal file
141
libraries/libldap/util-int.c
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* util-int.c Various functions to replace missing threadsafe ones.
|
||||
* Without the real *_r funcs, things will work, but won't be
|
||||
* threadsafe.
|
||||
*
|
||||
* Written by Bart Hartgers.
|
||||
*
|
||||
* Copyright 1998, A. Hartgers, All rights reserved.
|
||||
* This software is not subject to any license of Eindhoven University of
|
||||
* Technology, since it was written in my spare time.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted only
|
||||
* as authorized by the OpenLDAP Public License. A copy of this
|
||||
* license is available at http://www.OpenLDAP.org/license.html or
|
||||
* in file LICENSE in the top-level directory of the distribution.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <ac/errno.h>
|
||||
#include <ac/socket.h>
|
||||
#include <ac/string.h>
|
||||
#include <ac/time.h>
|
||||
|
||||
#include "ldap-int.h"
|
||||
|
||||
char *ldap_int_strtok( char *str, const char *delim, char **pos )
|
||||
{
|
||||
#ifdef HAVE_STRTOK_R
|
||||
return strtok_r(str, delim, pos);
|
||||
#else
|
||||
return strtok(str, delim);
|
||||
#endif
|
||||
}
|
||||
|
||||
char *ldap_int_ctime( const time_t *tp, char *buf )
|
||||
{
|
||||
#ifdef HAVE_CTIME_R
|
||||
return ctime_r(tp,buf);
|
||||
#else
|
||||
return ctime(tp);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define BUFSTART 1024
|
||||
#define BUFMAX (32*1024)
|
||||
|
||||
static char *safe_realloc( char **buf, int len )
|
||||
{
|
||||
char *tmpbuf;
|
||||
tmpbuf = realloc( *buf, len );
|
||||
if (tmpbuf) {
|
||||
*buf=tmpbuf;
|
||||
}
|
||||
return tmpbuf;
|
||||
}
|
||||
|
||||
int ldap_int_gethostbyname_a(
|
||||
const char *name,
|
||||
struct hostent *resbuf,
|
||||
char **buf,
|
||||
struct hostent **result,
|
||||
int *herrno_ptr )
|
||||
{
|
||||
#ifdef HAVE_GETHOSTBYNAME_R
|
||||
int r;
|
||||
int buflen=BUFSTART;
|
||||
|
||||
if (safe_realloc( buf, buflen)) {
|
||||
for(;buflen<BUFMAX;) {
|
||||
r = gethostbyname_r( name, resbuf, *buf,
|
||||
buflen, result, herrno_ptr );
|
||||
#ifdef NETDB_INTERNAL
|
||||
if ((r<0) &&
|
||||
(*herrno_ptr==NETDB_INTERNAL) &&
|
||||
(errno==ERANGE))
|
||||
{
|
||||
if (safe_realloc( buf, buflen*=2 )) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* gethostbyname() */
|
||||
*result = gethostbyname( name );
|
||||
|
||||
if (*result!=NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*herrno_ptr = h_errno;
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ldap_int_gethostbyaddr_a(
|
||||
const char *addr,
|
||||
int len,
|
||||
int type,
|
||||
struct hostent *resbuf,
|
||||
char **buf,
|
||||
struct hostent **result,
|
||||
int *herrno_ptr )
|
||||
{
|
||||
#ifdef HAVE_GETHOSTBYADDR_R
|
||||
int r;
|
||||
int buflen=BUFSTART;
|
||||
if (safe_realloc( buf, buflen)) {
|
||||
for(;buflen<BUFMAX;) {
|
||||
r = gethostbyaddr_r( addr, len, type,
|
||||
resbuf, *buf, buflen,
|
||||
result, herrno_ptr );
|
||||
#ifdef NETDB_INTERNAL
|
||||
if ((r<0) &&
|
||||
(*herrno_ptr==NETDB_INTERNAL) &&
|
||||
(errno==ERANGE))
|
||||
{
|
||||
if (safe_realloc( buf, buflen*=2))
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* gethostbyaddr() */
|
||||
*result = gethostbyaddr( addr, len, type );
|
||||
|
||||
if (*result!=NULL) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
Loading…
Reference in New Issue
Block a user