Newer versions of glibc don't exporting the _res symbol, but instead replace it with a function call of a different name. This breaks binary compatibility for code using _res compiled and linked with older versions of glibc. (iphlpapi uses _res)
Mike
ChangeLog:
* dlopen libc to avoid problems with glibc's _res symbol, which only defined in older glibc versions
Index: configure.ac =================================================================== RCS file: /home/wine/wine/configure.ac,v retrieving revision 1.166 diff -u -r1.166 configure.ac --- configure.ac 16 Jul 2003 23:37:22 -0000 1.166 +++ configure.ac 21 Jul 2003 02:45:13 -0000 @@ -911,8 +911,8 @@ WINE_GET_SONAME(jack,jack_client_new) WINE_GET_SONAME(ssl,SSL_library_init) WINE_GET_SONAME(crypto,BIO_new_socket) + WINE_GET_SONAME(c, vsprintf) fi - dnl **** Check for functions **** Index: configure =================================================================== RCS file: /home/wine/wine/configure,v retrieving revision 1.441 diff -u -r1.441 configure --- configure 16 Jul 2003 23:37:22 -0000 1.441 +++ configure 21 Jul 2003 02:45:21 -0000 @@ -2246,7 +2246,8 @@ echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ - '' \ + ''\ + '#include <stdlib.h>' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ @@ -2260,8 +2261,8 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -$ac_declaration #include <stdlib.h> +$ac_declaration int main () { @@ -12977,8 +12978,72 @@ #define SONAME_LIBCRYPTO "$ac_cv_lib_soname_crypto" _ACEOF fi -fi +echo "$as_me:$LINENO: checking for -lc soname" >&5 +echo $ECHO_N "checking for -lc soname... $ECHO_C" >&6 +if test "${ac_cv_lib_soname_c+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_get_soname_save_LIBS=$LIBS +LIBS="-lc $LIBS" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char vsprintf (); +int +main () +{ +vsprintf (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_soname_c=`$ac_cv_path_LDD conftest$ac_exeext | grep libc\\.so | sed 's/^[ ]*\([^ ]*\)[ ]*=>.*$/\1/'` + if test "x$ac_cv_lib_soname_c" = "x" + then + ac_cv_lib_soname_c="libc.so" + fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_soname_c="libc.so" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + LIBS=$ac_get_soname_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_soname_c" >&5 +echo "${ECHO_T}$ac_cv_lib_soname_c" >&6 +if test "x$ac_cv_lib_soname_c" != xNONE +then +cat >>confdefs.h <<_ACEOF +#define SONAME_LIBC "$ac_cv_lib_soname_c" +_ACEOF +fi +fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works Index: include/config.h.in =================================================================== RCS file: /home/wine/wine/include/config.h.in,v retrieving revision 1.157 diff -u -r1.157 config.h.in --- include/config.h.in 20 Jun 2003 23:26:56 -0000 1.157 +++ include/config.h.in 21 Jul 2003 02:45:22 -0000 @@ -53,6 +53,9 @@ /* Define to 1 if you have the <cups/cups.h> header file. */ #undef HAVE_CUPS_CUPS_H +/* Define to the soname of the C library. */ +#undef SONAME_LIBC + /* Define to 1 if you have the <curses.h> header file. */ #undef HAVE_CURSES_H Index: dlls/iphlpapi/Makefile.in =================================================================== RCS file: /home/wine/wine/dlls/iphlpapi/Makefile.in,v retrieving revision 1.1 diff -u -r1.1 Makefile.in --- dlls/iphlpapi/Makefile.in 13 May 2003 03:32:20 -0000 1.1 +++ dlls/iphlpapi/Makefile.in 21 Jul 2003 02:45:22 -0000 @@ -7,6 +7,7 @@ LDDLLFLAGS = @LDDLLFLAGS@ SYMBOLFILE = $(MODULE).tmp.o +EXTRALIBS = @DLLIBS@ C_SRCS = \ ifenum.c \ Index: dlls/iphlpapi/iphlpapi_main.c =================================================================== RCS file: /home/wine/wine/dlls/iphlpapi/iphlpapi_main.c,v retrieving revision 1.4 diff -u -r1.4 iphlpapi_main.c --- dlls/iphlpapi/iphlpapi_main.c 23 Jun 2003 03:32:28 -0000 1.4 +++ dlls/iphlpapi/iphlpapi_main.c 21 Jul 2003 02:45:22 -0000 @@ -29,6 +29,8 @@ #include <arpa/nameser.h> #endif #include <resolv.h> +#include <wine/library.h> +#include <wine/port.h> #include "winbase.h" #include "iphlpapi.h" #include "ifenum.h" @@ -847,6 +849,35 @@ return getIPStats(pStats); } +/****************************************************************** + * IPHLPAPI_GetResolver + * + * Finds the location of the DNS server list for GetNetworkParams + */ +#ifdef __GLIBC__ +struct __res_state *IPHLPAPI_GetResolverState() +{ + static struct __res_state *p_res; + static struct __res_state *(*p__res_state)(); + static void *plibc; + + if( !plibc ) + { + plibc = wine_dlopen(SONAME_LIBC, RTLD_GLOBAL, NULL, 0 ); + p__res_state = wine_dlsym(plibc, "__res_state", NULL, 0 ); + p_res = wine_dlsym(plibc, "_res", NULL, 0 ); + } + + if( p__res_state ) + return p__res_state(); + + if( p_res ) + return p_res; + + return NULL; +} +#endif /* __GLIBC */ + /****************************************************************** * GetNetworkParams (IPHLPAPI.@) @@ -865,11 +896,22 @@ DWORD WINAPI GetNetworkParams(PFIXED_INFO pFixedInfo, PULONG pOutBufLen) { DWORD size; +#ifdef __GLIBC__ + struct __res_state *p_res = IPHLPAPI_GetResolverState(); +#endif + int res_nscount = 0; if (!pOutBufLen) return ERROR_INVALID_PARAMETER; - size = sizeof(FIXED_INFO) + min(1, (_res.nscount - 1) * +#ifdef __GLIBC__ + if( p_res ) + res_nscount = p_res->nscount; +#else + res_nscount = _res.nscount; +#endif + + size = sizeof(FIXED_INFO) + min(1, (res_nscount - 1) * sizeof(IP_ADDR_STRING)); if (!pFixedInfo || *pOutBufLen < size) { *pOutBufLen = size; @@ -881,14 +923,19 @@ GetComputerNameExA(ComputerNameDnsHostname, pFixedInfo->HostName, &size); size = sizeof(pFixedInfo->DomainName); GetComputerNameExA(ComputerNameDnsDomain, pFixedInfo->DomainName, &size); - if (_res.nscount > 0) { + if ( res_nscount > 0) { PIP_ADDR_STRING ptr; int i; - for (i = 0, ptr = &pFixedInfo->DnsServerList; i < _res.nscount; + for (i = 0, ptr = &pFixedInfo->DnsServerList; i < res_nscount; i++, ptr = ptr->Next) { +#ifdef __GLIBC__ + toIPAddressString(p_res->nsaddr_list[i].sin_addr.s_addr, + ptr->IpAddress.String); +#else toIPAddressString(_res.nsaddr_list[i].sin_addr.s_addr, ptr->IpAddress.String); +#endif ptr->Next = (PIP_ADDR_STRING)((PBYTE)ptr + sizeof(IP_ADDRESS_STRING)); } }