From 68257d0f3971a7891d509df7472fb657b524f1f2 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Tue, 3 Aug 2021 23:53:36 -0500 Subject: [PATCH] ws2_32: Move gethostbyname() to the Unix library. Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- dlls/ws2_32/protocol.c | 132 ++++++----------------------------- dlls/ws2_32/unixlib.c | 55 +++++++++++++++ dlls/ws2_32/ws2_32_private.h | 1 + 3 files changed, 77 insertions(+), 111 deletions(-) diff --git a/dlls/ws2_32/protocol.c b/dlls/ws2_32/protocol.c index 2a7200ee137..c65e6b9674e 100644 --- a/dlls/ws2_32/protocol.c +++ b/dlls/ws2_32/protocol.c @@ -53,33 +53,6 @@ static const int ws_eai_map[][2] = { 0, 0 } }; -static const int ws_af_map[][2] = -{ - MAP_OPTION( AF_UNSPEC ), - MAP_OPTION( AF_INET ), - MAP_OPTION( AF_INET6 ), -#ifdef HAS_IPX - MAP_OPTION( AF_IPX ), -#endif -#ifdef AF_IRDA - MAP_OPTION( AF_IRDA ), -#endif - {FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO}, -}; - -static int convert_af_u2w( int family ) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(ws_af_map); i++) - { - if (ws_af_map[i][1] == family) - return ws_af_map[i][0]; - } - FIXME( "unhandled UNIX address family %d\n", family ); - return -1; -} - int convert_eai_u2w( int unixret ) { int i; @@ -706,24 +679,6 @@ int WINAPI GetNameInfoW( const SOCKADDR *addr, WS_socklen_t addr_len, WCHAR *hos } -static UINT host_errno_from_unix( int err ) -{ - WARN( "%d\n", err ); - - switch (err) - { - case HOST_NOT_FOUND: return WSAHOST_NOT_FOUND; - case TRY_AGAIN: return WSATRY_AGAIN; - case NO_RECOVERY: return WSANO_RECOVERY; - case NO_DATA: return WSANO_DATA; - case ENOBUFS: return WSAENOBUFS; - case 0: return 0; - default: - WARN( "Unknown h_errno %d!\n", err ); - return WSAEOPNOTSUPP; - } -} - static struct WS_hostent *get_hostent_buffer( unsigned int size ) { struct per_thread_data *data = get_per_thread_data(); @@ -791,37 +746,6 @@ static struct WS_hostent *create_hostent( char *name, int alias_count, int alias return p_to; } -static struct WS_hostent *hostent_from_unix( const struct hostent *p_he ) -{ - int i, addresses = 0, alias_size = 0; - struct WS_hostent *p_to; - char *p; - - for (i = 0; p_he->h_aliases[i]; i++) - alias_size += strlen( p_he->h_aliases[i] ) + 1; - while (p_he->h_addr_list[addresses]) - addresses++; - - p_to = create_hostent( p_he->h_name, i + 1, alias_size, addresses + 1, p_he->h_length ); - - if (!p_to) return NULL; - p_to->h_addrtype = convert_af_u2w( p_he->h_addrtype ); - p_to->h_length = p_he->h_length; - - for (i = 0, p = p_to->h_addr_list[0]; p_he->h_addr_list[i]; i++, p += p_to->h_length) - memcpy( p, p_he->h_addr_list[i], p_to->h_length ); - - /* Fill the aliases after the IP data */ - for (i = 0; p_he->h_aliases[i]; i++) - { - p_to->h_aliases[i] = p; - strcpy( p, p_he->h_aliases[i] ); - p += strlen(p) + 1; - } - - return p_to; -} - /*********************************************************************** * gethostbyaddr (ws2_32.51) @@ -987,16 +911,11 @@ cleanup: */ struct WS_hostent * WINAPI WS_gethostbyname( const char *name ) { - struct WS_hostent *retval = NULL; - struct hostent *host; -#ifdef HAVE_LINUX_GETHOSTBYNAME_R_6 - char *extrabuf; - int ebufsize = 1024; - struct hostent hostentry; - int locerr = ENOBUFS; -#endif + struct WS_hostent *host = NULL; char hostname[100]; + TRACE( "%s\n", debugstr_a(name) ); + if (!num_startup) { SetLastError( WSANOTINITIALISED ); @@ -1006,7 +925,7 @@ struct WS_hostent * WINAPI WS_gethostbyname( const char *name ) if (gethostname( hostname, 100 ) == -1) { SetLastError( WSAENOBUFS ); - return retval; + return NULL; } if (!name || !name[0]) @@ -1015,45 +934,36 @@ struct WS_hostent * WINAPI WS_gethostbyname( const char *name ) /* If the hostname of the local machine is requested then return the * complete list of local IP addresses */ if (!strcmp( name, hostname )) - retval = get_local_ips( hostname ); + host = get_local_ips( hostname ); /* If any other hostname was requested (or the routing table lookup failed) * then return the IP found by the host OS */ - if (!retval) + if (!host) { -#ifdef HAVE_LINUX_GETHOSTBYNAME_R_6 - host = NULL; - extrabuf = HeapAlloc( GetProcessHeap(), 0, ebufsize ); - while (extrabuf) + unsigned int size = 1024; + int ret; + + if (!(host = get_hostent_buffer( size ))) + return NULL; + + while ((ret = unix_funcs->gethostbyname( name, host, &size )) == ERROR_INSUFFICIENT_BUFFER) { - int res = gethostbyname_r( name, &hostentry, extrabuf, ebufsize, &host, &locerr ); - if (res != ERANGE) break; - ebufsize *= 2; - extrabuf = HeapReAlloc( GetProcessHeap(), 0, extrabuf, ebufsize ); + if (!(host = get_hostent_buffer( size ))) + return NULL; } - if (!host) SetLastError( (locerr < 0) ? sock_get_error( errno ) : host_errno_from_unix( locerr ) ); -#else - EnterCriticalSection( &csWSgetXXXbyYYY ); - host = gethostbyname( name ); - if (!host) SetLastError( (h_errno < 0) ? sock_get_error( errno ) : host_errno_from_unix( h_errno ) ); -#endif - if (host) retval = hostent_from_unix( host ); -#ifdef HAVE_LINUX_GETHOSTBYNAME_R_6 - HeapFree( GetProcessHeap(), 0, extrabuf ); -#else - LeaveCriticalSection( &csWSgetXXXbyYYY ); -#endif + + SetLastError( ret ); + return ret ? NULL : host; } - if (retval && retval->h_addr_list[0][0] == 127 && strcmp( name, "localhost" )) + if (host && host->h_addr_list[0][0] == 127 && strcmp( name, "localhost" )) { /* hostname != "localhost" but has loopback address. replace by our * special address.*/ - memcpy( retval->h_addr_list[0], magic_loopback_addr, 4 ); + memcpy( host->h_addr_list[0], magic_loopback_addr, 4 ); } - TRACE( "%s ret %p\n", debugstr_a(name), retval ); - return retval; + return host; } diff --git a/dlls/ws2_32/unixlib.c b/dlls/ws2_32/unixlib.c index 2423ef5aa2e..2a5fcd1b60d 100644 --- a/dlls/ws2_32/unixlib.c +++ b/dlls/ws2_32/unixlib.c @@ -735,10 +735,65 @@ static int CDECL unix_gethostbyaddr( const void *addr, int len, int family, } +#ifdef HAVE_LINUX_GETHOSTBYNAME_R_6 +static int CDECL unix_gethostbyname( const char *name, struct WS_hostent *const host, unsigned int *size ) +{ + struct hostent stack_host, *unix_host; + char *unix_buffer, *new_buffer; + int unix_size = 1024; + int locerr; + int ret; + + if (!(unix_buffer = malloc( unix_size ))) + return WSAENOBUFS; + + while (gethostbyname_r( name, &stack_host, unix_buffer, unix_size, &unix_host, &locerr ) == ERANGE) + { + unix_size *= 2; + if (!(new_buffer = realloc( unix_buffer, unix_size ))) + { + free( unix_buffer ); + return WSAENOBUFS; + } + unix_buffer = new_buffer; + } + + if (!unix_host) + return (locerr < 0 ? errno_from_unix( errno ) : host_errno_from_unix( locerr )); + + ret = hostent_from_unix( unix_host, host, size ); + + free( unix_buffer ); + return ret; +} +#else +static int CDECL unix_gethostbyname( const char *name, struct WS_hostent *const host, unsigned int *size ) +{ + struct hostent *unix_host; + int ret; + + pthread_mutex_lock( &host_mutex ); + + if (!(unix_host = gethostbyname( name ))) + { + ret = (h_errno < 0 ? errno_from_unix( errno ) : host_errno_from_unix( h_errno )); + pthread_mutex_unlock( &host_mutex ); + return ret; + } + + ret = hostent_from_unix( unix_host, host, size ); + + pthread_mutex_unlock( &host_mutex ); + return ret; +} +#endif + + static const struct unix_funcs funcs = { unix_getaddrinfo, unix_gethostbyaddr, + unix_gethostbyname, }; NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out ) diff --git a/dlls/ws2_32/ws2_32_private.h b/dlls/ws2_32/ws2_32_private.h index f9224306a7c..38454e1a9ba 100644 --- a/dlls/ws2_32/ws2_32_private.h +++ b/dlls/ws2_32/ws2_32_private.h @@ -202,6 +202,7 @@ struct unix_funcs struct WS(addrinfo) *info, unsigned int *size ); int (CDECL *gethostbyaddr)( const void *addr, int len, int family, struct WS(hostent) *host, unsigned int *size ); + int (CDECL *gethostbyname)( const char *name, struct WS(hostent) *host, unsigned int *size ); }; extern const struct unix_funcs *unix_funcs;