char *p;
int i;
- /* buffers for ldap_int_gethostbyname_a ... */
+ /* buffers for ldap_pvt_gethostbyname_a ... */
struct hostent he_buf;
int local_h_errno;
char *ha_buf=NULL;
/* 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 ((ldap_int_gethostbyname_a( host, &he_buf, &ha_buf,
+ if ((ldap_pvt_gethostbyname_a( host, &he_buf, &ha_buf,
&hp,&local_h_errno)<0) ||
(hp==NULL)) {
errno = EHOSTUNREACH;
}
if ( ld->ld_host == NULL ) {
- ld->ld_host = ldap_strdup( host );
+ ld->ld_host = strdup( host );
}
}
} else {
}
if( c->ldctl_oid != NULL ) {
- new->ldctl_oid = ldap_strdup( c->ldctl_oid );
+ new->ldctl_oid = strdup( c->ldctl_oid );
if(new->ldctl_oid == NULL) {
free( new );
for ( i = 0; !memerr && includeattrs[ i ] != NULL; ++i ) {
if (( attrs = (char **)realloc( attrs, ( attrcnt + 2 ) *
sizeof( char * ))) == NULL || ( attrs[ attrcnt++ ] =
- ldap_strdup( includeattrs[ i ] )) == NULL ) {
+ strdup( includeattrs[ i ] )) == NULL ) {
memerr = 1;
} else {
attrs[ attrcnt ] = NULL;
if ( ticolp->ti_attrname != NULL ) {
if (( attrs = (char **)realloc( attrs, ( attrcnt + 2 ) *
sizeof( char * ))) == NULL || ( attrs[ attrcnt++ ] =
- ldap_strdup( ticolp->ti_attrname )) == NULL ) {
+ strdup( ticolp->ti_attrname )) == NULL ) {
memerr = 1;
} else {
attrs[ attrcnt ] = NULL;
return( NULL );
}
- return( ldap_strdup( tokstart ));
+ return( strdup( tokstart ));
}
}
}
- (*map)[i].lf_unfriendly = ldap_strdup( buf );
- (*map)[i].lf_friendly = ldap_strdup( s );
+ (*map)[i].lf_unfriendly = strdup( buf );
+ (*map)[i].lf_friendly = strdup( s );
i++;
}
Debug( LDAP_DEBUG_TRACE, "ldap_dn2ufn\n", 0, 0, 0 );
if ( ldap_is_dns_dn( dn ) || ( p = strchr( dn, '=' )) == NULL )
- return( ldap_strdup( dn ) );
+ return( strdup( dn ) );
- ufn = ldap_strdup( ++p );
+ ufn = strdup( ++p );
#define INQUOTE 1
#define OUTQUOTE 2
maxcomps = 8;
ncomps = 0;
- for ( s = ldap_int_strtok( dn, "@.", &tok_r ); s != NULL;
- s = ldap_int_strtok( NULL, "@.", &tok_r ) ) {
+ for ( s = ldap_pvt_strtok( dn, "@.", &tok_r ); s != NULL;
+ s = ldap_pvt_strtok( NULL, "@.", &tok_r ) ) {
if ( ncomps == maxcomps ) {
maxcomps *= 2;
if ( (rdns = (char **) realloc( rdns, maxcomps *
return( NULL );
}
}
- rdns[ncomps++] = ldap_strdup( s );
+ rdns[ncomps++] = strdup( s );
}
rdns[ncomps] = NULL;
* punt: return list conisting of the original domain name only
*/
if (( dxs = (char **)malloc( 2 * sizeof( char * ))) == NULL ||
- ( dxs[ 0 ] = ldap_strdup( domain )) == NULL ) {
+ ( dxs[ 0 ] = strdup( domain )) == NULL ) {
if ( dxs != NULL ) {
free( dxs );
}
ldap_getfilter_free( lfdp );
return( NULL );
}
- nextflp->lfl_tag = ldap_strdup( tag );
+ nextflp->lfl_tag = strdup( tag );
nextflp->lfl_pattern = tok[ 0 ];
if ( (rc = regcomp( &re, nextflp->lfl_pattern, 0 )) != 0 ) {
#ifdef LDAP_LIBUI
if ( lfdp->lfd_filtprefix != NULL ) {
free( lfdp->lfd_filtprefix );
}
- lfdp->lfd_filtprefix = ( prefix == NULL ) ? NULL : ldap_strdup( prefix );
+ lfdp->lfd_filtprefix = ( prefix == NULL ) ? NULL : strdup( prefix );
if ( lfdp->lfd_filtsuffix != NULL ) {
free( lfdp->lfd_filtsuffix );
}
- lfdp->lfd_filtsuffix = ( suffix == NULL ) ? NULL : ldap_strdup( suffix );
+ lfdp->lfd_filtsuffix = ( suffix == NULL ) ? NULL : strdup( suffix );
}
return( NULL );
}
- if (( lfdp->lfd_curvalcopy = ldap_strdup( value )) == NULL ) {
+ if (( lfdp->lfd_curvalcopy = strdup( value )) == NULL ) {
return( NULL );
}
count = 0;
words[ count ] = NULL;
- word = ldap_int_strtok( str, delims, &tok_r );
+ word = ldap_pvt_strtok( str, delims, &tok_r );
while ( word != NULL ) {
if (( words = (char **)realloc( words,
( count + 2 ) * sizeof( char * ))) == NULL ) {
words[ count ] = word;
words[ ++count ] = NULL;
- word = ldap_int_strtok( NULL, delims, &tok_r );
+ word = ldap_pvt_strtok( NULL, delims, &tok_r );
}
*wordsp = words;
case ATTR_STRING:
if (* (char**) p != NULL) free(* (char**) p);
- * (char**) p = ldap_strdup(opt);
+ * (char**) p = strdup(opt);
break;
}
}
if (*value == '\0') {
* (char**) p = NULL;
} else {
- * (char**) p = ldap_strdup(value);
+ * (char**) p = strdup(value);
}
break;
}
if ( openldap_ldap_initialized ) {
return;
}
-
+
+ ldap_pvt_init_utils();
+
gopts.ldo_version = LDAP_VERSION2;
gopts.ldo_deref = LDAP_DEREF_NEVER;
gopts.ldo_timelimit = LDAP_NO_LIMIT;
gopts.ldo_debug = 0;
- gopts.ldo_defhost = ldap_strdup("localhost");
+ gopts.ldo_defhost = strdup("localhost");
gopts.ldo_defport = LDAP_PORT;
gopts.ldo_refhoplimit = LDAP_DEFAULT_REFHOPLIMIT;
#include "ldap.h"
+#include "ldap_pvt.h"
+
LDAP_BEGIN_DECL
#define LDAP_URL_PREFIX "ldap://"
#endif /* LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET */
#endif /* STR_TRANSLATION && LDAP_DEFAULT_CHARSET */
-/*
- * in util_r.c
- *
- */
-
-struct hostent; /* avoid pulling in <netdb.h> */
-
-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 */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
if (( srv = (LDAPServer *)calloc( 1, sizeof( LDAPServer ))) ==
NULL || ( ld->ld_defhost != NULL && ( srv->lsrv_host =
- ldap_strdup( ld->ld_defhost )) == NULL )) {
+ strdup( ld->ld_defhost )) == NULL )) {
ldap_ld_free( ld, 0 );
return( NULL );
}
ld->ld_options.ldo_defhost = NULL;
if ( defhost != NULL ) {
- ld->ld_options.ldo_defhost = ldap_strdup( defhost );
+ ld->ld_options.ldo_defhost = strdup( defhost );
} else {
- ld->ld_options.ldo_defhost = ldap_strdup(
+ ld->ld_options.ldo_defhost = strdup(
openldap_ldap_global_options.ldo_defhost);
}
}
if ( openldap_ldap_global_options.ldo_defbase != NULL ) {
- ld->ld_options.ldo_defbase = ldap_strdup(
+ ld->ld_options.ldo_defbase = strdup(
openldap_ldap_global_options.ldo_defbase);
}
for(i=0; features[i].ldapaif_name != NULL; i++) {
info->ldapai_extensions[i] =
- ldap_strdup(features[i].ldapaif_name);
+ strdup(features[i].ldapaif_name);
}
info->ldapai_extensions[i] = NULL;
}
- info->ldapai_vendor_name = ldap_strdup(LDAP_VENDOR_NAME);
+ info->ldapai_vendor_name = strdup(LDAP_VENDOR_NAME);
info->ldapai_vendor_version = LDAP_VENDOR_VERSION;
return 0;
* we do.
*/
- * (char **) outvalue = ldap_strdup(lo->ldo_defhost);
+ * (char **) outvalue = strdup(lo->ldo_defhost);
return 0;
case LDAP_OPT_ERROR_NUMBER:
if( ld->ld_error == NULL ) {
* (char **) outvalue = NULL;
} else {
- * (char **) outvalue = ldap_strdup(ld->ld_error);
+ * (char **) outvalue = strdup(ld->ld_error);
}
return 0;
}
if(host != NULL) {
- lo->ldo_defhost = ldap_strdup(host);
+ lo->ldo_defhost = strdup(host);
return 0;
}
* must want global default returned
* to initial condition.
*/
- lo->ldo_defhost = ldap_strdup("localhost");
+ lo->ldo_defhost = strdup("localhost");
} else {
/*
* must want the session default
* updated to the current global default
*/
- lo->ldo_defhost = ldap_strdup(
+ lo->ldo_defhost = strdup(
openldap_ldap_global_options.ldo_defhost);
}
} return 0;
free(ld->ld_error);
}
- ld->ld_error = ldap_strdup(err);
+ ld->ld_error = strdup(err);
} return 0;
case LDAP_OPT_API_FEATURE_INFO:
#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */
#endif /* notyet */
- /* buffers for ldap_int_gethostbyname_a */
+ /* buffers for ldap_pvt_gethostbyname_a */
struct hostent he_buf;
int local_h_errno;
char *ha_buf=NULL;
/* 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 ( ( ldap_int_gethostbyname_a( host, &he_buf, &ha_buf,
+ if ( ( ldap_pvt_gethostbyname_a( host, &he_buf, &ha_buf,
&hp, &local_h_errno) < 0) || (hp==NULL))
{
#ifdef HAVE_WINSOCK
* this is necessary for kerberos to work right, since the official
* hostname is used as the kerberos instance.
*/
- if ((ldap_int_gethostbyaddr_a( (char *) &sin.sin_addr,
+ if ((ldap_pvt_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 ) {
- DO_RETURN( ldap_strdup( hp->h_name ));
+ DO_RETURN( strdup( hp->h_name ));
}
}
"NeedSocket" : ( lc->lconn_status ==
LDAP_CONNST_CONNECTING ) ? "Connecting" : "Connected" );
fprintf( stderr, " last used: %s\n",
- ldap_int_ctime( &lc->lconn_lastused, timebuf ));
+ ldap_pvt_ctime( &lc->lconn_lastused, timebuf ));
if ( !all ) {
break;
}
return( -1 );
}
- if (( srv->lsrv_host = ldap_strdup( tmpref )) == NULL ) {
+ if (( srv->lsrv_host = strdup( tmpref )) == NULL ) {
free( (char *)srv );
ber_free( ber, 1 );
ld->ld_errno = LDAP_NO_MEMORY;
prevsrv = srv;
/* copy in info. */
- if (( srv->lsrv_host = ldap_strdup( host )) == NULL ||
+ if (( srv->lsrv_host = strdup( host )) == NULL ||
( server_dn != NULL && ( srv->lsrv_dn =
- ldap_strdup( server_dn )) == NULL )) {
+ strdup( server_dn )) == NULL )) {
free_servers( srvlist );
srvlist = NULL;
break; /* exit loop & return */
return( NULLBER );
}
- filter = ldap_strdup( filter );
+ filter = strdup( filter );
err = put_filter( ber, filter );
free( filter );
return( -1 );
*next = '\0';
- tmp = ldap_strdup( str );
+ tmp = strdup( str );
if ( gotescape ) {
escape = 0;
for ( s = d = tmp; *s; s++ ) {
Debug( LDAP_DEBUG_TRACE, "put_filter: default\n", 0, 0,
0 );
next = strchr( str, '\0' );
- tmp = ldap_strdup( str );
+ tmp = strdup( str );
if ( strchr( tmp, '\\' ) != NULL ) {
escape = 0;
for ( s = d = tmp; *s; s++ ) {
#include "ldap-int.h"
char *
-(ldap_strdup)( const char *s )
+(ldap_pvt_strdup)( const char *s )
{
char *p;
-
- if ( (p = (char *) malloc( strlen( s ) + 1 )) == NULL )
+ int len;
+ len = strlen( s ) + 1;
+ if ( (p = (char *) malloc( len )) == NULL )
return( (char *)0 );
- strcpy( p, s );
+ memcpy( p, s, len );
return( p );
}
result = (char **) realloc( result,
sizeof(char *) * (num + 1) );
- result[num++] = (char *) ldap_strdup( buf );
+ result[num++] = (char *) strdup( buf );
}
if ( result == (char **) 0 )
return( NULL );
getline( buf, sizeof(buf), stdin, prompt2 );
if ( buf[0] == '\0' )
break;
- tmp.mod_type = ldap_strdup( buf );
+ tmp.mod_type = strdup( buf );
tmp.mod_values = get_list( prompt3 );
break;
case 't': /* copy ber's to given file */
- copyfname = ldap_strdup( optarg );
+ copyfname = strdup( optarg );
copyoptions = LBER_TO_FILE;
break;
case 'T': /* only output ber's to given file */
- copyfname = ldap_strdup( optarg );
+ copyfname = strdup( optarg );
copyoptions = (LBER_TO_FILE | LBER_TO_FILE_ONLY);
break;
gmttime = gtime( &t );
- timestr = ldap_int_ctime( &gmttime, timebuf );
+ timestr = ldap_pvt_ctime( &gmttime, timebuf );
timestr[ strlen( timestr ) - 1 ] = zone; /* replace trailing newline */
if ( dateonly ) {
* 2 )) == NULL ) {
return( ld->ld_errno = LDAP_NO_MEMORY );
}
- dns[0] = ldap_strdup( prefix );
+ dns[0] = strdup( prefix );
dns[1] = NULL;
} else {
dns = NULL;
if ( ld->ld_ufnprefix != NULL )
free( ld->ld_ufnprefix );
- ld->ld_ufnprefix = ldap_strdup( prefix );
+ ld->ld_ufnprefix = strdup( prefix );
}
int
}
/* make working copy of the remainder of the URL */
- if (( url = ldap_strdup( url )) == NULL ) {
+ if (( url = strdup( url )) == NULL ) {
ldap_free_urldesc( ludp );
return( LDAP_URL_ERR_MEM );
}
if ( ludp->lud_host != NULL || ludp->lud_port != 0 ) {
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
if (( srv = (LDAPServer *)calloc( 1, sizeof( LDAPServer )))
- == NULL || ( srv->lsrv_host = ldap_strdup( ludp->lud_host ==
+ == NULL || ( srv->lsrv_host = strdup( ludp->lud_host ==
NULL ? ld->ld_defhost : ludp->lud_host )) == NULL ) {
if ( srv != NULL ) {
free( srv );
#include "ldap-int.h"
+#if defined( LDAP_R_COMPILE )
+# include <ldap_pvt_thread.h>
+# if !defined( HAVE_REENTRANT_FUNCTIONS )
+# if !defined( HAVE_CTIME_R )
+# define LDAP_INT_CTIME_MUTEX 1
+# endif
+# if !defined( HAVE_GETHOSTBYNAME_R )
+# define LDAP_INT_GETHOSTBYNAME_MUTEX 1
+# endif
+# if !defined( HAVE_GETHOSTBYADDR_R )
+# define LDAP_INT_GETHOSTBYADDR_MUTEX 1
+# endif
+# endif /* defined( HAVE_REENTRANT_FUNCTIONS ) */
+
+#if defined( LDAP_INT_CTIME_MUTEX )
+static ldap_pvt_thread_mutex_t ldap_int_ctime_mutex;
+#endif
+#if defined( LDAP_INT_GETHOSTBYNAME_MUTEX )
+static ldap_pvt_thread_mutex_t ldap_int_gethostbyname_mutex;
+#endif
+#if defined( LDAP_INT_GETHOSTBYADDR_MUTEX )
+static ldap_pvt_thread_mutex_t ldap_int_gethostbyaddr_mutex;
+#endif
+#else /* LDAP_R_COMPILE */
+#undef HAVE_REENTRANT_FUNCTIONS
+#endif
+
+#if defined ( HAVE_STRSPN )
+#define int_strspn strspn
+#else
static int int_strspn( const char *str, const char *delim )
{
-#if defined( HAVE_STRSPN )
- return strspn( str, delim );
-#else
int pos;
const char *p=delim;
for( pos=0; (*str) ; pos++,str++) {
return pos;
}
return pos;
-#endif
}
+#endif
-static char *int_strpbrk( const char *str, const char *accept )
-{
#if defined( HAVE_STRPBRK )
- return strpbrk( str, accept );
+#define int_strpbrk strpbrk
#else
+static char *int_strpbrk( const char *str, const char *accept )
+{
const char *p;
for( ; (*str) ; str++ ) {
for( p=accept; (*p) ; p++) {
}
}
return NULL;
-#endif
}
+#endif
-char *ldap_int_strtok( char *str, const char *delim, char **pos )
+char *ldap_pvt_strtok( char *str, const char *delim, char **pos )
{
-#ifdef HAVE_STRTOK_R
+#if defined( HAVE_STRTOK_R ) || defined( HAVE_REENTRANT_FUNCTIONS )
return strtok_r(str, delim, pos);
#else
char *p;
#endif
}
-char *ldap_int_ctime( const time_t *tp, char *buf )
+char *ldap_pvt_ctime( const time_t *tp, char *buf )
{
-#if defined( HAVE_CTIME_R ) && defined( CTIME_R_NARGS )
+#if (defined( HAVE_CTIME_R ) || defined( HAVE_REENTRANT_FUNCTIONS)) \
+ && defined( CTIME_R_NARGS )
# if (CTIME_R_NARGS > 3) || (CTIME_R_NARGS < 2)
choke me! nargs should have 2 or 3
# elif CTIME_R_NARGS > 2
return ctime_r(tp,buf);
# endif
#else
+# if defined( LDAP_INT_CTIME_MUTEX )
+ ldap_pvt_thread_mutex_lock( &ldap_int_ctime_mutex );
+# endif
memcpy( buf, ctime(tp), 26 );
+# if defined( LDAP_INT_CTIME_MUTEX )
+ ldap_pvt_thread_mutex_unlock( &ldap_int_ctime_mutex );
+# endif
return buf;
#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;
-}
+static char *safe_realloc( char **buf, int len );
+static int copy_hostent( struct hostent *res, char **buf, struct hostent * src );
-int ldap_int_gethostbyname_a(
+int ldap_pvt_gethostbyname_a(
const char *name,
struct hostent *resbuf,
char **buf,
struct hostent **result,
int *herrno_ptr )
{
-#ifdef HAVE_GETHOSTBYNAME_R
+#if defined( HAVE_GETHOSTBYNAME_R ) || defined( HAVE_REENTRANT_FUNCTIONS )
+# define NEED_SAFE_REALLOC 1
int r=-1;
int buflen=BUFSTART;
*buf = NULL;
return r;
}
return -1;
+#elif defined( LDAP_INT_GETHOSTBYNAME_MUTEX )
+# define NEED_COPY_HOSTENT
+ struct hostent *he;
+ int retval;
+
+ ldap_pvt_thread_mutex_lock( &ldap_int_gethostbyname_mutex );
+
+ he = gethostbyname( name );
+
+ if (he==NULL) {
+ *herrno_ptr = h_errno;
+ retval = -1;
+ } else if (copy_hostent( resbuf, buf, he )<0) {
+ *herrno_ptr = -1;
+ retval = -1;
+ } else {
+ *result = resbuf;
+ retval = 0;
+ }
+
+ ldap_pvt_thread_mutex_unlock( &ldap_int_gethostbyname_mutex );
+
+ return retval;
#else
*result = gethostbyname( name );
#endif
}
-int ldap_int_gethostbyaddr_a(
+int ldap_pvt_gethostbyaddr_a(
const char *addr,
int len,
int type,
struct hostent **result,
int *herrno_ptr )
{
-#ifdef HAVE_GETHOSTBYADDR_R
+#if defined( HAVE_GETHOSTBYADDR_R ) || defined( HAVE_REENTRANT_FUNCTIONS )
+# undef NEED_SAFE_REALLOC
+# define NEED_SAFE_REALLOC
int r=-1;
int buflen=BUFSTART;
*buf = NULL;
return r;
}
return -1;
+#elif defined( LDAP_INT_GETHOSTBYADDR_MUTEX )
+# undef NEED_COPY_HOSTENT
+# define NEED_COPY_HOSTENT
+ struct hostent *he;
+ int retval;
+
+ ldap_pvt_thread_mutex_lock( &ldap_int_gethostbyaddr_mutex );
+
+ he = gethostbyaddr( addr, len, type );
+
+ if (he==NULL) {
+ *herrno_ptr = h_errno;
+ retval = -1;
+ } else if (copy_hostent( resbuf, buf, he )<0) {
+ *herrno_ptr = -1;
+ retval = -1;
+ } else {
+ *result = resbuf;
+ retval = 0;
+ }
+
+ ldap_pvt_thread_mutex_unlock( &ldap_int_gethostbyaddr_mutex );
+
+ return retval;
#else /* gethostbyaddr() */
*result = gethostbyaddr( addr, len, type );
return -1;
#endif
}
+/*
+ * ldap_pvt_init_utils() should be called before any other function.
+ */
+
+void ldap_pvt_init_utils( void )
+{
+ static int done=0;
+ if (done)
+ return;
+ done=1;
+#if defined( LDAP_INT_CTIME_MUTEX )
+ ldap_pvt_thread_mutex_init( &ldap_int_ctime_mutex, NULL );
+#endif
+#if defined( LDAP_INT_GETHOSTBYNAME_MUTEX )
+ ldap_pvt_thread_mutex_init( &ldap_int_gethostbyname_mutex, NULL );
+#endif
+#if defined( LDAP_INT_GETHOSTBYADDR_MUTEX )
+ ldap_pvt_thread_mutex_init( &ldap_int_gethostbyaddr_mutex, NULL );
+#endif
+#if defined( LDAP_R_COMPILE )
+ /* call other module init functions here... */
+#endif
+}
+
+#if defined( NEED_COPY_HOSTENT )
+# undef NEED_SAFE_REALLOC
+#define NEED_SAFE_REALLOC
+
+static char *cpy_aliases( char ***tgtio, char *buf, char **src )
+{
+ int len;
+ char **tgt=*tgtio;
+ for( ; (*src) ; src++ ) {
+ len = strlen( *src ) + 1;
+ memcpy( buf, *src, len );
+ *tgt++=buf;
+ buf+=len;
+ }
+ *tgtio=tgt;
+ return buf;
+}
+
+static char *cpy_addresses( char ***tgtio, char *buf, char **src, int len )
+{
+ char **tgt=*tgtio;
+ for( ; (*src) ; src++ ) {
+ memcpy( buf, *src, len );
+ *tgt++=buf;
+ buf+=len;
+ }
+ *tgtio=tgt;
+ return buf;
+}
+
+static int copy_hostent( struct hostent *res, char **buf, struct hostent * src )
+{
+ char **p;
+ char **tp;
+ char *tbuf;
+ int name_len;
+ int n_alias;
+ int total_alias_len;
+ int n_addr;
+ int total_addr_len;
+ int total_len;
+
+ /* calculate the size needed for the buffer */
+ name_len = strlen( src->h_name ) + 1;
+
+ for( n_alias=total_alias_len=0, p=src->h_aliases; (*p) ; p++ ) {
+ total_alias_len += strlen( *p ) + 1;
+ n_alias++;
+ }
+
+ for( n_addr=0, p=src->h_addr_list; (*p) ; p++ ) {
+ n_addr++;
+ }
+ total_addr_len = n_addr * src->h_length;
+
+ total_len = (n_alias + n_addr + 2) * sizeof( char * ) +
+ total_addr_len + total_alias_len + name_len;
+
+ if (safe_realloc( buf, total_len )) {
+ tp = (char **) *buf;
+ tbuf = *buf + (n_alias + n_addr + 2) * sizeof( char * );
+ memcpy( res, src, sizeof( struct hostent ) );
+ /* first the name... */
+ memcpy( tbuf, src->h_name, name_len );
+ res->h_name = tbuf; tbuf+=name_len;
+ /* now the aliases */
+ res->h_aliases = tp;
+ tbuf = cpy_aliases( &tp, tbuf, src->h_aliases );
+ *tp++=NULL;
+ /* finally the addresses */
+ res->h_addr_list = tp;
+ tbuf = cpy_addresses( &tp, tbuf, src->h_addr_list, src->h_length );
+ *tp++=NULL;
+ return 0;
+ }
+ return -1;
+}
+#endif
+
+#if defined( NEED_SAFE_REALLOC )
+static char *safe_realloc( char **buf, int len )
+{
+ char *tmpbuf;
+ tmpbuf = realloc( *buf, len );
+ if (tmpbuf) {
+ *buf=tmpbuf;
+ }
+ return tmpbuf;
+}
+#endif
+
+