Attached is dns_getrecord.patch, previously known as getanyrr.patch for
introducing a new function.  I've made the changes suggested including:

* Rename function

* Add whitespace in argument list of functions called

* Change parameter two from string to int, use defined constants instead
DNS_ANY DNS_A DNS_MX DNS_NS DNS_CNAME DNS_PTR DNS_TXT DNS_SOA DNS_HINFO

* Caught the fact I wasn't checking for a user supplied type of "HINFO"
*whoops*

What I unfortunately don't know how to do is update the ./configure
process to check for existance of: res_nmkquery, res_nsend, and dn_expand.
 At the moment all I can do is rely on the fact that libresolv *is* being
tested for, and that it should contain these functions.  If someone could
point me to documentation on updating that process I'd appreciate it,
otherwise I'll go back to searching for it.

-Pollita


cvs -z3 -q diff basic_functions.c dns.c dns.h (in directory S:\php4-HEAD\ext\standard)
Index: basic_functions.c
===================================================================
RCS file: /repository/php4/ext/standard/basic_functions.c,v
retrieving revision 1.543
diff -u -r1.543 basic_functions.c
--- basic_functions.c   8 Nov 2002 15:49:32 -0000       1.543
+++ basic_functions.c   17 Nov 2002 00:15:19 -0000
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: basic_functions.c,v 1.543 2002/11/08 15:49:32 sterling Exp $ */
+/* $Id: basic_functions.c,v 1.543 2002/11/16 13:18:21 pollita Exp $ */
 
 #include "php.h"
 #include "php_streams.h"
@@ -440,6 +440,7 @@
 
 #if HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(PHP_WIN32) || defined(NETWARE))
        PHP_FE(checkdnsrr,                                                             
                                                 NULL)
+        PHP_FE(dns_getrecord,third_and_rest_force_ref)
        PHP_FE(getmxrr,second_and_third_args_force_ref)
 #endif
 
Index: dns.c
===================================================================
RCS file: /repository/php4/ext/standard/dns.c,v
retrieving revision 1.44
diff -u -r1.44 dns.c
--- dns.c       18 Oct 2002 22:08:23 -0000      1.44
+++ dns.c       17 Nov 2002 17:49:37 -0000
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: dns.c,v 1.44 2002/10/18 22:08:23 sniper Exp $ */
+/* $Id: dns.c,v 1.44 2002/11/16 17:43:41 pollita Exp $ */
 
 /* {{{ includes
  */
@@ -71,6 +71,13 @@
 #include "dns.h"
 /* }}} */
 
+#if HAVE_RES_SEARCH && !(defined(__BEOS__)||defined(PHP_WIN32))
+typedef union {
+       HEADER qb1;
+       u_char qb2[65536];
+} querybuf;
+#endif
+
 static char *php_gethostbyaddr(char *ip);
 static char *php_gethostbyname(char *name);
 
@@ -276,6 +283,255 @@
 #ifndef MAXHOSTNAMELEN
 #define MAXHOSTNAMELEN  256
 #endif /* MAXHOSTNAMELEN */
+
+#ifndef MAXRESOURCERECORDS
+#define MAXRESOURCERECORDS     64
+#endif /* MAXRESOURCERECORDS */
+
+REGISTER_LONG_CONSTANT("DNS_ANY", T_ANY, CONST_CS | CONST_PERSISTENT);
+REGISTER_LONG_CONSTANT("DNS_A", T_A, CONST_CS | CONST_PERSISTENT);
+REGISTER_LONG_CONSTANT("DNS_MX", T_MX, CONST_CS | CONST_PERSISTENT);
+REGISTER_LONG_CONSTANT("DNS_CNAME", T_CNAME, CONST_CS | CONST_PERSISTENT);
+REGISTER_LONG_CONSTANT("DNS_NS", T_NS, CONST_CS | CONST_PERSISTENT);
+REGISTER_LONG_CONSTANT("DNS_TXT", T_TXT, CONST_CS | CONST_PERSISTENT);
+REGISTER_LONG_CONSTANT("DNS_PTR", T_PTR, CONST_CS | CONST_PERSISTENT);
+REGISTER_LONG_CONSTANT("DNS_SOA", T_SOA, CONST_CS | CONST_PERSISTENT);
+REGISTER_LONG_CONSTANT("DNS_HINFO", T_HINFO, CONST_CS | CONST_PERSISTENT);
+
+/* {{{ php_parserr
+ */
+u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, zval **subarray) 
+{
+       u_short type, class, dlen;
+       u_long ttl;
+       long n, i;
+       char name[MAXHOSTNAMELEN];
+
+       n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, (sizeof name) - 2);
+       if (n < 0) {
+               return NULL;
+       }
+       cp += n;
+
+       GETSHORT(type, cp);
+       GETSHORT(class, cp);
+       GETLONG(ttl, cp);
+       GETSHORT(dlen, cp);
+       if (type_to_fetch != T_ANY && type != type_to_fetch) {
+               /* Should never actually occour */
+               cp += dlen;
+               return NULL;
+       }
+
+       MAKE_STD_ZVAL(*subarray);
+       if (array_init(*subarray) != SUCCESS) {
+               return NULL;
+       }
+       add_assoc_string(*subarray, "host", name, 1);
+
+       switch (type) {
+               case T_A:
+                       add_assoc_string(*subarray, "type", "A", 1);
+                       sprintf(name, "%d.%d.%d.%d", cp[0], cp[1], cp[2], cp[3]);
+                       add_assoc_string(*subarray, "ip", name, 1);
+                       cp += dlen;
+                       break;
+               case T_MX:
+                       add_assoc_string(*subarray, "type", "MX", 1);
+                       GETSHORT(n, cp);
+                       add_assoc_long(*subarray, "pri", n);
+               case T_CNAME:
+                       if (type == T_CNAME)
+                               add_assoc_string(*subarray, "type", "CNAME", 1);
+               case T_NS:
+                       if (type == T_NS)
+                               add_assoc_string(*subarray, "type", "NS", 1);
+               case T_PTR:
+                       if (type == T_PTR)
+                               add_assoc_string(*subarray, "type", "PTR", 1);
+                       n = dn_expand( answer->qb2, answer->qb2+65536, cp, name, 
+(sizeof name) - 2);
+                       if (n < 0) {
+                               return NULL;
+                       }
+                       cp += n;
+                       add_assoc_string(*subarray, "target", name, 1);
+                       break;
+               case T_HINFO:
+                       /* See RFC 1010 for values */
+                       GETSHORT(n, cp);
+                       add_assoc_long(*subarray, "cpu", n);
+                       GETSHORT(n, cp);
+                       add_assoc_long(*subarray, "os", n);
+                       break;
+               case T_TXT:
+                       add_assoc_string(*subarray, "type", "TXT", 1);
+                       n = cp[0]; 
+                       for(i=1; i<=n; i++)
+                               name[i-1] = cp[i];
+                       name[i-1] = '\0';
+                       cp += dlen;
+                       add_assoc_string(*subarray, "txt", name, 1);
+                       break;
+               case T_SOA:
+                       add_assoc_string(*subarray, "type", "SOA", 1);
+                       n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, 
+(sizeof name) -2);
+                       if (n < 0) {
+                               return NULL;
+                       }
+                       cp += n;
+                       add_assoc_string(*subarray, "mname", name, 1);
+                       n = dn_expand(answer->qb2, answer->qb2+65536, cp, name, 
+(sizeof name) -2);
+                       if (n < 0) {
+                               return NULL;
+                       }
+                       cp += n;
+                       add_assoc_string(*subarray, "rname", name, 1);
+                       GETLONG(n, cp);
+                       add_assoc_long(*subarray, "serial", n);
+                       GETLONG(n, cp);
+                       add_assoc_long(*subarray, "refresh", n);
+                       GETLONG(n, cp);
+                       add_assoc_long(*subarray, "retry", n);
+                       GETLONG(n, cp);
+                       add_assoc_long(*subarray, "expire", n);
+                       GETLONG(n, cp);
+                       add_assoc_long(*subarray, "minimum-ttl", n);
+                       break;
+               default:
+                       cp += dlen;
+       }
+
+       add_assoc_string(*subarray, "class", "IN", 1);
+       add_assoc_long(*subarray, "ttl", ttl);
+
+       return cp;
+}
+/* }}} */
+
+/* {{{ proto array dns_getrecord(string hostname [, int type[, array authns, array 
+addtl]])
+   Get any Resource Record corresponding to a given Internet host name */
+PHP_FUNCTION(dns_getrecord)
+{
+       zval *subarray[MAXRESOURCERECORDS];
+       pval *addtl, *host, *authns, *fetch_type;
+       int addtl_recs = 0;
+       int type_to_fetch = T_ANY;
+       int current_subarray = 0;
+       struct __res_state res;
+       HEADER *hp;
+       querybuf buf, answer, *ans;
+       u_char *cp, *end;
+       long n, qd, an, ns, ar;
+
+       /* Initialize the return array */
+       if (array_init(return_value) != SUCCESS) {
+               RETURN_FALSE;
+       }
+
+       switch (ZEND_NUM_ARGS()) {
+               case 1:
+                       if (zend_get_parameters(ht, 1, &host) == FAILURE) {
+                               WRONG_PARAM_COUNT;
+                       }
+                       break;
+               case 2:
+                       if (zend_get_parameters(ht, 2, &host, &fetch_type) == FAILURE) 
+{
+                               WRONG_PARAM_COUNT;
+                       }
+                       type_to_fetch = Z_LVAL_P(fetch_type);
+                       if ( type_to_fetch != T_ANY && type_to_fetch != T_A &&
+                            type_to_fetch != T_NS && type_to_fetch != T_MX &&
+                            type_to_fetch != T_TXT && type_to_fetch != T_CNAME &&
+                            type_to_fetch != T_SOA && type_to_fetch != T_PTR &&
+                            type_to_fetch != T_HINFO ) {
+                               php_error(E_WARNING, "%s(): Type '%d' not supported", 
+get_active_function_name(TSRMLS_C), type_to_fetch);
+                               RETURN_FALSE;
+                       }
+                       break;
+               case 4:
+                       if (zend_get_parameters(ht, 4, &host, &fetch_type, &authns, 
+&addtl) == FAILURE) {
+                               WRONG_PARAM_COUNT;
+                       }
+                       pval_destructor(authns);
+                       addtl_recs = 1;         /* We want the additional Records */
+                       if (array_init(authns) != SUCCESS) {
+                               RETURN_FALSE;
+                       }
+                       pval_destructor(addtl);
+                       if (array_init(addtl) != SUCCESS) {
+                               RETURN_FALSE;
+                       }
+                       type_to_fetch = Z_LVAL_P(fetch_type);
+                       if ( type_to_fetch != T_ANY && type_to_fetch != T_A &&
+                            type_to_fetch != T_NS && type_to_fetch != T_MX &&
+                            type_to_fetch != T_TXT && type_to_fetch != T_CNAME &&
+                            type_to_fetch != T_SOA && type_to_fetch != T_PTR &&
+                            type_to_fetch != T_HINFO ) {
+                               php_error(E_WARNING, "%s(): Type '%d' not supported", 
+get_active_function_name(TSRMLS_C), type_to_fetch);
+                               RETURN_FALSE;
+                       }
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+         }
+
+
+       res_ninit(&res);
+       res.retrans = 5;
+       res.options &= ~RES_DEFNAMES;
+
+       n = res_nmkquery(&res, QUERY, Z_STRVAL_P(host), C_IN, type_to_fetch, NULL, 0, 
+NULL, buf.qb2, sizeof buf);
+       if (n<0) {
+               RETURN_FALSE;
+       }
+       n = res_nsend(&res, buf.qb2, n, answer.qb2, sizeof answer);
+       if (n<0) {
+               RETURN_FALSE;
+       }
+
+       cp = answer.qb2 + HFIXEDSZ;
+       end = answer.qb2 + n;
+       ans = &answer;
+       hp = (HEADER *)ans;
+       qd = ntohs(hp->qdcount);
+       an = ntohs(hp->ancount);
+       ns = ntohs(hp->nscount);
+       ar = ntohs(hp->arcount);
+
+       /* Skip QD entries, they're only used by dn_expand later on */
+       while (qd-- > 0) {
+               n = dn_skipname(cp, end);
+               if (n < 0) {
+                       RETURN_FALSE;
+               }
+               cp += n + QFIXEDSZ;
+       }
+
+       /* YAY! Our real answers! */
+       while (an-- && cp && cp < end) {
+               cp = php_parserr(cp, &answer, type_to_fetch, 
+&subarray[current_subarray]);
+               if (subarray[current_subarray] != NULL)
+                       zend_hash_next_index_insert(HASH_OF(return_value), (void 
+*)&subarray[current_subarray], sizeof(zval *), NULL);
+               current_subarray++;
+       }
+
+       if (addtl_recs) {
+               /* List of Authoritative Name Servers */
+               while (ns-- > 0 && cp && cp < end) {
+                       cp = php_parserr(cp, &answer, T_ANY, 
+&subarray[current_subarray]);
+                       if (subarray[current_subarray] != NULL)
+                               zend_hash_next_index_insert(HASH_OF(authns), (void 
+*)&subarray[current_subarray], sizeof(zval *), NULL);
+                       current_subarray++;
+               }
+               /* Additional records associated with authoritative name servers */
+               while (ar-- > 0 && cp && cp < end) {
+                       cp = php_parserr(cp, &answer, T_ANY, 
+&subarray[current_subarray]);
+                       if (subarray[current_subarray] != NULL)
+                               zend_hash_next_index_insert(HASH_OF(addtl), (void 
+*)&subarray[current_subarray], sizeof(zval *), NULL);
+                       current_subarray++;
+               }
+       }
+       RETURN_TRUE;
+}
+/* }}} */
 
 /* {{{ proto int getmxrr(string hostname, array mxhosts [, array weight])
    Get MX records corresponding to a given Internet host name */
Index: dns.h
===================================================================
RCS file: /repository/php4/ext/standard/dns.h,v
retrieving revision 1.11
diff -u -r1.11 dns.h
--- dns.h       28 Feb 2002 08:26:44 -0000      1.11
+++ dns.h       17 Nov 2002 00:15:20 -0000
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: dns.h,v 1.11 2002/02/28 08:26:44 sebastian Exp $ */
+/* $Id: dns.h,v 1.12 2002/11/16 13:38:33 pollita Exp $ */
 
 #ifndef DNS_H
 #define DNS_H
@@ -27,6 +27,7 @@
 
 #if HAVE_RES_SEARCH && !(defined(__BEOS__)||defined(PHP_WIN32))
 PHP_FUNCTION(checkdnsrr);
+PHP_FUNCTION(dns_getrecord);
 PHP_FUNCTION(getmxrr);
 #endif


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to