Per corrections suggested by [EMAIL PROTECTED], attached is a revised pacth to
ext/standard/dns.c for addition of getanyrr() function.

--- dns.c       Sat Nov 16 13:31:51 2002
+++ dns.c       Sat Nov 16 15:04:07 2002
@@ -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 14:51:58 pollita Exp $ */
 
 /* {{{ includes
  */
@@ -276,6 +276,252 @@
 #ifndef MAXHOSTNAMELEN
 #define MAXHOSTNAMELEN  256
 #endif /* MAXHOSTNAMELEN */
+
+#ifndef MAXRESOURCERECORDS
+#define MAXRESOURCERECORDS     64
+#endif /* MAXRESOURCERECORDS */
+
+/* {{{ 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 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, *fetch_type;
+       int addtl_recs = 0;
+       int alt_server = 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 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, &fetch_type) == FAILURE) 
+{
+                               WRONG_PARAM_COUNT;
+                       }
+                       if ( !strcasecmp("A", Z_STRVAL_P(fetch_type)) ) type_to_fetch 
+= T_A;
+                       else if ( !strcasecmp("NS", Z_STRVAL_P(fetch_type)) ) 
+type_to_fetch = T_NS;
+                       else if ( !strcasecmp("MX", Z_STRVAL_P(fetch_type)) ) 
+type_to_fetch = T_MX;
+                       else if ( !strcasecmp("ANY", Z_STRVAL_P(fetch_type)) ) 
+type_to_fetch = T_ANY;
+                       else if ( !strcasecmp("TXT", Z_STRVAL_P(fetch_type)) ) 
+type_to_fetch = T_TXT;
+                       else if ( !strcasecmp("CNAME", Z_STRVAL_P(fetch_type)) ) 
+type_to_fetch = T_CNAME;
+                       else if ( !strcasecmp("SOA", Z_STRVAL_P(fetch_type)) ) 
+type_to_fetch = T_SOA;
+                       else if ( !strcasecmp("PTR", Z_STRVAL_P(fetch_type)) ) 
+type_to_fetch = T_PTR;
+                       else {
+                               php_error(E_WARNING, "%s(): Type '%s' not supported", 
+get_active_function_name(TSRMLS_C), Z_STRVAL_P(fetch_type));
+                               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;
+                       }
+                       if ( !strcasecmp("A", Z_STRVAL_P(fetch_type)) ) type_to_fetch 
+= T_A;
+                       else if ( !strcasecmp("NS", Z_STRVAL_P(fetch_type)) ) 
+type_to_fetch = T_NS;
+                       else if ( !strcasecmp("MX", Z_STRVAL_P(fetch_type)) ) 
+type_to_fetch = T_MX;
+                       else if ( !strcasecmp("ANY", Z_STRVAL_P(fetch_type)) ) 
+type_to_fetch = T_ANY;
+                       else if ( !strcasecmp("TXT", Z_STRVAL_P(fetch_type)) ) 
+type_to_fetch = T_TXT;
+                       else if ( !strcasecmp("CNAME", Z_STRVAL_P(fetch_type)) ) 
+type_to_fetch = T_CNAME;
+                       else if ( !strcasecmp("SOA", Z_STRVAL_P(fetch_type)) ) 
+type_to_fetch = T_SOA;
+                       else if ( !strcasecmp("PTR", Z_STRVAL_P(fetch_type)) ) 
+type_to_fetch = T_PTR;
+                       else {
+                               php_error(E_WARNING, "%s(): Type '%s' not supported", 
+get_active_function_name(TSRMLS_C), Z_STRVAL_P(fetch_type));
+                               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 = (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,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++;
+               }
+       }
+}
+/* }}} */
 
 /* {{{ proto int getmxrr(string hostname, array mxhosts [, array weight])
    Get MX records corresponding to a given Internet host name */

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

Reply via email to