]> granicus.if.org Git - php/commitdiff
Merge chanes from head to improve DNS on OSX and allow usage of bind9 stuff with...
authorScott MacVicar <scottmac@php.net>
Tue, 11 Aug 2009 22:07:35 +0000 (22:07 +0000)
committerScott MacVicar <scottmac@php.net>
Tue, 11 Aug 2009 22:07:35 +0000 (22:07 +0000)
configure.in
ext/standard/basic_functions.c
ext/standard/config.m4
ext/standard/dns.c
ext/standard/php_dns.h

index 6296078fcd17cb3d262e9c038dc6f632318c4fcd..2889870b15b4dd14f2e206835a2931d9884034cf 100644 (file)
@@ -254,7 +254,6 @@ case $host_alias in
         CPPFLAGS="$CPPFLAGS -no-cpp-precomp"
       fi
     fi
-    AC_DEFINE(BIND_8_COMPAT, 1, [Enabling BIND8 compatibility for Panther])
     php_multiple_shlib_versions_ok=yes
     ;;
   *beos*)
index 342fe3aae3cb0659482285afd8b0cac6f5116457..fb230f757412e691eb8505e70188c25601fb9a50 100644 (file)
@@ -995,22 +995,20 @@ ZEND_BEGIN_ARG_INFO(arginfo_gethostname, 0)
 ZEND_END_ARG_INFO()
 #endif
 
-#if defined(PHP_WIN32) || (HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(NETWARE)))
+#if defined(PHP_WIN32) || (HAVE_DNS_SEARCH_FUNC && !(defined(__BEOS__) || defined(NETWARE)))
 ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_check_record, 0, 0, 1)
        ZEND_ARG_INFO(0, host)
        ZEND_ARG_INFO(0, type)
 ZEND_END_ARG_INFO()
 
-# if defined(PHP_WIN32) || HAVE_DNS_FUNCS
+# if defined(PHP_WIN32) || HAVE_FULL_DNS_FUNCS
 ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_get_record, 1, 0, 1)
        ZEND_ARG_INFO(0, hostname)
        ZEND_ARG_INFO(0, type)
        ZEND_ARG_INFO(1, authns) /* ARRAY_INFO(1, authns, 1) */
        ZEND_ARG_INFO(1, addtl)  /* ARRAY_INFO(1, addtl, 1) */
 ZEND_END_ARG_INFO()
-# endif
 
-# if defined(PHP_WIN32) || (HAVE_DN_SKIPNAME && HAVE_DN_EXPAND)
 ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_get_mx, 0, 0, 2)
        ZEND_ARG_INFO(0, hostname)
        ZEND_ARG_INFO(1, mxhosts) /* ARRAY_INFO(1, mxhosts, 1) */
@@ -1018,7 +1016,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_get_mx, 0, 0, 2)
 ZEND_END_ARG_INFO()
 # endif
 
-#endif /* defined(PHP_WIN32) || (HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(NETWARE))) */
+#endif /* defined(PHP_WIN32) || (HAVE_DNS_SEARCH_FUNC && !(defined(__BEOS__) || defined(NETWARE))) */
 /* }}} */
 
 /* {{{ exec.c */
@@ -3000,17 +2998,14 @@ const zend_function_entry basic_functions[] = { /* {{{ */
        PHP_FE(gethostname,                                                                                                     arginfo_gethostname)
 #endif
 
-#if defined(PHP_WIN32) || (HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(NETWARE)))
+#if defined(PHP_WIN32) || (HAVE_DNS_SEARCH_FUNC && !(defined(__BEOS__) || defined(NETWARE)))
 
        PHP_FE(dns_check_record,                                                                                                arginfo_dns_check_record)
        PHP_FALIAS(checkdnsrr,                  dns_check_record,                                               arginfo_dns_check_record)
 
-# if defined(PHP_WIN32) || (HAVE_DN_SKIPNAME && HAVE_DN_EXPAND)
+# if defined(PHP_WIN32) || HAVE_FULL_DNS_FUNCS
        PHP_FE(dns_get_mx,                                                                                                              arginfo_dns_get_mx)
        PHP_FALIAS(getmxrr,                             dns_get_mx,                                     arginfo_dns_get_mx)
-# endif
-
-# if defined(PHP_WIN32) || HAVE_DNS_FUNCS
        PHP_FE(dns_get_record,                                                                                                  arginfo_dns_get_record)
 # endif
 #endif
@@ -3639,8 +3634,8 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */
        php_register_url_stream_wrapper("ftp", &php_stream_ftp_wrapper TSRMLS_CC);
 #endif
 
-#if defined(PHP_WIN32) || (HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(NETWARE)))
-# if defined(PHP_WIN32) || HAVE_DNS_FUNCS
+#if defined(PHP_WIN32) || (HAVE_DNS_SEARCH_FUNC && !(defined(__BEOS__) || defined(NETWARE)))
+# if defined(PHP_WIN32) || HAVE_FULL_DNS_FUNCS
        PHP_MINIT(dns)(INIT_FUNC_ARGS_PASSTHRU);
 # endif
 #endif
index 8b793c619b49f32403be0637707de6b273b59fec..e0f04e0bd40ec9ad6bd6dd9f7c648bc3f7418e6a 100644 (file)
@@ -247,21 +247,18 @@ fi
 
 dnl
 dnl Detect library functions needed by php dns_xxx functions
-dnl ext/standard/php_dns.h will collect these in a single define: HAVE_DNS_FUNCS
+dnl ext/standard/php_dns.h will collect these in a single define: HAVE_FULL_DNS_FUNCS
 dnl
-PHP_CHECK_FUNC(res_nmkquery, resolv, bind, socket)
-PHP_CHECK_FUNC(res_nsend, resolv, bind, socket)
-PHP_CHECK_FUNC(res_search, resolv, bind, socket)
+PHP_CHECK_FUNC(res_nsearch, resolv, bind, socket)
+PHP_CHECK_FUNC(dns_search, resolv, bind, socket)
 PHP_CHECK_FUNC(dn_expand, resolv, bind, socket)
 PHP_CHECK_FUNC(dn_skipname, resolv, bind, socket)
 
 dnl
-dnl These are old deprecated functions, a single define of HAVE_DEPRECATED_DNS_FUNCS
-dnl will be set in ext/standard/php_dns.h
+dnl These are old deprecated functions
 dnl
 
-PHP_CHECK_FUNC(res_mkquery, resolv, bind, socket)
-PHP_CHECK_FUNC(res_send, resolv, bind, socket)
+PHP_CHECK_FUNC(res_search, resolv, bind, socket)
 
 dnl
 dnl Check if atof() accepts NAN
index 637c156e0722234a607311370ffb195d46fee2b2..dd7a8b15b0b197fab34621df317cac1d55212f9a 100644 (file)
 #if HAVE_ARPA_NAMESER_H
 #include <arpa/nameser.h>
 #endif
+#if HAVE_ARPA_NAMESER_COMPAT_H
+#include <arpa/nameser_compat.h>
+#endif
 #if HAVE_RESOLV_H
 #include <resolv.h>
 #endif
+#ifdef HAVE_DNS_H
+#include <dns.h>
+#endif
 #endif
 
 /* Borrowed from SYS/SOCKET.H */
@@ -258,7 +264,7 @@ static char *php_gethostbyname(char *name)
 }
 /* }}} */
 
-#if HAVE_DNS_FUNCS || defined(PHP_WIN32)
+#if HAVE_FULL_DNS_FUNCS || defined(PHP_WIN32)
 # define PHP_DNS_NUM_TYPES     12      /* Number of DNS Types Supported by PHP currently */
 
 # define PHP_DNS_A      0x00000001
@@ -275,10 +281,51 @@ static char *php_gethostbyname(char *name)
 # define PHP_DNS_AAAA   0x08000000
 # define PHP_DNS_ANY    0x10000000
 # define PHP_DNS_ALL    (PHP_DNS_A|PHP_DNS_NS|PHP_DNS_CNAME|PHP_DNS_SOA|PHP_DNS_PTR|PHP_DNS_HINFO|PHP_DNS_MX|PHP_DNS_TXT|PHP_DNS_A6|PHP_DNS_SRV|PHP_DNS_NAPTR|PHP_DNS_AAAA)
-#endif /* HAVE_DNS_FUNCS || defined(PHP_WIN32) */
+#endif /* HAVE_FULL_DNS_FUNCS || defined(PHP_WIN32) */
 
 /* Note: These functions are defined in ext/standard/dns_win32.c for Windows! */
-#if !defined(PHP_WIN32) && (HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(NETWARE)))
+#if !defined(PHP_WIN32) && (HAVE_DNS_SEARCH_FUNC && !(defined(__BEOS__) || defined(NETWARE)))
+  
+#ifndef HFIXEDSZ
+#define HFIXEDSZ        12      /* fixed data in header <arpa/nameser.h> */
+#endif /* HFIXEDSZ */
+
+#ifndef QFIXEDSZ
+#define QFIXEDSZ        4       /* fixed data in query <arpa/nameser.h> */
+#endif /* QFIXEDSZ */
+
+#undef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN  1024
+
+#ifndef MAXRESOURCERECORDS
+#define MAXRESOURCERECORDS     64
+#endif /* MAXRESOURCERECORDS */
+
+typedef union {
+       HEADER qb1;
+       u_char qb2[65536];
+} querybuf;
+
+/* just a hack to free resources allocated by glibc in __res_nsend()
+ * See also:
+ *   res_thread_freeres() in glibc/resolv/res_init.c
+ *   __libc_res_nsend()   in resolv/res_send.c
+ * */
+
+#if defined(__GLIBC__) && !defined(HAVE_DEPRECATED_DNS_FUNCS)
+#define php_dns_free_res(__res__) _php_dns_free_res(__res__)
+static void _php_dns_free_res(struct __res_state res) { /* {{{ */
+       int ns;
+       for (ns = 0; ns < MAXNS; ns++) {
+               if (res._u._ext.nsaddrs[ns] != NULL) {
+                       free (res._u._ext.nsaddrs[ns]);
+                       res._u._ext.nsaddrs[ns] = NULL;
+               }
+       }
+} /* }}} */
+#else
+#define php_dns_free_res(__res__)
+#endif
 
 /* {{{ proto bool dns_check_record(string host [, string type])
    Check DNS records corresponding to a given Internet host name or IP address */
@@ -291,6 +338,14 @@ PHP_FUNCTION(dns_check_record)
        char *hostname, *rectype = NULL;
        int hostname_len, rectype_len = 0;
        int type = T_MX, i;
+#if defined(HAVE_DNS_SEARCH)
+       struct sockaddr_storage from;
+       uint32_t fromsize = sizeof(from);
+       dns_handle_t handle;
+#elif defined(HAVE_RES_NSEARCH)
+       struct __res_state state;
+       struct __res_state *handle = &state;
+#endif
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &hostname, &hostname_len, &rectype, &rectype_len) == FAILURE) {
                return;
@@ -320,58 +375,32 @@ PHP_FUNCTION(dns_check_record)
                }
        }
 
-       i = res_search(hostname, C_IN, type, ans, sizeof(ans));
+#if defined(HAVE_DNS_SEARCH)
+       handle = dns_open(NULL);
+       if (handle == NULL) {
+               RETURN_FALSE;
+       }
+#elif defined(HAVE_RES_NSEARCH)
+    memset(&state, 0, sizeof(state));
+    if (res_ninit(handle)) {
+                       RETURN_FALSE;
+       }
+#else
+       res_init();
+#endif
+
+       RETVAL_TRUE;
+       i = php_dns_search(handle, hostname, C_IN, type, ans, sizeof(ans));
 
        if (i < 0) {
-               RETURN_FALSE;
+               RETVAL_FALSE;
        }
 
-       RETURN_TRUE;
+       php_dns_free_handle(handle);
 }
 /* }}} */
 
-#if HAVE_DNS_FUNCS
-
-#ifndef HFIXEDSZ
-#define HFIXEDSZ        12      /* fixed data in header <arpa/nameser.h> */
-#endif /* HFIXEDSZ */
-
-#ifndef QFIXEDSZ
-#define QFIXEDSZ        4       /* fixed data in query <arpa/nameser.h> */
-#endif /* QFIXEDSZ */
-
-#undef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN  1024
-
-#ifndef MAXRESOURCERECORDS
-#define MAXRESOURCERECORDS     64
-#endif /* MAXRESOURCERECORDS */
-
-typedef union {
-       HEADER qb1;
-       u_char qb2[65536];
-} querybuf;
-
-/* just a hack to free resources allocated by glibc in __res_nsend()
- * See also:
- *   res_thread_freeres() in glibc/resolv/res_init.c
- *   __libc_res_nsend()   in resolv/res_send.c
- * */
-
-#if defined(__GLIBC__) && !defined(HAVE_DEPRECATED_DNS_FUNCS)
-#define php_dns_free_res(__res__) _php_dns_free_res(__res__)
-static void _php_dns_free_res(struct __res_state res) { /* {{{ */
-       int ns;
-       for (ns = 0; ns < MAXNS; ns++) {
-               if (res._u._ext.nsaddrs[ns] != NULL) {
-                       free (res._u._ext.nsaddrs[ns]);
-                       res._u._ext.nsaddrs[ns] = NULL;
-               }
-       }
-} /* }}} */
-#else
-#define php_dns_free_res(__res__)
-#endif
+#if HAVE_FULL_DNS_FUNCS
 
 /* {{{ php_parserr */
 static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int store, zval **subarray)
@@ -670,11 +699,16 @@ PHP_FUNCTION(dns_get_record)
        zval *authns = NULL, *addtl = NULL;
        int addtl_recs = 0;
        int type_to_fetch;
-#if !defined(HAVE_DEPRECATED_DNS_FUNCS)
-       struct __res_state res;
+#if defined(HAVE_DNS_SEARCH)
+       struct sockaddr_storage from;
+       uint32_t fromsize = sizeof(from);
+       dns_handle_t handle;
+#elif defined(HAVE_RES_NSEARCH)
+       struct __res_state state;
+       struct __res_state *handle = &state;
 #endif
        HEADER *hp;
-       querybuf buf, answer;
+       querybuf answer;
        u_char *cp = NULL, *end = NULL;
        int n, qd, an, ns = 0, ar = 0;
        int type, first_query = 1, store_results = 1;
@@ -757,29 +791,32 @@ PHP_FUNCTION(dns_get_record)
                                type_to_fetch = DNS_T_ANY;
                                break;
                }
+
                if (type_to_fetch) {
-#if defined(HAVE_DEPRECATED_DNS_FUNCS)
-                       res_init();
-#else
-                       memset(&res, 0, sizeof(res));
-                       res_ninit(&res);
-                       res.retrans = 5;
-                       res.options &= ~RES_DEFNAMES;
-#endif
-                       n = res_nmkquery(&res, QUERY, hostname, C_IN, type_to_fetch, NULL, 0, NULL, buf.qb2, sizeof buf);
-                       if (n<0) {
-                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "res_nmkquery() failed");
-                               zval_dtor(return_value);
-                               res_nclose(&res);
-                               php_dns_free_res(res);
+#if defined(HAVE_DNS_SEARCH)
+                       handle = dns_open(NULL);
+                       if (handle == NULL) {
                                RETURN_FALSE;
                        }
-                       n = res_nsend(&res, buf.qb2, n, answer.qb2, sizeof answer);
-                       if (n<0) {
-                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "res_nsend() failed");
+#elif defined(HAVE_RES_NSEARCH)
+                   memset(&state, 0, sizeof(state));
+                   if (res_ninit(handle)) {
+                                       RETURN_FALSE;
+                       }
+#else
+                       res_init();
+#endif
+
+                       n = php_dns_search(handle, hostname, C_IN, type_to_fetch, answer.qb2, sizeof answer);
+
+                       if (n < 0) {
+                               if (php_dns_errno(handle) == NO_DATA) {
+                                       php_dns_free_handle(handle);
+                                       continue;
+                               }
+
+                               php_dns_free_handle(handle);
                                zval_dtor(return_value);
-                               res_nclose(&res);
-                               php_dns_free_res(res);
                                RETURN_FALSE;
                        }
 
@@ -797,8 +834,7 @@ PHP_FUNCTION(dns_get_record)
                                if (n < 0) {
                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse DNS data received");
                                        zval_dtor(return_value);
-                                       res_nclose(&res);
-                                       php_dns_free_res(res);
+                                       php_dns_free_handle(handle);
                                        RETURN_FALSE;
                                }
                                cp += n + QFIXEDSZ;
@@ -813,41 +849,38 @@ PHP_FUNCTION(dns_get_record)
                                        add_next_index_zval(return_value, retval);
                                }
                        }
-                       res_nclose(&res);
-                       php_dns_free_res(res);
-               }
-       }
 
-       if (authns || addtl) {
-               /* List of Authoritative Name Servers
-                * Process when only requesting addtl so that we can skip through the section
-                */
-               while (ns-- > 0 && cp && cp < end) {
-                       zval *retval = NULL;
+                       if (authns || addtl) {
+                               /* List of Authoritative Name Servers
+                                * Process when only requesting addtl so that we can skip through the section
+                                */
+                               while (ns-- > 0 && cp && cp < end) {
+                                       zval *retval = NULL;
 
-                       cp = php_parserr(cp, &answer, DNS_T_ANY, authns != NULL, &retval);
-                       if (retval != NULL) {
-                               add_next_index_zval(authns, retval);
+                                       cp = php_parserr(cp, &answer, DNS_T_ANY, authns != NULL, &retval);
+                                       if (retval != NULL) {
+                                               add_next_index_zval(authns, retval);
+                                       }
+                               }
                        }
-               }
-       }
 
-       if (addtl_recs && addtl) {
-               /* Additional records associated with authoritative name servers */
-               while (ar-- > 0 && cp && cp < end) {
-                       zval *retval = NULL;
+                       if (addtl_recs && addtl) {
+                               /* Additional records associated with authoritative name servers */
+                               while (ar-- > 0 && cp && cp < end) {
+                                       zval *retval = NULL;
 
-                       cp = php_parserr(cp, &answer, DNS_T_ANY, 1, &retval);
-                       if (retval != NULL) {
-                               add_next_index_zval(addtl, retval);
+                                       cp = php_parserr(cp, &answer, DNS_T_ANY, 1, &retval);
+                                       if (retval != NULL) {
+                                               add_next_index_zval(addtl, retval);
+                                       }
+                               }
                        }
+                       php_dns_free_handle(handle);
                }
        }
 }
 /* }}} */
-#endif /* HAVE_DNS_FUNCS */
 
-#if HAVE_DN_SKIPNAME && HAVE_DN_EXPAND
 /* {{{ proto bool dns_get_mx(string hostname, array mxhosts [, array weight])
    Get MX records corresponding to a given Internet host name */
 PHP_FUNCTION(dns_get_mx)
@@ -862,6 +895,14 @@ PHP_FUNCTION(dns_get_mx)
        HEADER *hp;
        u_char *cp, *end;
        int i;
+#if defined(HAVE_DNS_SEARCH)
+       struct sockaddr_storage from;
+       uint32_t fromsize = sizeof(from);
+       dns_handle_t handle;
+#elif defined(HAVE_RES_NSEARCH)
+       struct __res_state state;
+       struct __res_state *handle = &state;
+#endif
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|z", &hostname, &hostname_len, &mx_list, &weight_list) == FAILURE) {
                return;
@@ -875,7 +916,21 @@ PHP_FUNCTION(dns_get_mx)
                array_init(weight_list);
        }
 
-       i = res_search(hostname, C_IN, DNS_T_MX, (u_char *)&ans, sizeof(ans));
+#if defined(HAVE_DNS_SEARCH)
+       handle = dns_open(NULL);
+       if (handle == NULL) {
+               RETURN_FALSE;
+       }
+#elif defined(HAVE_RES_NSEARCH)
+    memset(&state, 0, sizeof(state));
+    if (res_ninit(handle)) {
+                       RETURN_FALSE;
+       }
+#else
+       res_init();
+#endif
+
+       i = php_dns_search(handle, hostname, C_IN, DNS_T_MX, (u_char *)&ans, sizeof(ans));
        if (i < 0) {
                RETURN_FALSE;
        }
@@ -887,12 +942,14 @@ PHP_FUNCTION(dns_get_mx)
        end = (u_char *)&ans +i;
        for (qdc = ntohs((unsigned short)hp->qdcount); qdc--; cp += i + QFIXEDSZ) {
                if ((i = dn_skipname(cp, end)) < 0 ) {
+                       php_dns_free_handle(handle);
                        RETURN_FALSE;
                }
        }
        count = ntohs((unsigned short)hp->ancount);
        while (--count >= 0 && cp < end) {
                if ((i = dn_skipname(cp, end)) < 0 ) {
+                       php_dns_free_handle(handle);
                        RETURN_FALSE;
                }
                cp += i;
@@ -905,6 +962,7 @@ PHP_FUNCTION(dns_get_mx)
                }
                GETSHORT(weight, cp);
                if ((i = dn_expand(ans, end, cp, buf, sizeof(buf)-1)) < 0) {
+                       php_dns_free_handle(handle);
                        RETURN_FALSE;
                }
                cp += i;
@@ -913,13 +971,14 @@ PHP_FUNCTION(dns_get_mx)
                        add_next_index_long(weight_list, weight);
                }
        }
+       php_dns_free_handle(handle);
        RETURN_TRUE;
 }
 /* }}} */
-#endif /* HAVE_DN_SKIPNAME && HAVE_DN_EXPAND */
-#endif /* !defined(PHP_WIN32) && (HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(NETWARE))) */
+#endif /* HAVE_FULL_DNS_FUNCS */
+#endif /* !defined(PHP_WIN32) && (HAVE_DNS_SEARCH_FUNC && !(defined(__BEOS__) || defined(NETWARE))) */
 
-#if HAVE_DNS_FUNCS || defined(PHP_WIN32)
+#if HAVE_FULL_DNS_FUNCS || defined(PHP_WIN32)
 PHP_MINIT_FUNCTION(dns) {
        REGISTER_LONG_CONSTANT("DNS_A",     PHP_DNS_A,     CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("DNS_NS",    PHP_DNS_NS,    CONST_CS | CONST_PERSISTENT);
@@ -937,7 +996,7 @@ PHP_MINIT_FUNCTION(dns) {
        REGISTER_LONG_CONSTANT("DNS_ALL",   PHP_DNS_ALL,   CONST_CS | CONST_PERSISTENT);
        return SUCCESS;
 }
-#endif /* HAVE_DNS_FUNCS */
+#endif /* HAVE_FULL_DNS_FUNCS */
 
 /*
  * Local variables:
index 8790d2b4ac3dc233b37f93b89ab235886bb2d1f7..44963717276e42415830590de8d1436c07e61b6d 100644 (file)
 #ifndef PHP_DNS_H
 #define PHP_DNS_H
 
-#if HAVE_RES_MKQUERY && !defined(HAVE_RES_NMKQUERY) && HAVE_RES_SEND && !defined(HAVE_RES_NSEND)
-#define HAVE_DEPRECATED_DNS_FUNCS 1
+#if defined(HAVE_DNS_SEARCH)
+#define php_dns_search(res, dname, class, type, answer, anslen) \
+       ((int)dns_search(res, dname, class, type, answer, anslen, (struct sockaddr *)&from, &fromsize))
+#define php_dns_free_handle(res) \
+               dns_free(res)
+#define php_dns_errno(_res) \
+                       (NO_DATA)
+
+#elif defined(HAVE_RES_NSEARCH)
+#define php_dns_search(res, dname, class, type, answer, anslen) \
+                       res_nsearch(res, dname, class, type, answer, anslen);
+#define php_dns_free_handle(res) \
+                       res_nclose(res); \
+                       php_dns_free_res(*res)
+#define php_dns_errno(res) \
+                       (res->res_h_errno)
+
+#elif defined(HAVE_RES_SEARCH)
+#define php_dns_search(res, dname, class, type, answer, anslen) \
+                       res_search(dname, class, type, answer, anslen)
+#define php_dns_free_handle(res) /* noop */
+#define php_dns_errno(res) \
+                       (_res.res_h_errno)
+
 #endif
 
-#if HAVE_DEPRECATED_DNS_FUNCS
-#define res_nmkquery(res, op, dname, class, type, data, datalen, newrr, buf, buflen) \
-       res_mkquery(op, dname, class, type, data, datalen, newrr, buf, buflen)
-#define res_nsend(res, msg, msglen, answer, anslen) \
-       res_send(msg, msglen, answer, anslen);
-#define res_nclose(res) /* noop */
+#if defined(HAVE_DNS_SEARCH) || defined(HAVE_RES_NSEARCH) || defined(HAVE_RES_SEARCH)
+#define HAVE_DNS_SEARCH_FUNC 1
 #endif
 
-#if ((HAVE_RES_NMKQUERY && HAVE_RES_NSEND) || HAVE_DEPRECATED_DNS_FUNCS) && HAVE_DN_EXPAND && HAVE_DN_SKIPNAME
-#define HAVE_DNS_FUNCS 1
+#if HAVE_DNS_SEARCH_FUNC && HAVE_DN_EXPAND && HAVE_DN_SKIPNAME
+#define HAVE_FULL_DNS_FUNCS 1
 #endif
 
 PHP_FUNCTION(gethostbyaddr);
@@ -47,18 +65,16 @@ PHP_FUNCTION(gethostbynamel);
 PHP_FUNCTION(gethostname);
 #endif
 
-#if defined(PHP_WIN32) || (HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(NETWARE)))
+#if defined(PHP_WIN32) || (HAVE_DNS_SEARCH_FUNC && !(defined(__BEOS__) || defined(NETWARE)))
 PHP_FUNCTION(dns_check_record);
-# if defined(PHP_WIN32) || (HAVE_DN_SKIPNAME && HAVE_DN_EXPAND)
-PHP_FUNCTION(dns_get_mx);
-# endif
 
-#if defined(PHP_WIN32) || HAVE_DNS_FUNCS
+# if defined(PHP_WIN32) || HAVE_FULL_DNS_FUNCS
+PHP_FUNCTION(dns_get_mx);
 PHP_FUNCTION(dns_get_record);
 PHP_MINIT_FUNCTION(dns);
 # endif
 
-#endif /* defined(PHP_WIN32) || (HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(NETWARE))) */
+#endif /* defined(PHP_WIN32) || (HAVE_DNS_SEARCH_FUNC && !(defined(__BEOS__) || defined(NETWARE))) */
 
 #ifndef INT16SZ
 #define INT16SZ                2