The three attached patch files (to be applied in ext/standard/ ) introduce
a new function: getanyrr().  Where the existing getmxrr() will retrieve MX
records for a given host, getanyrr() will return all standard INET DNS
Resource Records.

proto:
  array getanyrr(string hostname [, string type[, array authns, array
addtl]])

"Type" is optional and can be any of "ANY", "A", "MX", "CNAME", "NS",
"TXT", "SOA", "HINFO", or "PTR".  "ANY" is default.

getanyrr returns an index array of associative arrays.  Each associative
array contains 'host', 'type', 'class', 'ttl', and one or more additional
records depending on type.

The third and fourth arguments are pass-by-ref arrays with the same
structure as the function return argument.  "authns" contains a list of
authoritative name servers, while "addtl" contains additional relevant
records (typically A records for the name servers).

Further documentation to be submitted to PHP-DOC when and if attached
patches are accepted and committed to CVS.

basic_functions.c    Patch against r1.543
dns.c    Patch against r1.44
dns.h    Patch against r1.11

--- basic_functions.c   Sat Nov 16 13:35:31 2002
+++ basic_functions.c   Sat Nov 16 13:41:53 2002
@@ -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(getanyrr,third_and_rest_force_ref)
        PHP_FE(getmxrr,second_and_third_args_force_ref)
 #endif
 
--- dns.h       Sat Nov 16 13:33:06 2002
+++ dns.h       Sat Nov 16 13:38:33 2002
@@ -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,7 +27,14 @@
 
 #if HAVE_RES_SEARCH && !(defined(__BEOS__)||defined(PHP_WIN32))
 PHP_FUNCTION(checkdnsrr);
+PHP_FUNCTION(getanyrr);
 PHP_FUNCTION(getmxrr);
+
+typedef union {
+        HEADER qb1;
+        u_char qb2[65536];
+} querybuf;
+
 #endif
 
 #ifndef INT16SZ
--- dns.c       Sat Nov 16 13:31:51 2002
+++ dns.c       Sat Nov 16 13:45:25 2002
@@ -277,6 +277,244 @@
 #define MAXHOSTNAMELEN  256
 #endif /* MAXHOSTNAMELEN */
 
+#ifndef MAXRESOURCERECORDS
+#define MAXRESOURCERECORDS     64
+#endif /* MAXRESOURCERECORDS */
+
+/* {{{ php_parserr
+ */
+u_char *php_parserr(u_char *cp, querybuf *answer, int typeToFetch, 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 (typeToFetch != T_ANY && type != typeToFetch) {
+               /* 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 getanyrr(string hostname [, string type[, array authns, array 
+addtl]])
+   Get any Resource Record corresponding to a given Internet host name */
+PHP_FUNCTION(getanyrr)
+{
+       zval *subarray[MAXRESOURCERECORDS];
+       pval *addtl,*host,*authns,*fetchType;
+       int addtl_recs = 0;
+       int alt_server = 0;
+       int typeToFetch = T_ANY;
+       int current_subarray = 0;
+       struct __res_state res;
+       HEADER *hp;
+       querybuf buf,answer,*ans;
+       u_char *cp,*end;
+       long i,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, &fetchType) == FAILURE) {
+                               WRONG_PARAM_COUNT;
+                       }
+                       break;
+               case 4:
+                       if (zend_get_parameters(ht, 4, &host, &fetchType, &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;
+                       }
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+         }
+
+       if (ZEND_NUM_ARGS() == 1) {
+               typeToFetch = T_ANY;
+       } else {
+               if ( !strcasecmp("A", Z_STRVAL_P(fetchType)) ) typeToFetch = T_A;
+               else if ( !strcasecmp("NS", Z_STRVAL_P(fetchType)) ) typeToFetch = 
+T_NS;
+               else if ( !strcasecmp("MX", Z_STRVAL_P(fetchType)) ) typeToFetch = 
+T_MX;
+               else if ( !strcasecmp("ANY", Z_STRVAL_P(fetchType)) ) typeToFetch = 
+T_ANY;
+               else if ( !strcasecmp("TXT", Z_STRVAL_P(fetchType)) ) typeToFetch = 
+T_TXT;
+               else if ( !strcasecmp("CNAME", Z_STRVAL_P(fetchType)) ) typeToFetch = 
+T_CNAME;
+               else if ( !strcasecmp("SOA", Z_STRVAL_P(fetchType)) ) typeToFetch = 
+T_SOA;
+               else if ( !strcasecmp("PTR", Z_STRVAL_P(fetchType)) ) typeToFetch = 
+T_PTR;
+               else {
+                       php_error(E_WARNING, "Type '%s' not supported", 
+Z_STRVAL_P(fetchType));
+                       RETURN_FALSE;
+               }
+       }
+
+       res_ninit(&res);
+       res.retrans = 5;
+       res.options &= ~RES_DEFNAMES;
+
+       n = 
+res_nmkquery(&res,QUERY,Z_STRVAL_P(host),C_IN,typeToFetch,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 = (const 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,typeToFetch,&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++;
+               }
+       }
+}
+/* }}} */
+
 /* {{{ proto int getmxrr(string hostname, array mxhosts [, array weight])
    Get MX records corresponding to a given Internet host name */
 PHP_FUNCTION(getmxrr)

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

Reply via email to