OSSP CVS Repository

ossp - Check-in [160]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 160
Date: 2000-Sep-18 17:46:45 (local)
2000-Sep-18 15:46:45 (UTC)
User:rse
Branch:
Comment: Import of ADNS 1.0
Tickets:
Inspections:
Files:
ossp-pkg/adns/aclocal.m4      added-> 1.1.1.2
ossp-pkg/adns/adns_check.c      added-> 1.1.1.3
ossp-pkg/adns/adns_event.c      1.1.1.3 -> 1.1.1.4     3 inserted, 2 deleted
ossp-pkg/adns/adns_general.c      added-> 1.1.1.4
ossp-pkg/adns/adns_internal.h      added-> 1.1.1.4
ossp-pkg/adns/adns_parse.c      added-> 1.1.1.4
ossp-pkg/adns/adns_poll.c      added-> 1.1.1.3
ossp-pkg/adns/adns_query.c      1.1.1.4 -> 1.1.1.5     1 inserted, 1 deleted
ossp-pkg/adns/adns_reply.c      1.1.1.4 -> 1.1.1.5     1 inserted, 1 deleted
ossp-pkg/adns/adns_setup.c      added-> 1.1.1.3
ossp-pkg/adns/adns_test.c      1.1.1.3 -> 1.1.1.4     7 inserted, 8 deleted
ossp-pkg/adns/adns_transmit.c      1.1.1.4 -> 1.1.1.5     1 inserted, 1 deleted
ossp-pkg/adns/adns_tvarith.c      added-> 1.1.1.3
ossp-pkg/adns/adns_types.c      added-> 1.1.1.3
ossp-pkg/adns/configure.in      1.1.1.3 -> 1.1.1.4     24 inserted, 2 deleted

ossp-pkg/adns/aclocal.m4 -> 1.1.1.2

*** /dev/null    Sun Apr 28 21:30:37 2024
--- -    Sun Apr 28 21:31:45 2024
***************
*** 0 ****
--- 1,70 ----
+ # aclocal.m4 - package-specific macros for autoconf
+ #  
+ #  This file is
+ #    Copyright (C) 1997-1999 Ian Jackson <ian@davenant.greenend.org.uk>
+ #
+ #  It is part of adns, which is
+ #    Copyright (C) 1997-1999 Ian Jackson <ian@davenant.greenend.org.uk>
+ #    Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
+ #  
+ #  This file is part of adns, which is Copyright (C) 1997-1999 Ian Jackson
+ #
+ #  This program is free software; you can redistribute it and/or modify
+ #  it under the terms of the GNU General Public License as published by
+ #  the Free Software Foundation; either version 2, or (at your option)
+ #  any later version.
+ #  
+ #  This program is distributed in the hope that it will be useful,
+ #  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #  GNU General Public License for more details.
+ #  
+ #  You should have received a copy of the GNU General Public License
+ #  along with this program; if not, write to the Free Software Foundation,
+ #  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ 
+ dnl DPKG_CACHED_TRY_COMPILE(<description>,<cachevar>,<include>,<program>,<ifyes>,<ifno>)
+ define(DPKG_CACHED_TRY_COMPILE,[
+  AC_MSG_CHECKING($1)
+  AC_CACHE_VAL($2,[
+   AC_TRY_COMPILE([$3],[$4],[$2=yes],[$2=no])
+  ])
+  if test "x$$2" = xyes; then
+   true
+   $5
+  else
+   true
+   $6
+  fi
+ ])
+ 
+ define(ADNS_C_GCCATTRIB,[
+  DPKG_CACHED_TRY_COMPILE(__attribute__((,,)),adns_cv_c_attribute_supported,,
+   [extern int testfunction(int x) __attribute__((,,))],
+   AC_MSG_RESULT(yes)
+   AC_DEFINE(HAVE_GNUC25_ATTRIB)
+    DPKG_CACHED_TRY_COMPILE(__attribute__((noreturn)),adns_cv_c_attribute_noreturn,,
+     [extern int testfunction(int x) __attribute__((noreturn))],
+     AC_MSG_RESULT(yes)
+     AC_DEFINE(HAVE_GNUC25_NORETURN),
+     AC_MSG_RESULT(no))
+    DPKG_CACHED_TRY_COMPILE(__attribute__((const)),adns_cv_c_attribute_const,,
+     [extern int testfunction(int x) __attribute__((const))],
+     AC_MSG_RESULT(yes)
+     AC_DEFINE(HAVE_GNUC25_CONST),
+     AC_MSG_RESULT(no))
+    DPKG_CACHED_TRY_COMPILE(__attribute__((format...)),adns_cv_attribute_format,,
+     [extern int testfunction(char *y, ...) __attribute__((format(printf,1,2)))],
+     AC_MSG_RESULT(yes)
+     AC_DEFINE(HAVE_GNUC25_PRINTFFORMAT),
+     AC_MSG_RESULT(no)),
+   AC_MSG_RESULT(no))
+ ])
+ 
+ define(ADNS_C_GETFUNC,[
+  AC_CHECK_FUNC([$1],,[
+   AC_CHECK_LIB([$2],[$1],[$3],[
+     AC_MSG_ERROR([cannot find library function $1])
+   ])
+  ])
+ ])


ossp-pkg/adns/adns_check.c -> 1.1.1.3

*** /dev/null    Sun Apr 28 21:30:37 2024
--- -    Sun Apr 28 21:31:45 2024
***************
*** 0 ****
--- 1,199 ----
+ /*
+  * check.c
+  * - consistency checks
+  */
+ /*
+  *  This file is
+  *    Copyright (C) 1997-1999 Ian Jackson <ian@davenant.greenend.org.uk>
+  *
+  *  It is part of adns, which is
+  *    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
+  *    Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
+  *  
+  *  This program is free software; you can redistribute it and/or modify
+  *  it under the terms of the GNU General Public License as published by
+  *  the Free Software Foundation; either version 2, or (at your option)
+  *  any later version.
+  *  
+  *  This program is distributed in the hope that it will be useful,
+  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *  GNU General Public License for more details.
+  *  
+  *  You should have received a copy of the GNU General Public License
+  *  along with this program; if not, write to the Free Software Foundation,
+  *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+  */
+ 
+ #include "internal.h"
+ 
+ void adns_checkconsistency(adns_state ads, adns_query qu) {
+   adns__consistency(ads,qu,cc_user);
+ }
+ 
+ #define DLIST_CHECK(list, nodevar, part, body)                                 \
+   if ((list).head) {                                                           \
+     assert(! (list).head->part back);                                          \
+     for ((nodevar)= (list).head; (nodevar); (nodevar)= (nodevar)->part next) { \
+       assert((nodevar)->part next                                              \
+             ? (nodevar) == (nodevar)->part next->part back                     \
+             : (nodevar) == (list).tail);                                       \
+       body                                                                     \
+     }                                                                          \
+   }
+ 
+ #define DLIST_ASSERTON(node, nodevar, list, part)                              \
+   do {                                                                         \
+     for ((nodevar)= (list).head;                                               \
+         (nodevar) != (node);                                                   \
+         (nodevar)= (nodevar)->part next) {                                     \
+       assert((nodevar));                                                       \
+     }                                                                          \
+   } while(0)
+ 
+ static void checkc_query_alloc(adns_state ads, adns_query qu) {
+   allocnode *an;
+ 
+   DLIST_CHECK(qu->allocations, an, , {
+   });
+ }
+ 
+ static void checkc_query(adns_state ads, adns_query qu) {
+   adns_query child;
+ 
+   assert(qu->udpnextserver < ads->nservers);
+   assert(!(qu->udpsent & (~0UL << ads->nservers)));
+   assert(qu->search_pos <= ads->nsearchlist);
+   if (qu->parent) DLIST_ASSERTON(qu, child, qu->parent->children, siblings.);
+ }
+ 
+ static void checkc_notcpbuf(adns_state ads) {
+   assert(!ads->tcpsend.used);
+   assert(!ads->tcprecv.used);
+   assert(!ads->tcprecv_skip);
+ }
+ 
+ static void checkc_global(adns_state ads) {
+   int i;
+   
+   assert(ads->udpsocket >= 0);
+ 
+   for (i=0; i<ads->nsortlist; i++)
+     assert(!(ads->sortlist[i].base.s_addr & ~ads->sortlist[i].mask.s_addr));
+ 
+   assert(ads->tcpserver >= 0 && ads->tcpserver < ads->nservers);
+   
+   switch (ads->tcpstate) {
+   case server_connecting:
+     assert(ads->tcpsocket >= 0);
+     checkc_notcpbuf(ads);
+     break;
+   case server_disconnected:
+   case server_broken:
+     assert(ads->tcpsocket == -1);
+     checkc_notcpbuf(ads);
+     break;
+   case server_ok:
+     assert(ads->tcpsocket >= 0);
+     assert(ads->tcprecv_skip <= ads->tcprecv.used);
+     break;
+   default:
+     assert(!"ads->tcpstate value");
+   }
+ 
+   assert(ads->searchlist || !ads->nsearchlist);
+ }
+ 
+ static void checkc_queue_udpw(adns_state ads) {
+   adns_query qu;
+   
+   DLIST_CHECK(ads->udpw, qu, , {
+     assert(qu->state==query_tosend);
+     assert(qu->retries <= UDPMAXRETRIES);
+     assert(qu->udpsent);
+     assert(!qu->children.head && !qu->children.tail);
+     checkc_query(ads,qu);
+     checkc_query_alloc(ads,qu);
+   });
+ }
+ 
+ static void checkc_queue_tcpw(adns_state ads) {
+   adns_query qu;
+   
+   DLIST_CHECK(ads->tcpw, qu, , {
+     assert(qu->state==query_tcpw);
+     assert(!qu->children.head && !qu->children.tail);
+     assert(qu->retries <= ads->nservers+1);
+     checkc_query(ads,qu);
+     checkc_query_alloc(ads,qu);
+   });
+ }
+ 
+ static void checkc_queue_childw(adns_state ads) {
+   adns_query parent, child;
+ 
+   DLIST_CHECK(ads->childw, parent, , {
+     assert(parent->state == query_childw);
+     assert(parent->children.head);
+     DLIST_CHECK(parent->children, child, siblings., {
+       assert(child->parent == parent);
+       assert(child->state != query_done);
+     });
+     checkc_query(ads,parent);
+     checkc_query_alloc(ads,parent);
+   });
+ }
+ 
+ static void checkc_queue_output(adns_state ads) {
+   adns_query qu;
+   
+   DLIST_CHECK(ads->output, qu, , {
+     assert(qu->state == query_done);
+     assert(!qu->children.head && !qu->children.tail);
+     assert(!qu->parent);
+     assert(!qu->allocations.head && !qu->allocations.tail);
+     checkc_query(ads,qu);
+   });
+ }
+ 
+ void adns__consistency(adns_state ads, adns_query qu, consistency_checks cc) {
+   adns_query search;
+   
+   switch (cc) {
+   case cc_user:
+     break;
+   case cc_entex:
+     if (!(ads->iflags & adns_if_checkc_entex)) return;
+     break;
+   case cc_freq:
+     if ((ads->iflags & adns_if_checkc_freq) != adns_if_checkc_freq) return;
+     break;
+   default:
+     abort();
+   }
+ 
+   checkc_global(ads);
+   checkc_queue_udpw(ads);
+   checkc_queue_tcpw(ads);
+   checkc_queue_childw(ads);
+   checkc_queue_output(ads);
+ 
+   if (qu) {
+     switch (qu->state) {
+     case query_tosend:
+       DLIST_ASSERTON(qu, search, ads->udpw, );
+       break;
+     case query_tcpw:
+       DLIST_ASSERTON(qu, search, ads->tcpw, );
+       break;
+     case query_childw:
+       DLIST_ASSERTON(qu, search, ads->childw, );
+       break;
+     case query_done:
+       DLIST_ASSERTON(qu, search, ads->output, );
+       break;
+     default:
+       assert(!"specific query state");
+     }
+   }
+ }


ossp-pkg/adns/adns_event.c 1.1.1.3 -> 1.1.1.4

--- adns_event.c 2000/08/12 11:35:09     1.1.1.3
+++ adns_event.c 2000/09/19 15:46:46     1.1.1.4
@@ -10,7 +10,7 @@
  *
  *  It is part of adns, which is
  *    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
- *    Copyright (C) 1999 Tony Finch <dot@dotat.at>
+ *    Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
  *  
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -395,7 +395,8 @@
       }
       if (udpaddrlen != sizeof(udpaddr)) {
         adns__diag(ads,-1,0,"datagram received with wrong address length %d"
-                   " (expected %d)", udpaddrlen,sizeof(udpaddr));
+                   " (expected %lu)", udpaddrlen,
+                   (unsigned long)sizeof(udpaddr));
         continue;
       }
       if (udpaddr.sin_family != AF_INET) {


ossp-pkg/adns/adns_general.c -> 1.1.1.4

*** /dev/null    Sun Apr 28 21:30:37 2024
--- -    Sun Apr 28 21:31:45 2024
***************
*** 0 ****
--- 1,360 ----
+ /*
+  * general.c
+  * - diagnostic functions
+  * - vbuf handling
+  */
+ /*
+  *  This file is
+  *    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
+  *
+  *  It is part of adns, which is
+  *    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
+  *    Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
+  *  
+  *  This program is free software; you can redistribute it and/or modify
+  *  it under the terms of the GNU General Public License as published by
+  *  the Free Software Foundation; either version 2, or (at your option)
+  *  any later version.
+  *  
+  *  This program is distributed in the hope that it will be useful,
+  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *  GNU General Public License for more details.
+  *  
+  *  You should have received a copy of the GNU General Public License
+  *  along with this program; if not, write to the Free Software Foundation,
+  *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+  */
+ 
+ #include <stdlib.h>
+ #include <unistd.h>
+ 
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ 
+ #include "internal.h"
+ 
+ /* Core diagnostic functions */
+ 
+ void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent,
+                 int serv, adns_query qu, const char *fmt, va_list al) {
+   const char *bef, *aft;
+   vbuf vb;
+   
+   if (!ads->diagfile ||
+       (!(ads->iflags & adns_if_debug) && (!prevent || (ads->iflags & prevent))))
+     return;
+ 
+   if (ads->iflags & adns_if_logpid) {
+     fprintf(ads->diagfile,"adns%s [%ld]: ",pfx,(long)getpid());
+   } else {
+     fprintf(ads->diagfile,"adns%s: ",pfx);
+   }
+ 
+   vfprintf(ads->diagfile,fmt,al);
+ 
+   bef= " (";
+   aft= "\n";
+ 
+   if (qu && qu->query_dgram) {
+     adns__vbuf_init(&vb);
+     fprintf(ads->diagfile,"%sQNAME=%s, QTYPE=%s",
+            bef,
+            adns__diag_domain(qu->ads,-1,0, &vb,
+                              qu->query_dgram,qu->query_dglen,DNS_HDRSIZE),
+            qu->typei ? qu->typei->rrtname : "<unknown>");
+     if (qu->typei && qu->typei->fmtname)
+       fprintf(ads->diagfile,"(%s)",qu->typei->fmtname);
+     bef=", "; aft=")\n";
+     adns__vbuf_free(&vb);
+   }
+   
+   if (serv>=0) {
+     fprintf(ads->diagfile,"%sNS=%s",bef,inet_ntoa(ads->servers[serv].addr));
+     bef=", "; aft=")\n";
+   }
+ 
+   fputs(aft,ads->diagfile);
+ }
+ 
+ void adns__debug(adns_state ads, int serv, adns_query qu, const char *fmt, ...) {
+   va_list al;
+ 
+   va_start(al,fmt);
+   adns__vdiag(ads," debug",0,serv,qu,fmt,al);
+   va_end(al);
+ }
+ 
+ void adns__warn(adns_state ads, int serv, adns_query qu, const char *fmt, ...) {
+   va_list al;
+ 
+   va_start(al,fmt);
+   adns__vdiag(ads," warning",adns_if_noerrprint|adns_if_noserverwarn,serv,qu,fmt,al);
+   va_end(al);
+ }
+ 
+ void adns__diag(adns_state ads, int serv, adns_query qu, const char *fmt, ...) {
+   va_list al;
+ 
+   va_start(al,fmt);
+   adns__vdiag(ads,"",adns_if_noerrprint,serv,qu,fmt,al);
+   va_end(al);
+ }
+ 
+ /* vbuf functions */
+ 
+ void adns__vbuf_init(vbuf *vb) {
+   vb->used= vb->avail= 0; vb->buf= 0;
+ }
+ 
+ int adns__vbuf_ensure(vbuf *vb, int want) {
+   void *nb;
+   
+   if (vb->avail >= want) return 1;
+   nb= realloc(vb->buf,want); if (!nb) return 0;
+   vb->buf= nb;
+   vb->avail= want;
+   return 1;
+ }
+   
+ void adns__vbuf_appendq(vbuf *vb, const byte *data, int len) {
+   memcpy(vb->buf+vb->used,data,len);
+   vb->used+= len;
+ }
+ 
+ int adns__vbuf_append(vbuf *vb, const byte *data, int len) {
+   int newlen;
+   void *nb;
+ 
+   newlen= vb->used+len;
+   if (vb->avail < newlen) {
+     if (newlen<20) newlen= 20;
+     newlen <<= 1;
+     nb= realloc(vb->buf,newlen);
+     if (!nb) { newlen= vb->used+len; nb= realloc(vb->buf,newlen); }
+     if (!nb) return 0;
+     vb->buf= nb;
+     vb->avail= newlen;
+   }
+   adns__vbuf_appendq(vb,data,len);
+   return 1;
+ }
+ 
+ int adns__vbuf_appendstr(vbuf *vb, const char *data) {
+   int l;
+   l= strlen(data);
+   return adns__vbuf_append(vb,data,l);
+ }
+ 
+ void adns__vbuf_free(vbuf *vb) {
+   free(vb->buf);
+   adns__vbuf_init(vb);
+ }
+ 
+ /* Additional diagnostic functions */
+ 
+ const char *adns__diag_domain(adns_state ads, int serv, adns_query qu,
+                              vbuf *vb, const byte *dgram, int dglen, int cbyte) {
+   adns_status st;
+ 
+   st= adns__parse_domain(ads,serv,qu,vb, pdf_quoteok, dgram,dglen,&cbyte,dglen);
+   if (st == adns_s_nomemory) {
+     return "<cannot report domain... out of memory>";
+   }
+   if (st) {
+     vb->used= 0;
+     if (!(adns__vbuf_appendstr(vb,"<bad format... ") &&
+          adns__vbuf_appendstr(vb,adns_strerror(st)) &&
+          adns__vbuf_appendstr(vb,">") &&
+          adns__vbuf_append(vb,"",1))) {
+       return "<cannot report bad format... out of memory>";
+     }
+   }
+   if (!vb->used) {
+     adns__vbuf_appendstr(vb,"<truncated ...>");
+     adns__vbuf_append(vb,"",1);
+   }
+   return vb->buf;
+ }
+ 
+ adns_status adns_rr_info(adns_rrtype type,
+                         const char **rrtname_r, const char **fmtname_r,
+                         int *len_r,
+                         const void *datap, char **data_r) {
+   const typeinfo *typei;
+   vbuf vb;
+   adns_status st;
+ 
+   typei= adns__findtype(type);
+   if (!typei) return adns_s_unknownrrtype;
+ 
+   if (rrtname_r) *rrtname_r= typei->rrtname;
+   if (fmtname_r) *fmtname_r= typei->fmtname;
+   if (len_r) *len_r= typei->rrsz;
+ 
+   if (!datap) return adns_s_ok;
+   
+   adns__vbuf_init(&vb);
+   st= typei->convstring(&vb,datap);
+   if (st) goto x_freevb;
+   if (!adns__vbuf_append(&vb,"",1)) { st= adns_s_nomemory; goto x_freevb; }
+   assert(strlen(vb.buf) == vb.used-1);
+   *data_r= realloc(vb.buf,vb.used);
+   if (!*data_r) *data_r= vb.buf;
+   return adns_s_ok;
+ 
+  x_freevb:
+   adns__vbuf_free(&vb);
+   return st;
+ }
+ 
+ 
+ #define SINFO(n,s) { adns_s_##n, #n, s }
+ 
+ static const struct sinfo {
+   adns_status st;
+   const char *abbrev;
+   const char *string;
+ } sinfos[]= {
+   SINFO(  ok,                  "OK"                                            ),
+ 
+   SINFO(  nomemory,            "Out of memory"                                 ),
+   SINFO(  unknownrrtype,       "Query not implemented in DNS library"          ),
+   SINFO(  systemfail,          "General resolver or system failure"            ),
+ 
+   SINFO(  timeout,             "DNS query timed out"                           ),
+   SINFO(  allservfail,         "All nameservers failed"                        ),
+   SINFO(  norecurse,           "Recursion denied by nameserver"                ),
+   SINFO(  invalidresponse,     "Nameserver sent bad response"                  ),
+   SINFO(  unknownformat,       "Nameserver used unknown format"                ),
+ 
+   SINFO(  rcodeservfail,       "Nameserver reports failure"                    ),
+   SINFO(  rcodeformaterror,    "Query not understood by nameserver"            ),
+   SINFO(  rcodenotimplemented, "Query not implemented by nameserver"           ),
+   SINFO(  rcoderefused,        "Query refused by nameserver"                   ),
+   SINFO(  rcodeunknown,        "Nameserver sent unknown response code"         ),
+   
+   SINFO(  inconsistent,        "Inconsistent resource records in DNS"          ),
+   SINFO(  prohibitedcname,     "DNS alias found where canonical name wanted"   ),
+   SINFO(  answerdomaininvalid, "Found syntactically invalid domain name"       ),
+   SINFO(  answerdomaintoolong, "Found overly-long domain name"                 ),
+   SINFO(  invaliddata,         "Found invalid DNS data"                        ),
+ 
+   SINFO(  querydomainwrong,    "Domain invalid for particular DNS query type"  ),
+   SINFO(  querydomaininvalid,  "Domain name is syntactically invalid"          ),
+   SINFO(  querydomaintoolong,  "Domain name or component is too long"          ),
+ 
+   SINFO(  nxdomain,            "No such domain"                                ),
+   SINFO(  nodata,              "No such data"                                  )
+ };
+ 
+ static int si_compar(const void *key, const void *elem) {
+   const adns_status *st= key;
+   const struct sinfo *si= elem;
+ 
+   return *st < si->st ? -1 : *st > si->st ? 1 : 0;
+ }
+ 
+ static const struct sinfo *findsinfo(adns_status st) {
+   return bsearch(&st,sinfos,sizeof(sinfos)/sizeof(*sinfos),sizeof(*sinfos),si_compar);
+ }
+ 
+ const char *adns_strerror(adns_status st) {
+   const struct sinfo *si;
+ 
+   si= findsinfo(st);
+   return si->string;
+ }
+ 
+ const char *adns_errabbrev(adns_status st) {
+   const struct sinfo *si;
+ 
+   si= findsinfo(st);
+   return si->abbrev;
+ }
+ 
+ 
+ #define STINFO(max) { adns_s_max_##max, #max }
+ 
+ static const struct stinfo {
+   adns_status stmax;
+   const char *abbrev;
+ } stinfos[]= {
+   { adns_s_ok, "ok" },
+   STINFO(  localfail   ),
+   STINFO(  remotefail  ),
+   STINFO(  tempfail    ),
+   STINFO(  misconfig   ),
+   STINFO(  misquery    ),
+   STINFO(  permfail    )
+ };
+ 
+ static int sti_compar(const void *key, const void *elem) {
+   const adns_status *st= key;
+   const struct stinfo *sti= elem;
+ 
+   adns_status here, min, max;
+ 
+   here= *st;
+   min= (sti==stinfos) ? 0 : sti[-1].stmax+1;
+   max= sti->stmax;
+   
+   return here < min  ? -1 : here > max ? 1 : 0;
+ }
+ 
+ const char *adns_errtypeabbrev(adns_status st) {
+   const struct stinfo *sti;
+ 
+   sti= bsearch(&st,stinfos,sizeof(stinfos)/sizeof(*stinfos),sizeof(*stinfos),sti_compar);
+   return sti->abbrev;
+ }
+ 
+ 
+ void adns__isort(void *array, int nobjs, int sz, void *tempbuf,
+                 int (*needswap)(void *context, const void *a, const void *b),
+                 void *context) {
+   byte *data= array;
+   int i, place;
+ 
+   for (i=0; i<nobjs; i++) {
+     for (place= i;
+         place>0 && needswap(context, data + (place-1)*sz, data + i*sz);
+         place--);
+     if (place != i) {
+       memcpy(tempbuf, data + i*sz, sz);
+       memmove(data + (place+1)*sz, data + place*sz, (i-place)*sz);
+       memcpy(data + place*sz, tempbuf, sz);
+     }
+   }
+ }
+ 
+ /* SIGPIPE protection. */
+ 
+ void adns__sigpipe_protect(adns_state ads) {
+   sigset_t toblock;
+   struct sigaction sa;
+   int r;
+ 
+   if (ads->iflags & adns_if_nosigpipe) return;
+ 
+   sigfillset(&toblock);
+   sigdelset(&toblock,SIGPIPE);
+ 
+   sa.sa_handler= SIG_IGN;
+   sigfillset(&sa.sa_mask);
+   sa.sa_flags= 0;
+   
+   r= sigprocmask(SIG_SETMASK,&toblock,&ads->stdsigmask); assert(!r);
+   r= sigaction(SIGPIPE,&sa,&ads->stdsigpipe); assert(!r);
+ }
+ 
+ void adns__sigpipe_unprotect(adns_state ads) {
+   int r;
+ 
+   if (ads->iflags & adns_if_nosigpipe) return;
+ 
+   r= sigaction(SIGPIPE,&ads->stdsigpipe,0); assert(!r);
+   r= sigprocmask(SIG_SETMASK,&ads->stdsigmask,0); assert(!r);
+ }


ossp-pkg/adns/adns_internal.h -> 1.1.1.4

*** /dev/null    Sun Apr 28 21:30:37 2024
--- -    Sun Apr 28 21:31:45 2024
***************
*** 0 ****
--- 1,713 ----
+ /*
+  * internal.h
+  * - declarations of private objects with external linkage (adns__*)
+  * - definitons of internal macros
+  * - comments regarding library data structures
+  */
+ /*
+  *  This file is
+  *    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
+  *
+  *  It is part of adns, which is
+  *    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
+  *    Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
+  *
+  *  This program is free software; you can redistribute it and/or modify
+  *  it under the terms of the GNU General Public License as published by
+  *  the Free Software Foundation; either version 2, or (at your option)
+  *  any later version.
+  *
+  *  This program is distributed in the hope that it will be useful,
+  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *  GNU General Public License for more details.
+  *
+  *  You should have received a copy of the GNU General Public License
+  *  along with this program; if not, write to the Free Software Foundation,
+  *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  */
+ 
+ #ifndef ADNS_INTERNAL_H_INCLUDED
+ #define ADNS_INTERNAL_H_INCLUDED
+ 
+ #include "config.h"
+ typedef unsigned char byte;
+ 
+ #include <stdarg.h>
+ #include <assert.h>
+ #include <unistd.h>
+ #include <signal.h>
+ #include <errno.h>
+ #include <string.h>
+ 
+ #include <sys/time.h>
+ 
+ #include "adns.h"
+ #include "dlist.h"
+ 
+ #ifdef ADNS_REGRESS_TEST
+ # include "hredirect.h"
+ #endif
+ 
+ /* Configuration and constants */
+ 
+ #define MAXSERVERS 5
+ #define MAXSORTLIST 15
+ #define UDPMAXRETRIES 15
+ #define UDPRETRYMS 2000
+ #define TCPWAITMS 30000
+ #define TCPCONNMS 14000
+ #define TCPIDLEMS 30000
+ #define MAXTTLBELIEVE (7*86400) /* any TTL > 7 days is capped */
+ 
+ #define DNS_PORT 53
+ #define DNS_MAXUDP 512
+ #define DNS_MAXLABEL 63
+ #define DNS_MAXDOMAIN 255
+ #define DNS_HDRSIZE 12
+ #define DNS_IDOFFSET 0
+ #define DNS_CLASS_IN 1
+ 
+ #define DNS_INADDR_ARPA "in-addr", "arpa"
+ 
+ #define MAX_POLLFDS  ADNS_POLLFDS_RECOMMENDED
+ 
+ typedef enum {
+   cc_user,
+   cc_entex,
+   cc_freq
+ } consistency_checks;
+ 
+ typedef enum {
+   rcode_noerror,
+   rcode_formaterror,
+   rcode_servfail,
+   rcode_nxdomain,
+   rcode_notimp,
+   rcode_refused
+ } dns_rcode;
+ 
+ /* Shared data structures */
+ 
+ typedef union {
+   adns_status status;
+   char *cp;
+   adns_rrtype type;
+   int i;
+   struct in_addr ia;
+   unsigned long ul;
+ } rr_align;
+ 
+ typedef struct {
+   int used, avail;
+   byte *buf;
+ } vbuf;
+ 
+ typedef struct {
+   adns_state ads;
+   adns_query qu;
+   int serv;
+   const byte *dgram;
+   int dglen, nsstart, nscount, arcount;
+   struct timeval now;
+ } parseinfo;
+ 
+ typedef struct {
+   adns_rrtype type;
+   const char *rrtname;
+   const char *fmtname;
+   int rrsz;
+ 
+   void (*makefinal)(adns_query qu, void *data);
+   /* Change memory management of *data.
+    * Previously, used alloc_interim, now use alloc_final.
+    */
+ 
+   adns_status (*convstring)(vbuf *vb, const void *data);
+   /* Converts the RR data to a string representation in vbuf.
+    * vbuf will be appended to (it must have been initialised),
+    * and will not be null-terminated by convstring.
+    */
+ 
+   adns_status (*parse)(const parseinfo *pai, int cbyte, int max, void *store_r);
+   /* Parse one RR, in dgram of length dglen, starting at cbyte and
+    * extending until at most max.
+    *
+    * The RR should be stored at *store_r, of length qu->typei->rrsz.
+    *
+    * If there is an overrun which might indicate truncation, it should set
+    * *rdstart to -1; otherwise it may set it to anything else positive.
+    *
+    * nsstart is the offset of the authority section.
+    */
+ 
+   int (*diff_needswap)(adns_state ads, const void *datap_a, const void *datap_b);
+   /* Returns !0 if RR a should be strictly after RR b in the sort order,
+    * 0 otherwise.  Must not fail.
+    */
+ } typeinfo;
+ 
+ typedef struct allocnode {
+   struct allocnode *next, *back;
+ } allocnode;
+ 
+ union maxalign {
+   byte d[1];
+   struct in_addr ia;
+   long l;
+   void *p;
+   void (*fp)(void);
+   union maxalign *up;
+ } data;
+ 
+ typedef struct {
+   void *ext;
+   void (*callback)(adns_query parent, adns_query child);
+   union {
+     adns_rr_addr ptr_parent_addr;
+     adns_rr_hostaddr *hostaddr;
+   } info;
+ } qcontext;
+ 
+ struct adns__query {
+   adns_state ads;
+   enum { query_tosend, query_tcpw, query_childw, query_done } state;
+   adns_query back, next, parent;
+   struct { adns_query head, tail; } children;
+   struct { adns_query back, next; } siblings;
+   struct { allocnode *head, *tail; } allocations;
+   int interim_allocd, preserved_allocd;
+   void *final_allocspace;
+ 
+   const typeinfo *typei;
+   byte *query_dgram;
+   int query_dglen;
+ 
+   vbuf vb;
+   /* General-purpose messing-about buffer.
+    * Wherever a `big' interface is crossed, this may be corrupted/changed
+    * unless otherwise specified.
+    */
+ 
+   adns_answer *answer;
+   /* This is allocated when a query is submitted, to avoid being unable
+    * to relate errors to queries if we run out of memory.  During
+    * query processing status, rrs is 0.  cname is set if
+    * we found a cname (this corresponds to cname_dgram in the query
+    * structure).  type is set from the word go.  nrrs and rrs
+    * are set together, when we find how many rrs there are.
+    * owner is set during querying unless we're doing searchlist,
+    * in which case it is set only when we find an answer.
+    */
+ 
+   byte *cname_dgram;
+   int cname_dglen, cname_begin;
+   /* If non-0, has been allocated using . */
+ 
+   vbuf search_vb;
+   int search_origlen, search_pos, search_doneabs;
+   /* Used by the searching algorithm.  The query domain in textual form
+    * is copied into the vbuf, and _origlen set to its length.  Then
+    * we walk the searchlist, if we want to.  _pos says where we are
+    * (next entry to try), and _doneabs says whether we've done the
+    * absolute query yet (0=not yet, 1=done, -1=must do straight away,
+    * but not done yet).  If flags doesn't have adns_qf_search then
+    * the vbuf is initialised but empty and everything else is zero.
+    */
+ 
+   int id, flags, retries;
+   int udpnextserver;
+   unsigned long udpsent; /* bitmap indexed by server */
+   struct timeval timeout;
+   time_t expires; /* Earliest expiry time of any record we used. */
+ 
+   qcontext ctx;
+ 
+   /* Possible states:
+    *
+    *  state   Queue   child  id   nextudpserver  udpsent     tcpfailed
+    *
+    *  tosend  NONE    null   >=0  0              zero        zero
+    *  tosend  udpw    null   >=0  any            nonzero     zero
+    *  tosend  NONE    null   >=0  any            nonzero     zero
+    *
+    *  tcpw    tcpw    null   >=0  irrelevant     any         any
+    *
+    *  child   childw  set    >=0  irrelevant     irrelevant  irrelevant
+    *  child   NONE    null   >=0  irrelevant     irrelevant  irrelevant
+    *  done    output  null   -1   irrelevant     irrelevant  irrelevant
+    *
+    * Queries are only not on a queue when they are actually being processed.
+    * Queries in state tcpw/tcpw have been sent (or are in the to-send buffer)
+    * iff the tcp connection is in state server_ok.
+    *
+    *                         +------------------------+
+    *             START -----> |      tosend/NONE       |
+    *                         +------------------------+
+    *                         /                       |\  \
+    *        too big for UDP /             UDP timeout  \  \ send via UDP
+    *        send via TCP   /              more retries  \  \
+    *        when conn'd   /                  desired     \  \
+    *                     |                                       |  |
+    *                     v                               |  v
+    *              +-----------+                        +-------------+
+    *              | tcpw/tcpw | ________                | tosend/udpw |
+    *              +-----------+         \              +-------------+
+    *                 |    |              |     UDP timeout | |
+    *                 |    |              |      no more    | |
+    *                 |    |              |      retries    | |
+    *                  \   | TCP died     |      desired    | |
+    *                   \   \ no more     |                 | |
+    *                    \   \ servers    | TCP            /  |
+    *                     \   \ to try    | timeout       /   |
+    *                  got \   \          v             |_    | got
+    *                 reply \   _| +------------------+      / reply
+    *                               \     | done/output FAIL |     /
+    *                         \    +------------------+    /
+    *                          \                          /
+    *                           _|                      |_
+    *                             (..... got reply ....)
+    *                              /                   \
+    *        need child query/ies /                     \ no child query
+    *                            /                       \
+    *                          |_                         _|
+    *              +---------------+                   +----------------+
+    *               | childw/childw | ----------------> | done/output OK |
+    *               +---------------+  children done    +----------------+
+    */
+ };
+ 
+ struct query_queue { adns_query head, tail; };
+ 
+ struct adns__state {
+   adns_initflags iflags;
+   FILE *diagfile;
+   int configerrno;
+   struct query_queue udpw, tcpw, childw, output;
+   adns_query forallnext;
+   int nextid, udpsocket, tcpsocket;
+   vbuf tcpsend, tcprecv;
+   int nservers, nsortlist, nsearchlist, searchndots, tcpserver, tcprecv_skip;
+   enum adns__tcpstate {
+     server_disconnected, server_connecting,
+     server_ok, server_broken
+   } tcpstate;
+   struct timeval tcptimeout;
+   /* This will have tv_sec==0 if it is not valid.  It will always be
+    * valid if tcpstate _connecting.  When _ok, it will be nonzero if
+    * we are idle (ie, tcpw queue is empty), in which case it is the
+    * absolute time when we will close the connection.
+    */
+   struct sigaction stdsigpipe;
+   sigset_t stdsigmask;
+   struct pollfd pollfds_buf[MAX_POLLFDS];
+   struct server {
+     struct in_addr addr;
+   } servers[MAXSERVERS];
+   struct sortlist {
+     struct in_addr base, mask;
+   } sortlist[MAXSORTLIST];
+   char **searchlist;
+ };
+ 
+ /* From setup.c: */
+ 
+ int adns__setnonblock(adns_state ads, int fd); /* => errno value */
+ 
+ /* From general.c: */
+ 
+ void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent,
+                 int serv, adns_query qu, const char *fmt, va_list al);
+ 
+ void adns__debug(adns_state ads, int serv, adns_query qu,
+                 const char *fmt, ...) PRINTFFORMAT(4,5);
+ void adns__warn(adns_state ads, int serv, adns_query qu,
+                const char *fmt, ...) PRINTFFORMAT(4,5);
+ void adns__diag(adns_state ads, int serv, adns_query qu,
+                const char *fmt, ...) PRINTFFORMAT(4,5);
+ 
+ int adns__vbuf_ensure(vbuf *vb, int want);
+ int adns__vbuf_appendstr(vbuf *vb, const char *data); /* does not include nul */
+ int adns__vbuf_append(vbuf *vb, const byte *data, int len);
+ /* 1=>success, 0=>realloc failed */
+ void adns__vbuf_appendq(vbuf *vb, const byte *data, int len);
+ void adns__vbuf_init(vbuf *vb);
+ void adns__vbuf_free(vbuf *vb);
+ 
+ const char *adns__diag_domain(adns_state ads, int serv, adns_query qu,
+                              vbuf *vb, const byte *dgram, int dglen, int cbyte);
+ /* Unpicks a domain in a datagram and returns a string suitable for
+  * printing it as.  Never fails - if an error occurs, it will
+  * return some kind of string describing the error.
+  *
+  * serv may be -1 and qu may be 0.  vb must have been initialised,
+  * and will be left in an arbitrary consistent state.
+  *
+  * Returns either vb->buf, or a pointer to a string literal.  Do not modify
+  * vb before using the return value.
+  */
+ 
+ void adns__isort(void *array, int nobjs, int sz, void *tempbuf,
+                 int (*needswap)(void *context, const void *a, const void *b),
+                 void *context);
+ /* Does an insertion sort of array which must contain nobjs objects
+  * each sz bytes long.  tempbuf must point to a buffer at least
+  * sz bytes long.  needswap should return !0 if a>b (strictly, ie
+  * wrong order) 0 if a<=b (ie, order is fine).
+  */
+ 
+ void adns__sigpipe_protect(adns_state);
+ void adns__sigpipe_unprotect(adns_state);
+ /* If SIGPIPE protection is not disabled, will block all signals except
+  * SIGPIPE, and set SIGPIPE's disposition to SIG_IGN.  (And then restore.)
+  * Each call to _protect must be followed by a call to _unprotect before
+  * any significant amount of code gets to run, since the old signal mask
+  * is stored in the adns structure.
+  */
+ 
+ /* From transmit.c: */
+ 
+ adns_status adns__mkquery(adns_state ads, vbuf *vb, int *id_r,
+                          const char *owner, int ol,
+                          const typeinfo *typei, adns_queryflags flags);
+ /* Assembles a query packet in vb.  A new id is allocated and returned.
+  */
+ 
+ adns_status adns__mkquery_frdgram(adns_state ads, vbuf *vb, int *id_r,
+                                  const byte *qd_dgram, int qd_dglen, int qd_begin,
+                                  adns_rrtype type, adns_queryflags flags);
+ /* Same as adns__mkquery, but takes the owner domain from an existing datagram.
+  * That domain must be correct and untruncated.
+  */
+ 
+ void adns__querysend_tcp(adns_query qu, struct timeval now);
+ /* Query must be in state tcpw/tcpw; it will be sent if possible and
+  * no further processing can be done on it for now.  The connection
+  * might be broken, but no reconnect will be attempted.
+  */
+ 
+ void adns__query_send(adns_query qu, struct timeval now);
+ /* Query must be in state tosend/NONE; it will be moved to a new state,
+  * and no further processing can be done on it for now.
+  * (Resulting state is one of udp/timew, tcpwait/timew (if server not connected),
+  *  tcpsent/timew, child/childw or done/output.)
+  * __query_send may decide to use either UDP or TCP depending whether
+  * _qf_usevc is set (or has become set) and whether the query is too
+  * large.
+  */
+ 
+ /* From query.c: */
+ 
+ adns_status adns__internal_submit(adns_state ads, adns_query *query_r,
+                                  const typeinfo *typei, vbuf *qumsg_vb, int id,
+                                  adns_queryflags flags, struct timeval now,
+                                  const qcontext *ctx);
+ /* Submits a query (for internal use, called during external submits).
+  *
+  * The new query is returned in *query_r, or we return adns_s_nomemory.
+  *
+  * The query datagram should already have been assembled in qumsg_vb;
+  * the memory for it is _taken over_ by this routine whether it
+  * succeeds or fails (if it succeeds, the vbuf is reused for qu->vb).
+  *
+  * *ctx is copied byte-for-byte into the query.
+  *
+  * When the child query is done, ctx->callback will be called.  The
+  * child will already have been taken off both the global list of
+  * queries in ads and the list of children in the parent.  The child
+  * will be freed when the callback returns.  The parent will have been
+  * taken off the global childw queue.
+  *
+  * The callback should either call adns__query_done, if it is
+  * complete, or adns__query_fail, if an error has occurred, in which
+  * case the other children (if any) will be cancelled.  If the parent
+  * has more unfinished children (or has just submitted more) then the
+  * callback may choose to wait for them - it must then put the parent
+  * back on the childw queue.
+  */
+ 
+ void adns__search_next(adns_state ads, adns_query qu, struct timeval now);
+ /* Walks down the searchlist for a query with adns_qf_search.
+  * The query should have just had a negative response, or not had
+  * any queries sent yet, and should not be on any queue.
+  * The query_dgram if any will be freed and forgotten and a new
+  * one constructed from the search_* members of the query.
+  *
+  * Cannot fail (in case of error, calls adns__query_fail).
+  */
+ 
+ void *adns__alloc_interim(adns_query qu, size_t sz);
+ void *adns__alloc_preserved(adns_query qu, size_t sz);
+ /* Allocates some memory, and records which query it came from
+  * and how much there was.
+  *
+  * If an error occurs in the query, all the memory from _interim is
+  * simply freed.  If the query succeeds, one large buffer will be made
+  * which is big enough for all these allocations, and then
+  * adns__alloc_final will get memory from this buffer.
+  *
+  * _alloc_interim can fail (and return 0).
+  * The caller must ensure that the query is failed.
+  *
+  * The memory from _preserved is is kept and transferred into the
+  * larger buffer - unless we run out of memory, in which case it too
+  * is freed.  When you use _preserved you have to add code to the
+  * x_nomem error exit case in adns__makefinal_query to clear out the
+  * pointers you made to those allocations, because that's when they're
+  * thrown away; you should also make a note in the declaration of
+  * those pointer variables, to note that they are _preserved rather
+  * than _interim.  If they're in the answer, note it here:
+  *  answer->cname and answer->owner are _preserved.
+  */
+ 
+ void adns__transfer_interim(adns_query from, adns_query to, void *block, size_t sz);
+ /* Transfers an interim allocation from one query to another, so that
+  * the `to' query will have room for the data when we get to makefinal
+  * and so that the free will happen when the `to' query is freed
+  * rather than the `from' query.
+  *
+  * It is legal to call adns__transfer_interim with a null pointer; this
+  * has no effect.
+  *
+  * _transfer_interim also ensures that the expiry time of the `to' query
+  * is no later than that of the `from' query, so that child queries'
+  * TTLs get inherited by their parents.
+  */
+ 
+ void *adns__alloc_mine(adns_query qu, size_t sz);
+ /* Like _interim, but does not record the length for later
+  * copying into the answer.  This just ensures that the memory
+  * will be freed when we're done with the query.
+  */
+ 
+ void *adns__alloc_final(adns_query qu, size_t sz);
+ /* Cannot fail, and cannot return 0.
+  */
+ 
+ void adns__makefinal_block(adns_query qu, void **blpp, size_t sz);
+ void adns__makefinal_str(adns_query qu, char **strp);
+ 
+ void adns__reset_preserved(adns_query qu);
+ /* Resets all of the memory management stuff etc. to take account of
+  * only the _preserved stuff from _alloc_preserved.  Used when we find
+  * an error somewhere and want to just report the error (with perhaps
+  * CNAME, owner, etc. info), and also when we're halfway through RRs
+  * in a datagram and discover that we need to retry the query.
+  */
+ 
+ void adns__query_done(adns_query qu);
+ void adns__query_fail(adns_query qu, adns_status stat);
+ 
+ /* From reply.c: */
+ 
+ void adns__procdgram(adns_state ads, const byte *dgram, int len,
+                     int serv, int viatcp, struct timeval now);
+ /* This function is allowed to cause new datagrams to be constructed
+  * and sent, or even new queries to be started.  However,
+  * query-sending functions are not allowed to call any general event
+  * loop functions in case they accidentally call this.
+  *
+  * Ie, receiving functions may call sending functions.
+  * Sending functions may NOT call receiving functions.
+  */
+ 
+ /* From types.c: */
+ 
+ const typeinfo *adns__findtype(adns_rrtype type);
+ 
+ /* From parse.c: */
+ 
+ typedef struct {
+   adns_state ads;
+   adns_query qu;
+   int serv;
+   const byte *dgram;
+   int dglen, max, cbyte, namelen;
+   int *dmend_r;
+ } findlabel_state;
+ 
+ void adns__findlabel_start(findlabel_state *fls, adns_state ads,
+                           int serv, adns_query qu,
+                           const byte *dgram, int dglen, int max,
+                           int dmbegin, int *dmend_rlater);
+ /* Finds labels in a domain in a datagram.
+  *
+  * Call this routine first.
+  * dmend_rlater may be null.  ads (and of course fls) may not be.
+  * serv may be -1, qu may be null - they are for error reporting.
+  */
+ 
+ adns_status adns__findlabel_next(findlabel_state *fls, int *lablen_r, int *labstart_r);
+ /* Then, call this one repeatedly.
+  *
+  * It will return adns_s_ok if all is well, and tell you the length
+  * and start of successive labels.  labstart_r may be null, but
+  * lablen_r must not be.
+  *
+  * After the last label, it will return with *lablen_r zero.
+  * Do not then call it again; instead, just throw away the findlabel_state.
+  *
+  * *dmend_rlater will have been set to point to the next part of
+  * the datagram after the label (or after the uncompressed part,
+  * if compression was used).  *namelen_rlater will have been set
+  * to the length of the domain name (total length of labels plus
+  * 1 for each intervening dot).
+  *
+  * If the datagram appears to be truncated, *lablen_r will be -1.
+  * *dmend_rlater, *labstart_r and *namelen_r may contain garbage.
+  * Do not call _next again.
+  *
+  * There may also be errors, in which case *dmend_rlater,
+  * *namelen_rlater, *lablen_r and *labstart_r may contain garbage.
+  * Do not then call findlabel_next again.
+  */
+ 
+ typedef enum {
+   pdf_quoteok= 0x001
+ } parsedomain_flags;
+ 
+ adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu,
+                               vbuf *vb, parsedomain_flags flags,
+                               const byte *dgram, int dglen, int *cbyte_io, int max);
+ /* vb must already have been initialised; it will be reset if necessary.
+  * If there is truncation, vb->used will be set to 0; otherwise
+  * (if there is no error) vb will be null-terminated.
+  * If there is an error vb and *cbyte_io may be left indeterminate.
+  *
+  * serv may be -1 and qu may be 0 - they are used for error reporting only.
+  */
+ 
+ adns_status adns__parse_domain_more(findlabel_state *fls, adns_state ads,
+                                    adns_query qu, vbuf *vb, parsedomain_flags flags,
+                                    const byte *dgram);
+ /* Like adns__parse_domain, but you pass it a pre-initialised findlabel_state,
+  * for continuing an existing domain or some such of some kind.  Also, unlike
+  * _parse_domain, the domain data will be appended to vb, rather than replacing
+  * the existing contents.
+  */
+ 
+ adns_status adns__findrr(adns_query qu, int serv,
+                         const byte *dgram, int dglen, int *cbyte_io,
+                         int *type_r, int *class_r, unsigned long *ttl_r,
+                         int *rdlen_r, int *rdstart_r,
+                         int *ownermatchedquery_r);
+ /* Finds the extent and some of the contents of an RR in a datagram
+  * and does some checks.  The datagram is *dgram, length dglen, and
+  * the RR starts at *cbyte_io (which is updated afterwards to point
+  * to the end of the RR).
+  *
+  * The type, class, TTL and RRdata length and start are returned iff
+  * the corresponding pointer variables are not null.  type_r, class_r
+  * and ttl_r may not be null.  The TTL will be capped.
+  *
+  * If ownermatchedquery_r != 0 then the owner domain of this
+  * RR will be compared with that in the query (or, if the query
+  * has gone to a CNAME lookup, with the canonical name).
+  * In this case, *ownermatchedquery_r will be set to 0 or 1.
+  * The query datagram (or CNAME datagram) MUST be valid and not truncated.
+  *
+  * If there is truncation then *type_r will be set to -1 and
+  * *cbyte_io, *class_r, *rdlen_r, *rdstart_r and *eo_matched_r will be
+  * undefined.
+  *
+  * qu must obviously be non-null.
+  *
+  * If an error is returned then *type_r will be undefined too.
+  */
+ 
+ adns_status adns__findrr_anychk(adns_query qu, int serv,
+                                const byte *dgram, int dglen, int *cbyte_io,
+                                int *type_r, int *class_r, unsigned long *ttl_r,
+                                int *rdlen_r, int *rdstart_r,
+                                const byte *eo_dgram, int eo_dglen, int eo_cbyte,
+                                int *eo_matched_r);
+ /* Like adns__findrr_checked, except that the datagram and
+  * owner to compare with can be specified explicitly.
+  *
+  * If the caller thinks they know what the owner of the RR ought to
+  * be they can pass in details in eo_*: this is another (or perhaps
+  * the same datagram), and a pointer to where the putative owner
+  * starts in that datagram.  In this case *eo_matched_r will be set
+  * to 1 if the datagram matched or 0 if it did not.  Either
+  * both eo_dgram and eo_matched_r must both be non-null, or they
+  * must both be null (in which case eo_dglen and eo_cbyte will be ignored).
+  * The eo datagram and contained owner domain MUST be valid and
+  * untruncated.
+  */
+ 
+ void adns__update_expires(adns_query qu, unsigned long ttl, struct timeval now);
+ /* Updates the `expires' field in the query, so that it doesn't exceed
+  * now + ttl.
+  */
+ 
+ int vbuf__append_quoted1035(vbuf *vb, const byte *buf, int len);
+ 
+ /* From event.c: */
+ 
+ void adns__tcp_broken(adns_state ads, const char *what, const char *why);
+ /* what and why may be both 0, or both non-0. */
+ 
+ void adns__tcp_tryconnect(adns_state ads, struct timeval now);
+ 
+ void adns__autosys(adns_state ads, struct timeval now);
+ /* Make all the system calls we want to if the application wants us to.
+  * Must not be called from within adns internal processing functions,
+  * lest we end up in recursive descent !
+  */
+ 
+ void adns__must_gettimeofday(adns_state ads, const struct timeval **now_io,
+                             struct timeval *tv_buf);
+ 
+ int adns__pollfds(adns_state ads, struct pollfd pollfds_buf[MAX_POLLFDS]);
+ void adns__fdevents(adns_state ads,
+                    const struct pollfd *pollfds, int npollfds,
+                    int maxfd, const fd_set *readfds,
+                    const fd_set *writefds, const fd_set *exceptfds,
+                    struct timeval now, int *r_r);
+ int adns__internal_check(adns_state ads,
+                         adns_query *query_io,
+                         adns_answer **answer,
+                         void **context_r);
+ 
+ void adns__timeouts(adns_state ads, int act,
+                    struct timeval **tv_io, struct timeval *tvbuf,
+                    struct timeval now);
+ /* If act is !0, then this will also deal with the TCP connection
+  * if previous events broke it or require it to be connected.
+  */
+ 
+ /* From check.c: */
+ 
+ void adns__consistency(adns_state ads, adns_query qu, consistency_checks cc);
+ 
+ /* Useful static inline functions: */
+ 
+ static inline int ctype_whitespace(int c) { return c==' ' || c=='\n' || c=='\t'; }
+ static inline int ctype_digit(int c) { return c>='0' && c<='9'; }
+ static inline int ctype_alpha(int c) {
+   return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+ }
+ static inline int ctype_822special(int c) { return strchr("()<>@,;:\\\".[]",c) != 0; }
+ static inline int ctype_domainunquoted(int c) {
+   return ctype_alpha(c) || ctype_digit(c) || (strchr("-_/+",c) != 0);
+ }
+ 
+ static inline int errno_resources(int e) { return e==ENOMEM || e==ENOBUFS; }
+ 
+ /* Useful macros */
+ 
+ #define MEM_ROUND(sz) \
+   (( ((sz)+sizeof(union maxalign)-1) / sizeof(union maxalign) ) \
+    * sizeof(union maxalign) )
+ 
+ #define GETIL_B(cb) (((dgram)[(cb)++]) & 0x0ff)
+ #define GET_B(cb,tv) ((tv)= GETIL_B((cb)))
+ #define GET_W(cb,tv) ((tv)=0, (tv)|=(GETIL_B((cb))<<8), (tv)|=GETIL_B(cb), (tv))
+ #define GET_L(cb,tv) ( (tv)=0, \
+                       (tv)|=(GETIL_B((cb))<<24), \
+                       (tv)|=(GETIL_B((cb))<<16), \
+                       (tv)|=(GETIL_B((cb))<<8), \
+                       (tv)|=GETIL_B(cb), \
+                       (tv) )
+ 
+ #endif


ossp-pkg/adns/adns_parse.c -> 1.1.1.4

*** /dev/null    Sun Apr 28 21:30:37 2024
--- -    Sun Apr 28 21:31:46 2024
***************
*** 0 ****
--- 1,246 ----
+ /*
+  * parse.c
+  * - parsing assistance functions (mainly for domains inside datagrams)
+  */
+ /*
+  *  This file is
+  *    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
+  *
+  *  It is part of adns, which is
+  *    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
+  *    Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
+  *  
+  *  This program is free software; you can redistribute it and/or modify
+  *  it under the terms of the GNU General Public License as published by
+  *  the Free Software Foundation; either version 2, or (at your option)
+  *  any later version.
+  *  
+  *  This program is distributed in the hope that it will be useful,
+  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *  GNU General Public License for more details.
+  *  
+  *  You should have received a copy of the GNU General Public License
+  *  along with this program; if not, write to the Free Software Foundation,
+  *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+  */
+ 
+ #include "internal.h"
+ 
+ int vbuf__append_quoted1035(vbuf *vb, const byte *buf, int len) {
+   char qbuf[10];
+   int i, ch;
+   
+   while (len) {
+     qbuf[0]= 0;
+     for (i=0; i<len; i++) {
+       ch= buf[i];
+       if (ch <= ' ' || ch >= 127) {
+        sprintf(qbuf,"\\%03o",ch);
+        break;
+       } else if (!ctype_domainunquoted(ch)) {
+        sprintf(qbuf,"\\%c",ch);
+        break;
+       }
+     }
+     if (!adns__vbuf_append(vb,buf,i) || !adns__vbuf_append(vb,qbuf,strlen(qbuf)))
+       return 0;
+     if (i<len) i++;
+     buf+= i;
+     len-= i;
+   }
+   return 1;
+ }
+ 
+ void adns__findlabel_start(findlabel_state *fls, adns_state ads,
+                           int serv, adns_query qu,
+                           const byte *dgram, int dglen, int max,
+                           int dmbegin, int *dmend_rlater) {
+   fls->ads= ads;
+   fls->qu= qu;
+   fls->serv= serv;
+   fls->dgram= dgram;
+   fls->dglen= dglen;
+   fls->max= max;
+   fls->cbyte= dmbegin;
+   fls->namelen= 0;
+   fls->dmend_r= dmend_rlater;
+ }
+ 
+ adns_status adns__findlabel_next(findlabel_state *fls,
+                                 int *lablen_r, int *labstart_r) {
+   int lablen, jumpto;
+   const char *dgram;
+ 
+   dgram= fls->dgram;
+   for (;;) {
+     if (fls->cbyte >= fls->dglen) goto x_truncated;
+     if (fls->cbyte >= fls->max) goto x_badresponse;
+     GET_B(fls->cbyte,lablen);
+     if (!(lablen & 0x0c0)) break;
+     if ((lablen & 0x0c0) != 0x0c0) return adns_s_unknownformat;
+     if (fls->cbyte >= fls->dglen) goto x_truncated;
+     if (fls->cbyte >= fls->max) goto x_badresponse;
+     GET_B(fls->cbyte,jumpto);
+     jumpto |= (lablen&0x3f)<<8;
+     if (fls->dmend_r) *(fls->dmend_r)= fls->cbyte;
+     fls->cbyte= jumpto;
+     fls->dmend_r= 0; fls->max= fls->dglen+1;
+   }
+   if (labstart_r) *labstart_r= fls->cbyte;
+   if (lablen) {
+     if (fls->namelen) fls->namelen++;
+     fls->namelen+= lablen;
+     if (fls->namelen > DNS_MAXDOMAIN) return adns_s_answerdomaintoolong;
+     fls->cbyte+= lablen;
+     if (fls->cbyte > fls->dglen) goto x_truncated;
+     if (fls->cbyte > fls->max) goto x_badresponse;
+   } else {
+     if (fls->dmend_r) *(fls->dmend_r)= fls->cbyte;
+   }
+   *lablen_r= lablen;
+   return adns_s_ok;
+ 
+  x_truncated:
+   *lablen_r= -1;
+   return adns_s_ok;
+ 
+  x_badresponse: 
+   adns__diag(fls->ads,fls->serv,fls->qu,"label in domain runs beyond end of domain");
+   return adns_s_invalidresponse;
+ }
+ 
+ adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu,
+                               vbuf *vb, adns_queryflags flags,
+                               const byte *dgram, int dglen, int *cbyte_io, int max) {
+   findlabel_state fls;
+   
+   adns__findlabel_start(&fls,ads, serv,qu, dgram,dglen,max, *cbyte_io,cbyte_io);
+   vb->used= 0;
+   return adns__parse_domain_more(&fls,ads,qu, vb,flags,dgram);
+ }
+ 
+ adns_status adns__parse_domain_more(findlabel_state *fls, adns_state ads,
+                                    adns_query qu, vbuf *vb, parsedomain_flags flags,
+                                    const byte *dgram) {
+   int lablen, labstart, i, ch, first;
+   adns_status st;
+ 
+   first= 1;
+   for (;;) {
+     st= adns__findlabel_next(fls,&lablen,&labstart);
+     if (st) return st;
+     if (lablen<0) { vb->used=0; return adns_s_ok; }
+     if (!lablen) break;
+     if (first) {
+       first= 0;
+     } else {
+       if (!adns__vbuf_append(vb,".",1)) return adns_s_nomemory;
+     }
+     if (flags & pdf_quoteok) {
+       if (!vbuf__append_quoted1035(vb,dgram+labstart,lablen))
+        return adns_s_nomemory;
+     } else {
+       ch= dgram[labstart];
+       if (!ctype_alpha(ch) && !ctype_digit(ch)) return adns_s_answerdomaininvalid;
+       for (i= labstart+1; i<labstart+lablen; i++) {
+        ch= dgram[i];
+        if (ch != '-' && !ctype_alpha(ch) && !ctype_digit(ch))
+          return adns_s_answerdomaininvalid;
+       }
+       if (!adns__vbuf_append(vb,dgram+labstart,lablen))
+        return adns_s_nomemory;
+     }
+   }
+   if (!adns__vbuf_append(vb,"",1)) return adns_s_nomemory;
+   return adns_s_ok;
+ }
+        
+ adns_status adns__findrr_anychk(adns_query qu, int serv,
+                                const byte *dgram, int dglen, int *cbyte_io,
+                                int *type_r, int *class_r, unsigned long *ttl_r,
+                                int *rdlen_r, int *rdstart_r,
+                                const byte *eo_dgram, int eo_dglen, int eo_cbyte,
+                                int *eo_matched_r) {
+   findlabel_state fls, eo_fls;
+   int cbyte;
+   
+   int tmp, rdlen, mismatch;
+   unsigned long ttl;
+   int lablen, labstart, ch;
+   int eo_lablen, eo_labstart, eo_ch;
+   adns_status st;
+ 
+   cbyte= *cbyte_io;
+ 
+   adns__findlabel_start(&fls,qu->ads, serv,qu, dgram,dglen,dglen,cbyte,&cbyte);
+   if (eo_dgram) {
+     adns__findlabel_start(&eo_fls,qu->ads, -1,0, eo_dgram,eo_dglen,eo_dglen,eo_cbyte,0);
+     mismatch= 0;
+   } else {
+     mismatch= 1;
+   }
+   
+   for (;;) {
+     st= adns__findlabel_next(&fls,&lablen,&labstart);
+     if (st) return st;
+     if (lablen<0) goto x_truncated;
+ 
+     if (!mismatch) {
+       st= adns__findlabel_next(&eo_fls,&eo_lablen,&eo_labstart);
+       assert(!st); assert(eo_lablen>=0);
+       if (lablen != eo_lablen) mismatch= 1;
+       while (!mismatch && eo_lablen-- > 0) {
+        ch= dgram[labstart++]; if (ctype_alpha(ch)) ch &= ~32;
+        eo_ch= eo_dgram[eo_labstart++]; if (ctype_alpha(eo_ch)) eo_ch &= ~32;
+        if (ch != eo_ch) mismatch= 1;
+       }
+     }
+     if (!lablen) break;
+   }
+   if (eo_matched_r) *eo_matched_r= !mismatch;
+    
+   if (cbyte+10>dglen) goto x_truncated;
+   GET_W(cbyte,tmp); *type_r= tmp;
+   GET_W(cbyte,tmp); *class_r= tmp;
+ 
+   GET_L(cbyte,ttl);
+   if (ttl > MAXTTLBELIEVE) ttl= MAXTTLBELIEVE;
+   *ttl_r= ttl;
+   
+   GET_W(cbyte,rdlen); if (rdlen_r) *rdlen_r= rdlen;
+   if (rdstart_r) *rdstart_r= cbyte;
+   cbyte+= rdlen;
+   if (cbyte>dglen) goto x_truncated;
+   *cbyte_io= cbyte;
+   return adns_s_ok;
+ 
+  x_truncated:
+   *type_r= -1;
+   return 0;
+ }
+ 
+ adns_status adns__findrr(adns_query qu, int serv,
+                         const byte *dgram, int dglen, int *cbyte_io,
+                         int *type_r, int *class_r, unsigned long *ttl_r,
+                         int *rdlen_r, int *rdstart_r,
+                         int *ownermatchedquery_r) {
+   if (!ownermatchedquery_r) {
+     return adns__findrr_anychk(qu,serv,
+                               dgram,dglen,cbyte_io,
+                               type_r,class_r,ttl_r,rdlen_r,rdstart_r,
+                               0,0,0, 0);
+   } else if (!qu->cname_dgram) {
+     return adns__findrr_anychk(qu,serv,
+                               dgram,dglen,cbyte_io,
+                               type_r,class_r,ttl_r,rdlen_r,rdstart_r,
+                               qu->query_dgram,qu->query_dglen,DNS_HDRSIZE,
+                               ownermatchedquery_r);
+   } else {
+     return adns__findrr_anychk(qu,serv,
+                               dgram,dglen,cbyte_io,
+                               type_r,class_r,ttl_r,rdlen_r,rdstart_r,
+                               qu->cname_dgram,qu->cname_dglen,qu->cname_begin,
+                               ownermatchedquery_r);
+   }
+ }


ossp-pkg/adns/adns_poll.c -> 1.1.1.3

*** /dev/null    Sun Apr 28 21:30:37 2024
--- -    Sun Apr 28 21:31:46 2024
***************
*** 0 ****
--- 1,131 ----
+ /*
+  * poll.c
+  * - wrappers for poll(2)
+  */
+ /*
+  *  This file is
+  *    Copyright (C) 1997-1999 Ian Jackson <ian@davenant.greenend.org.uk>
+  *
+  *  It is part of adns, which is
+  *    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
+  *    Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
+  *  
+  *  This program is free software; you can redistribute it and/or modify
+  *  it under the terms of the GNU General Public License as published by
+  *  the Free Software Foundation; either version 2, or (at your option)
+  *  any later version.
+  *  
+  *  This program is distributed in the hope that it will be useful,
+  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *  GNU General Public License for more details.
+  *  
+  *  You should have received a copy of the GNU General Public License
+  *  along with this program; if not, write to the Free Software Foundation,
+  *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+  */
+ 
+ #include <limits.h>
+ #include <string.h>
+ 
+ #include "internal.h"
+ 
+ #ifdef HAVE_POLL
+ 
+ int adns_beforepoll(adns_state ads, struct pollfd *fds, int *nfds_io, int *timeout_io,
+                    const struct timeval *now) {
+   struct timeval tv_nowbuf, tv_tobuf, *tv_to;
+   int space, found, timeout_ms, r;
+   struct pollfd fds_tmp[MAX_POLLFDS];
+ 
+   adns__consistency(ads,0,cc_entex);
+ 
+   if (timeout_io) {
+     adns__must_gettimeofday(ads,&now,&tv_nowbuf);
+     if (!now) { *nfds_io= 0; r= 0; goto xit; }
+ 
+     timeout_ms= *timeout_io;
+     if (timeout_ms == -1) {
+       tv_to= 0;
+     } else {
+       tv_tobuf.tv_sec= timeout_ms / 1000;
+       tv_tobuf.tv_usec= (timeout_ms % 1000)*1000;
+       tv_to= &tv_tobuf;
+     }
+ 
+     adns__timeouts(ads, 0, &tv_to,&tv_tobuf, *now);
+ 
+     if (tv_to) {
+       assert(tv_to == &tv_tobuf);
+       timeout_ms= (tv_tobuf.tv_usec+999)/1000;
+       assert(tv_tobuf.tv_sec < (INT_MAX-timeout_ms)/1000);
+       timeout_ms += tv_tobuf.tv_sec*1000;
+     } else {
+       timeout_ms= -1;
+     }
+     *timeout_io= timeout_ms;
+   }
+   
+   space= *nfds_io;
+   if (space >= MAX_POLLFDS) {
+     found= adns__pollfds(ads,fds);
+     *nfds_io= found;
+   } else {
+     found= adns__pollfds(ads,fds_tmp);
+     *nfds_io= found;
+     if (space < found) { r= ERANGE; goto xit; }
+     memcpy(fds,fds_tmp,sizeof(struct pollfd)*found);
+   }
+   r= 0;
+ xit:
+   adns__consistency(ads,0,cc_entex);
+   return r;
+ }
+ 
+ void adns_afterpoll(adns_state ads, const struct pollfd *fds, int nfds,
+                    const struct timeval *now) {
+   struct timeval tv_buf;
+ 
+   adns__consistency(ads,0,cc_entex);
+   adns__must_gettimeofday(ads,&now,&tv_buf);
+   if (now) {
+     adns__timeouts(ads, 1, 0,0, *now);
+     adns__fdevents(ads, fds,nfds, 0,0,0,0, *now,0);
+   }
+   adns__consistency(ads,0,cc_entex);
+ }
+ 
+ int adns_wait_poll(adns_state ads,
+                   adns_query *query_io,
+                   adns_answer **answer_r,
+                   void **context_r) {
+   int r, nfds, to;
+   struct pollfd fds[MAX_POLLFDS];
+   
+   adns__consistency(ads,0,cc_entex);
+ 
+   for (;;) {
+     r= adns__internal_check(ads,query_io,answer_r,context_r);
+     if (r != EAGAIN) goto xit;
+     nfds= MAX_POLLFDS; to= -1;
+     adns_beforepoll(ads,fds,&nfds,&to,0);
+     r= poll(fds,nfds,to);
+     if (r == -1) {
+       if (errno == EINTR) {
+        if (ads->iflags & adns_if_eintr) { r= EINTR; goto xit; }
+       } else {
+        adns__diag(ads,-1,0,"poll failed in wait: %s",strerror(errno));
+        adns_globalsystemfailure(ads);
+       }
+     } else {
+       assert(r >= 0);
+       adns_afterpoll(ads,fds,nfds,0);
+     }
+   }
+ 
+  xit:
+   adns__consistency(ads,0,cc_entex);
+   return r;
+ }
+ 
+ #endif


ossp-pkg/adns/adns_query.c 1.1.1.4 -> 1.1.1.5

--- adns_query.c 2000/08/12 11:35:11     1.1.1.4
+++ adns_query.c 2000/09/19 15:46:49     1.1.1.5
@@ -10,7 +10,7 @@
  *
  *  It is part of adns, which is
  *    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
- *    Copyright (C) 1999 Tony Finch <dot@dotat.at>
+ *    Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
  *  
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by


ossp-pkg/adns/adns_reply.c 1.1.1.4 -> 1.1.1.5

--- adns_reply.c 2000/08/12 11:35:11     1.1.1.4
+++ adns_reply.c 2000/09/19 15:46:49     1.1.1.5
@@ -8,7 +8,7 @@
  *
  *  It is part of adns, which is
  *    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
- *    Copyright (C) 1999 Tony Finch <dot@dotat.at>
+ *    Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
  *  
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by


ossp-pkg/adns/adns_setup.c -> 1.1.1.3

*** /dev/null    Sun Apr 28 21:30:37 2024
--- -    Sun Apr 28 21:31:46 2024
***************
*** 0 ****
--- 1,643 ----
+ /*
+  * setup.c
+  * - configuration file parsing
+  * - management of global state
+  */
+ /*
+  *  This file is
+  *    Copyright (C) 1997-1999 Ian Jackson <ian@davenant.greenend.org.uk>
+  *
+  *  It is part of adns, which is
+  *    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
+  *    Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
+  *  
+  *  This program is free software; you can redistribute it and/or modify
+  *  it under the terms of the GNU General Public License as published by
+  *  the Free Software Foundation; either version 2, or (at your option)
+  *  any later version.
+  *  
+  *  This program is distributed in the hope that it will be useful,
+  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *  GNU General Public License for more details.
+  *  
+  *  You should have received a copy of the GNU General Public License
+  *  along with this program; if not, write to the Free Software Foundation,
+  *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+  */
+ 
+ #include <stdlib.h>
+ #include <errno.h>
+ #include <limits.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ 
+ #include <netdb.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ 
+ #include "internal.h"
+ 
+ static void readconfig(adns_state ads, const char *filename, int warnmissing);
+ 
+ static void addserver(adns_state ads, struct in_addr addr) {
+   int i;
+   struct server *ss;
+   
+   for (i=0; i<ads->nservers; i++) {
+     if (ads->servers[i].addr.s_addr == addr.s_addr) {
+       adns__debug(ads,-1,0,"duplicate nameserver %s ignored",inet_ntoa(addr));
+       return;
+     }
+   }
+   
+   if (ads->nservers>=MAXSERVERS) {
+     adns__diag(ads,-1,0,"too many nameservers, ignoring %s",inet_ntoa(addr));
+     return;
+   }
+ 
+   ss= ads->servers+ads->nservers;
+   ss->addr= addr;
+   ads->nservers++;
+ }
+ 
+ static void freesearchlist(adns_state ads) {
+   if (ads->nsearchlist) free(*ads->searchlist);
+   free(ads->searchlist);
+ }
+ 
+ static void saveerr(adns_state ads, int en) {
+   if (!ads->configerrno) ads->configerrno= en;
+ }
+ 
+ static void configparseerr(adns_state ads, const char *fn, int lno,
+                           const char *fmt, ...) {
+   va_list al;
+ 
+   saveerr(ads,EINVAL);
+   if (!ads->diagfile || (ads->iflags & adns_if_noerrprint)) return;
+ 
+   if (lno==-1) fprintf(ads->diagfile,"adns: %s: ",fn);
+   else fprintf(ads->diagfile,"adns: %s:%d: ",fn,lno);
+   va_start(al,fmt);
+   vfprintf(ads->diagfile,fmt,al);
+   va_end(al);
+   fputc('\n',ads->diagfile);
+ }
+ 
+ static int nextword(const char **bufp_io, const char **word_r, int *l_r) {
+   const char *p, *q;
+ 
+   p= *bufp_io;
+   while (ctype_whitespace(*p)) p++;
+   if (!*p) return 0;
+ 
+   q= p;
+   while (*q && !ctype_whitespace(*q)) q++;
+ 
+   *l_r= q-p;
+   *word_r= p;
+   *bufp_io= q;
+ 
+   return 1;
+ }
+ 
+ static void ccf_nameserver(adns_state ads, const char *fn, int lno, const char *buf) {
+   struct in_addr ia;
+   
+   if (!inet_aton(buf,&ia)) {
+     configparseerr(ads,fn,lno,"invalid nameserver address `%s'",buf);
+     return;
+   }
+   adns__debug(ads,-1,0,"using nameserver %s",inet_ntoa(ia));
+   addserver(ads,ia);
+ }
+ 
+ static void ccf_search(adns_state ads, const char *fn, int lno, const char *buf) {
+   const char *bufp, *word;
+   char *newchars, **newptrs, **pp;
+   int count, tl, l;
+ 
+   if (!buf) return;
+ 
+   bufp= buf;
+   count= 0;
+   tl= 0;
+   while (nextword(&bufp,&word,&l)) { count++; tl += l+1; }
+ 
+   newptrs= malloc(sizeof(char*)*count);  if (!newptrs) { saveerr(ads,errno); return; }
+   newchars= malloc(tl);  if (!newchars) { saveerr(ads,errno); free(newptrs); return; }
+ 
+   bufp= buf;
+   pp= newptrs;
+   while (nextword(&bufp,&word,&l)) {
+     *pp++= newchars;
+     memcpy(newchars,word,l);
+     newchars += l;
+     *newchars++ = 0;
+   }
+ 
+   freesearchlist(ads);
+   ads->nsearchlist= count;
+   ads->searchlist= newptrs;
+ }
+ 
+ static void ccf_sortlist(adns_state ads, const char *fn, int lno, const char *buf) {
+   const char *word;
+   char tbuf[200], *slash, *ep;
+   struct in_addr base, mask;
+   int l;
+   unsigned long initial, baselocal;
+ 
+   if (!buf) return;
+   
+   ads->nsortlist= 0;
+   while (nextword(&buf,&word,&l)) {
+     if (ads->nsortlist >= MAXSORTLIST) {
+       adns__diag(ads,-1,0,"too many sortlist entries, ignoring %.*s onwards",l,word);
+       return;
+     }
+ 
+     if (l >= sizeof(tbuf)) {
+       configparseerr(ads,fn,lno,"sortlist entry `%.*s' too long",l,word);
+       continue;
+     }
+     
+     memcpy(tbuf,word,l); tbuf[l]= 0;
+     slash= strchr(tbuf,'/');
+     if (slash) *slash++= 0;
+     
+     if (!inet_aton(tbuf,&base)) {
+       configparseerr(ads,fn,lno,"invalid address `%s' in sortlist",tbuf);
+       continue;
+     }
+ 
+     if (slash) {
+       if (strchr(slash,'.')) {
+        if (!inet_aton(slash,&mask)) {
+          configparseerr(ads,fn,lno,"invalid mask `%s' in sortlist",slash);
+          continue;
+        }
+        if (base.s_addr & ~mask.s_addr) {
+          configparseerr(ads,fn,lno,
+                         "mask `%s' in sortlist overlaps address `%s'",slash,tbuf);
+          continue;
+        }
+       } else {
+        initial= strtoul(slash,&ep,10);
+        if (*ep || initial>32) {
+          configparseerr(ads,fn,lno,"mask length `%s' invalid",slash);
+          continue;
+        }
+        mask.s_addr= htonl((0x0ffffffffUL) << (32-initial));
+       }
+     } else {
+       baselocal= ntohl(base.s_addr);
+       if (!baselocal & 0x080000000UL) /* class A */
+        mask.s_addr= htonl(0x0ff000000UL);
+       else if ((baselocal & 0x0c0000000UL) == 0x080000000UL)
+        mask.s_addr= htonl(0x0ffff0000UL); /* class B */
+       else if ((baselocal & 0x0f0000000UL) == 0x0e0000000UL)
+        mask.s_addr= htonl(0x0ff000000UL); /* class C */
+       else {
+        configparseerr(ads,fn,lno,
+                       "network address `%s' in sortlist is not in classed ranges,"
+                       " must specify mask explicitly", tbuf);
+        continue;
+       }
+     }
+ 
+     ads->sortlist[ads->nsortlist].base= base;
+     ads->sortlist[ads->nsortlist].mask= mask;
+     ads->nsortlist++;
+   }
+ }
+ 
+ static void ccf_options(adns_state ads, const char *fn, int lno, const char *buf) {
+   const char *word;
+   char *ep;
+   unsigned long v;
+   int l;
+ 
+   if (!buf) return;
+ 
+   while (nextword(&buf,&word,&l)) {
+     if (l==5 && !memcmp(word,"debug",5)) {
+       ads->iflags |= adns_if_debug;
+       continue;
+     }
+     if (l>=6 && !memcmp(word,"ndots:",6)) {
+       v= strtoul(word+6,&ep,10);
+       if (l==6 || ep != word+l || v > INT_MAX) {
+        configparseerr(ads,fn,lno,"option `%.*s' malformed or has bad value",l,word);
+        continue;
+       }
+       ads->searchndots= v;
+       continue;
+     }
+     if (l>=12 && !memcmp(word,"adns_checkc:",12)) {
+       if (!strcmp(word+12,"none")) {
+        ads->iflags &= ~adns_if_checkc_freq;
+        ads->iflags |= adns_if_checkc_entex;
+       } else if (!strcmp(word+12,"entex")) {
+        ads->iflags &= ~adns_if_checkc_freq;
+        ads->iflags |= adns_if_checkc_entex;
+       } else if (!strcmp(word+12,"freq")) {
+        ads->iflags |= adns_if_checkc_freq;
+       } else {
+        configparseerr(ads,fn,lno, "option adns_checkc has bad value `%s' "
+                       "(must be none, entex or freq", word+12);
+       }
+       continue;
+     }
+     adns__diag(ads,-1,0,"%s:%d: unknown option `%.*s'", fn,lno, l,word);
+   }
+ }
+ 
+ static void ccf_clearnss(adns_state ads, const char *fn, int lno, const char *buf) {
+   ads->nservers= 0;
+ }
+ 
+ static void ccf_include(adns_state ads, const char *fn, int lno, const char *buf) {
+   if (!*buf) {
+     configparseerr(ads,fn,lno,"`include' directive with no filename");
+     return;
+   }
+   readconfig(ads,buf,1);
+ }
+ 
+ static const struct configcommandinfo {
+   const char *name;
+   void (*fn)(adns_state ads, const char *fn, int lno, const char *buf);
+ } configcommandinfos[]= {
+   { "nameserver",        ccf_nameserver  },
+   { "domain",            ccf_search      },
+   { "search",            ccf_search      },
+   { "sortlist",          ccf_sortlist    },
+   { "options",           ccf_options     },
+   { "clearnameservers",  ccf_clearnss    },
+   { "include",           ccf_include     },
+   {  0                                   }
+ };
+ 
+ typedef union {
+   FILE *file;
+   const char *text;
+ } getline_ctx;
+ 
+ static int gl_file(adns_state ads, getline_ctx *src_io, const char *filename,
+                   int lno, char *buf, int buflen) {
+   FILE *file= src_io->file;
+   int c, i;
+   char *p;
+ 
+   p= buf;
+   buflen--;
+   i= 0;
+     
+   for (;;) { /* loop over chars */
+     if (i == buflen) {
+       adns__diag(ads,-1,0,"%s:%d: line too long, ignored",filename,lno);
+       goto x_badline;
+     }
+     c= getc(file);
+     if (!c) {
+       adns__diag(ads,-1,0,"%s:%d: line contains nul, ignored",filename,lno);
+       goto x_badline;
+     } else if (c == '\n') {
+       break;
+     } else if (c == EOF) {
+       if (ferror(file)) {
+        saveerr(ads,errno);
+        adns__diag(ads,-1,0,"%s:%d: read error: %s",filename,lno,strerror(errno));
+        return -1;
+       }
+       if (!i) return -1;
+       break;
+     } else {
+       *p++= c;
+       i++;
+     }
+   }
+ 
+   *p++= 0;
+   return i;
+ 
+  x_badline:
+   saveerr(ads,EINVAL);
+   while ((c= getc(file)) != EOF && c != '\n');
+   return -2;
+ }
+ 
+ static int gl_text(adns_state ads, getline_ctx *src_io, const char *filename,
+                   int lno, char *buf, int buflen) {
+   const char *cp= src_io->text;
+   int l;
+ 
+   if (!cp || !*cp) return -1;
+ 
+   if (*cp == ';' || *cp == '\n') cp++;
+   l= strcspn(cp,";\n");
+   src_io->text = cp+l;
+ 
+   if (l >= buflen) {
+     adns__diag(ads,-1,0,"%s:%d: line too long, ignored",filename,lno);
+     saveerr(ads,EINVAL);
+     return -2;
+   }
+     
+   memcpy(buf,cp,l);
+   buf[l]= 0;
+   return l;
+ }
+ 
+ static void readconfiggeneric(adns_state ads, const char *filename,
+                              int (*getline)(adns_state ads, getline_ctx*,
+                                             const char *filename, int lno,
+                                             char *buf, int buflen),
+                              /* Returns >=0 for success, -1 for EOF or error
+                               * (error will have been reported), or -2 for
+                               * bad line was encountered, try again.
+                               */
+                              getline_ctx gl_ctx) {
+   char linebuf[2000], *p, *q;
+   int lno, l, dirl;
+   const struct configcommandinfo *ccip;
+ 
+   for (lno=1;
+        (l= getline(ads,&gl_ctx, filename,lno, linebuf,sizeof(linebuf))) != -1;
+        lno++) {
+     if (l == -2) continue;
+     while (l>0 && ctype_whitespace(linebuf[l-1])) l--;
+     linebuf[l]= 0;
+     p= linebuf;
+     while (ctype_whitespace(*p)) p++;
+     if (*p == '#' || !*p) continue;
+     q= p;
+     while (*q && !ctype_whitespace(*q)) q++;
+     dirl= q-p;
+     for (ccip=configcommandinfos;
+         ccip->name && !(strlen(ccip->name)==dirl && !memcmp(ccip->name,p,q-p));
+         ccip++);
+     if (!ccip->name) {
+       adns__diag(ads,-1,0,"%s:%d: unknown configuration directive `%.*s'",
+                 filename,lno,q-p,p);
+       continue;
+     }
+     while (ctype_whitespace(*q)) q++;
+     ccip->fn(ads,filename,lno,q);
+   }
+ }
+ 
+ static const char *instrum_getenv(adns_state ads, const char *envvar) {
+   const char *value;
+ 
+   value= getenv(envvar);
+   if (!value) adns__debug(ads,-1,0,"environment variable %s not set",envvar);
+   else adns__debug(ads,-1,0,"environment variable %s set to `%s'",envvar,value);
+   return value;
+ }
+ 
+ static void readconfig(adns_state ads, const char *filename, int warnmissing) {
+   getline_ctx gl_ctx;
+   
+   gl_ctx.file= fopen(filename,"r");
+   if (!gl_ctx.file) {
+     if (errno == ENOENT) {
+       if (warnmissing)
+        adns__debug(ads,-1,0,"configuration file `%s' does not exist",filename);
+       return;
+     }
+     saveerr(ads,errno);
+     adns__diag(ads,-1,0,"cannot open configuration file `%s': %s",
+               filename,strerror(errno));
+     return;
+   }
+ 
+   readconfiggeneric(ads,filename,gl_file,gl_ctx);
+   
+   fclose(gl_ctx.file);
+ }
+ 
+ static void readconfigtext(adns_state ads, const char *text, const char *showname) {
+   getline_ctx gl_ctx;
+   
+   gl_ctx.text= text;
+   readconfiggeneric(ads,showname,gl_text,gl_ctx);
+ }
+   
+ static void readconfigenv(adns_state ads, const char *envvar) {
+   const char *filename;
+ 
+   if (ads->iflags & adns_if_noenv) {
+     adns__debug(ads,-1,0,"not checking environment variable `%s'",envvar);
+     return;
+   }
+   filename= instrum_getenv(ads,envvar);
+   if (filename) readconfig(ads,filename,1);
+ }
+ 
+ static void readconfigenvtext(adns_state ads, const char *envvar) {
+   const char *textdata;
+ 
+   if (ads->iflags & adns_if_noenv) {
+     adns__debug(ads,-1,0,"not checking environment variable `%s'",envvar);
+     return;
+   }
+   textdata= instrum_getenv(ads,envvar);
+   if (textdata) readconfigtext(ads,textdata,envvar);
+ }
+ 
+ 
+ int adns__setnonblock(adns_state ads, int fd) {
+   int r;
+   
+   r= fcntl(fd,F_GETFL,0); if (r<0) return errno;
+   r |= O_NONBLOCK;
+   r= fcntl(fd,F_SETFL,r); if (r<0) return errno;
+   return 0;
+ }
+ 
+ static int init_begin(adns_state *ads_r, adns_initflags flags, FILE *diagfile) {
+   adns_state ads;
+   
+   ads= malloc(sizeof(*ads)); if (!ads) return errno;
+ 
+   ads->iflags= flags;
+   ads->diagfile= diagfile;
+   ads->configerrno= 0;
+   LIST_INIT(ads->udpw);
+   LIST_INIT(ads->tcpw);
+   LIST_INIT(ads->childw);
+   LIST_INIT(ads->output);
+   ads->forallnext= 0;
+   ads->nextid= 0x311f;
+   ads->udpsocket= ads->tcpsocket= -1;
+   adns__vbuf_init(&ads->tcpsend);
+   adns__vbuf_init(&ads->tcprecv);
+   ads->tcprecv_skip= 0;
+   ads->nservers= ads->nsortlist= ads->nsearchlist= ads->tcpserver= 0;
+   ads->searchndots= 1;
+   ads->tcpstate= server_disconnected;
+   timerclear(&ads->tcptimeout);
+   ads->searchlist= 0;
+ 
+   *ads_r= ads;
+   return 0;
+ }
+ 
+ static int init_finish(adns_state ads) {
+   struct in_addr ia;
+   struct protoent *proto;
+   int r;
+   
+   if (!ads->nservers) {
+     if (ads->diagfile && ads->iflags & adns_if_debug)
+       fprintf(ads->diagfile,"adns: no nameservers, using localhost\n");
+     ia.s_addr= htonl(INADDR_LOOPBACK);
+     addserver(ads,ia);
+   }
+ 
+   proto= getprotobyname("udp"); if (!proto) { r= ENOPROTOOPT; goto x_free; }
+   ads->udpsocket= socket(AF_INET,SOCK_DGRAM,proto->p_proto);
+   if (ads->udpsocket<0) { r= errno; goto x_free; }
+ 
+   r= adns__setnonblock(ads,ads->udpsocket);
+   if (r) { r= errno; goto x_closeudp; }
+   
+   return 0;
+ 
+  x_closeudp:
+   close(ads->udpsocket);
+  x_free:
+   free(ads);
+   return r;
+ }
+ 
+ static void init_abort(adns_state ads) {
+   if (ads->nsearchlist) {
+     free(ads->searchlist[0]);
+     free(ads->searchlist);
+   }
+   free(ads);
+ }
+ 
+ int adns_init(adns_state *ads_r, adns_initflags flags, FILE *diagfile) {
+   adns_state ads;
+   const char *res_options, *adns_res_options;
+   int r;
+   
+   r= init_begin(&ads, flags, diagfile ? diagfile : stderr);
+   if (r) return r;
+   
+   res_options= instrum_getenv(ads,"RES_OPTIONS");
+   adns_res_options= instrum_getenv(ads,"ADNS_RES_OPTIONS");
+   ccf_options(ads,"RES_OPTIONS",-1,res_options);
+   ccf_options(ads,"ADNS_RES_OPTIONS",-1,adns_res_options);
+ 
+   readconfig(ads,"/etc/resolv.conf",1);
+   readconfig(ads,"/etc/resolv-adns.conf",0);
+   readconfigenv(ads,"RES_CONF");
+   readconfigenv(ads,"ADNS_RES_CONF");
+ 
+   readconfigenvtext(ads,"RES_CONF_TEXT");
+   readconfigenvtext(ads,"ADNS_RES_CONF_TEXT");
+ 
+   ccf_options(ads,"RES_OPTIONS",-1,res_options);
+   ccf_options(ads,"ADNS_RES_OPTIONS",-1,adns_res_options);
+ 
+   ccf_search(ads,"LOCALDOMAIN",-1,instrum_getenv(ads,"LOCALDOMAIN"));
+   ccf_search(ads,"ADNS_LOCALDOMAIN",-1,instrum_getenv(ads,"ADNS_LOCALDOMAIN"));
+ 
+   if (ads->configerrno && ads->configerrno != EINVAL) {
+     r= ads->configerrno;
+     init_abort(ads);
+     return r;
+   }
+ 
+   r= init_finish(ads);
+   if (r) return r;
+ 
+   adns__consistency(ads,0,cc_entex);
+   *ads_r= ads;
+   return 0;
+ }
+ 
+ int adns_init_strcfg(adns_state *ads_r, adns_initflags flags,
+                     FILE *diagfile, const char *configtext) {
+   adns_state ads;
+   int r;
+ 
+   r= init_begin(&ads, flags, diagfile);  if (r) return r;
+ 
+   readconfigtext(ads,configtext,"<supplied configuration text>");
+   if (ads->configerrno) {
+     r= ads->configerrno;
+     init_abort(ads);
+     return r;
+   }
+ 
+   r= init_finish(ads);  if (r) return r;
+   adns__consistency(ads,0,cc_entex);
+   *ads_r= ads;
+   return 0;
+ }
+ 
+ 
+ void adns_finish(adns_state ads) {
+   adns__consistency(ads,0,cc_entex);
+   for (;;) {
+     if (ads->udpw.head) adns_cancel(ads->udpw.head);
+     else if (ads->tcpw.head) adns_cancel(ads->tcpw.head);
+     else if (ads->childw.head) adns_cancel(ads->childw.head);
+     else if (ads->output.head) adns_cancel(ads->output.head);
+     else break;
+   }
+   close(ads->udpsocket);
+   if (ads->tcpsocket >= 0) close(ads->tcpsocket);
+   adns__vbuf_free(&ads->tcpsend);
+   adns__vbuf_free(&ads->tcprecv);
+   freesearchlist(ads);
+   free(ads);
+ }
+ 
+ void adns_forallqueries_begin(adns_state ads) {
+   adns__consistency(ads,0,cc_entex);
+   ads->forallnext=
+     ads->udpw.head ? ads->udpw.head :
+     ads->tcpw.head ? ads->tcpw.head :
+     ads->childw.head ? ads->childw.head :
+     ads->output.head;
+ }
+   
+ adns_query adns_forallqueries_next(adns_state ads, void **context_r) {
+   adns_query qu, nqu;
+ 
+   adns__consistency(ads,0,cc_entex);
+   nqu= ads->forallnext;
+   for (;;) {
+     qu= nqu;
+     if (!qu) return 0;
+     if (qu->next) {
+       nqu= qu->next;
+     } else if (qu == ads->udpw.tail) {
+       nqu=
+        ads->tcpw.head ? ads->tcpw.head :
+        ads->childw.head ? ads->childw.head :
+        ads->output.head;
+     } else if (qu == ads->tcpw.tail) {
+       nqu=
+        ads->childw.head ? ads->childw.head :
+        ads->output.head;
+     } else if (qu == ads->childw.tail) {
+       nqu= ads->output.head;
+     } else {
+       nqu= 0;
+     }
+     if (!qu->parent) break;
+   }
+   ads->forallnext= nqu;
+   if (context_r) *context_r= qu->ctx.ext;
+   return qu;
+ }


ossp-pkg/adns/adns_test.c 1.1.1.3 -> 1.1.1.4

--- adns_test.c  2000/08/12 11:35:14     1.1.1.3
+++ adns_test.c  2000/09/19 15:46:52     1.1.1.4
@@ -4,11 +4,11 @@
  */
 /*
  *  This file is
- *    Copyright (C) 1997-1999 Ian Jackson <ian@davenant.greenend.org.uk>
+ *    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
  *
  *  It is part of adns, which is
  *    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
- *    Copyright (C) 1999 Tony Finch <dot@dotat.at>
+ *    Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
  *  
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -33,12 +33,11 @@
 #include <string.h>
 #include <errno.h>
 
-#include "adns.h"
-
 #include "config.h"
+#include "adns.h"
 
-#ifndef OUTPUTSTREAM
-# define OUTPUTSTREAM stdout
+#ifdef ADNS_REGRESS_TEST
+# include "hredirect.h"
 #endif
 
 struct myctx {
@@ -220,6 +219,8 @@
   mcs= malloc(tc ? sizeof(*mcs)*qc*tc : 1);
   if (!mcs) { perror("malloc mcs"); quitnow(3); }
 
+  setvbuf(stdout,0,_IOLBF,0);
+  
   if (initstring) {
     r= adns_init_strcfg(&ads,
                         (adns_if_debug|adns_if_noautosys|adns_if_checkc_freq)
@@ -232,8 +233,6 @@
   }
   if (r) failure_errno("init",r);
 
-  setvbuf(stdout,0,_IOLBF,0);
-  
   for (qi=0; qi<qc; qi++) {
     fdom_split(fdomlist[qi],&domain,&qflags,ownflags,sizeof(ownflags));
     if (!consistsof(ownflags,"a")) usageerr("unknown ownqueryflag");


ossp-pkg/adns/adns_transmit.c 1.1.1.4 -> 1.1.1.5

--- adns_transmit.c      2000/08/12 11:35:12     1.1.1.4
+++ adns_transmit.c      2000/09/19 15:46:50     1.1.1.5
@@ -9,7 +9,7 @@
  *
  *  It is part of adns, which is
  *    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
- *    Copyright (C) 1999 Tony Finch <dot@dotat.at>
+ *    Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
  *  
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by


ossp-pkg/adns/adns_tvarith.c -> 1.1.1.3

*** /dev/null    Sun Apr 28 21:30:37 2024
--- -    Sun Apr 28 21:31:46 2024
***************
*** 0 ****
--- 1,41 ----
+ /*
+  * tvarith.h
+  * - static inline functions for doing arithmetic on timevals
+  */
+ /*
+  *  This file is
+  *    Copyright (C) 1997-1999 Ian Jackson <ian@davenant.greenend.org.uk>
+  *
+  *  It is part of adns, which is
+  *    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
+  *    Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
+  *
+  *  This program is free software; you can redistribute it and/or modify
+  *  it under the terms of the GNU General Public License as published by
+  *  the Free Software Foundation; either version 2, or (at your option)
+  *  any later version.
+  *
+  *  This program is distributed in the hope that it will be useful,
+  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *  GNU General Public License for more details.
+  *
+  *  You should have received a copy of the GNU General Public License
+  *  along with this program; if not, write to the Free Software Foundation,
+  *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  */
+ 
+ #ifndef ADNS_TVARITH_H_INCLUDED
+ #define ADNS_TVARITH_H_INCLUDED
+ 
+ static inline void timevaladd(struct timeval *tv_io, long ms) {
+   struct timeval tmp;
+   assert(ms>=0);
+   tmp= *tv_io;
+   tmp.tv_usec += (ms%1000)*1000;
+   tmp.tv_sec += ms/1000;
+   if (tmp.tv_usec >= 1000000) { tmp.tv_sec++; tmp.tv_usec -= 1000000; }
+   *tv_io= tmp;
+ }
+ 
+ #endif


ossp-pkg/adns/adns_types.c -> 1.1.1.3

*** /dev/null    Sun Apr 28 21:30:37 2024
--- -    Sun Apr 28 21:31:46 2024
***************
*** 0 ****
--- 1,1034 ----
+ /*
+  * types.c
+  * - RR-type-specific code, and the machinery to call it
+  */
+ /*
+  *  This file is
+  *    Copyright (C) 1997-1999 Ian Jackson <ian@davenant.greenend.org.uk>
+  *
+  *  It is part of adns, which is
+  *    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
+  *    Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
+  *  
+  *  This program is free software; you can redistribute it and/or modify
+  *  it under the terms of the GNU General Public License as published by
+  *  the Free Software Foundation; either version 2, or (at your option)
+  *  any later version.
+  *  
+  *  This program is distributed in the hope that it will be useful,
+  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  *  GNU General Public License for more details.
+  *  
+  *  You should have received a copy of the GNU General Public License
+  *  along with this program; if not, write to the Free Software Foundation,
+  *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+  */
+ 
+ #include <stdlib.h>
+ 
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ 
+ #include "internal.h"
+ 
+ #define R_NOMEM           return adns_s_nomemory
+ #define CSP_ADDSTR(s)     do { if (!adns__vbuf_appendstr(vb,(s))) R_NOMEM; } while (0)
+ 
+ /*
+  * order of sections:
+  *
+  * _string                    (pap)
+  * _textdata, _qstring        (csp)
+  * _str                       (mf,cs)
+  * _intstr                    (mf,csp,cs)
+  * _manyistr                  (mf,cs)
+  * _txt                       (pa)
+  * _inaddr                    (pa,dip,di)
+  * _addr                      (pa,di,csp,cs)
+  * _domain                    (pap)
+  * _host_raw                  (pa)
+  * _hostaddr                  (pap,pa,dip,di,mfp,mf,csp,cs +pap_findaddrs)
+  * _mx_raw                    (pa,di)
+  * _mx                        (pa,di)
+  * _inthostaddr               (mf,cs)
+  * _ptr                       (pa)
+  * _strpair                   (mf,cs)
+  * _intstrpair                (mf,cs)
+  * _hinfo                     (pa)
+  * _mailbox                   (pap +pap_mailbox822)
+  * _rp                        (pa)
+  * _soa                       (pa,mf,cs)
+  * _flat                      (mf)
+  *
+  * within each section:
+  *    pap_*
+  *    pa_*
+  *    dip_*
+  *    di_*
+  *    mfp_*
+  *    mf_*
+  *    csp_*
+  *    cs_*
+  */
+ 
+ /*
+  * _qstring               (pap,csp)
+  */
+ 
+ static adns_status pap_qstring(const parseinfo *pai, int *cbyte_io, int max,
+                              int *len_r, char **str_r) {
+   /* Neither len_r nor str_r may be null.
+    * End of datagram (overrun) is indicated by returning adns_s_invaliddata;
+    */
+   const byte *dgram= pai->dgram;
+   int l, cbyte;
+   char *str;
+ 
+   cbyte= *cbyte_io;
+ 
+   if (cbyte >= max) return adns_s_invaliddata;
+   GET_B(cbyte,l);
+   if (cbyte+l > max) return adns_s_invaliddata;
+   
+   str= adns__alloc_interim(pai->qu, l+1);
+   if (!str) R_NOMEM;
+   
+   str[l]= 0;
+   memcpy(str,dgram+cbyte,l);
+ 
+   *len_r= l;
+   *str_r= str;
+   *cbyte_io= cbyte+l;
+   
+   return adns_s_ok;
+ }
+ 
+ static adns_status csp_qstring(vbuf *vb, const char *dp, int len) {
+   unsigned char ch;
+   char buf[10];
+   int cn;
+ 
+   CSP_ADDSTR("\"");
+   for (cn=0; cn<len; cn++) {
+     ch= *dp++;
+     if (ch == '\\') {
+       CSP_ADDSTR("\\\\");
+     } else if (ch == '"') {
+       CSP_ADDSTR("\\\"");
+     } else if (ch >= 32 && ch <= 126) {
+       if (!adns__vbuf_append(vb,&ch,1)) R_NOMEM;
+     } else {
+       sprintf(buf,"\\x%02x",ch);
+       CSP_ADDSTR(buf);
+     }
+   }
+   CSP_ADDSTR("\"");
+   
+   return adns_s_ok;
+ }
+ 
+ /*
+  * _str  (mf)
+  */
+ 
+ static void mf_str(adns_query qu, void *datap) {
+   char **rrp= datap;
+ 
+   adns__makefinal_str(qu,rrp);
+ }
+ 
+ /*
+  * _intstr  (mf)
+  */
+ 
+ static void mf_intstr(adns_query qu, void *datap) {
+   adns_rr_intstr *rrp= datap;
+ 
+   adns__makefinal_str(qu,&rrp->str);
+ }
+ 
+ /*
+  * _manyistr   (mf)
+  */
+ 
+ static void mf_manyistr(adns_query qu, void *datap) {
+   adns_rr_intstr **rrp= datap;
+   adns_rr_intstr *te, *table;
+   void *tablev;
+   int tc;
+ 
+   for (tc=0, te= *rrp; te->i >= 0; te++, tc++);
+   tablev= *rrp;
+   adns__makefinal_block(qu,&tablev,sizeof(*te)*(tc+1));
+   *rrp= table= tablev;
+   for (te= *rrp; te->i >= 0; te++)
+     adns__makefinal_str(qu,&te->str);
+ }
+ 
+ /*
+  * _txt   (pa,cs)
+  */
+ 
+ static adns_status pa_txt(const parseinfo *pai, int cbyte, int max, void *datap) {
+   adns_rr_intstr **rrp= datap, *table, *te;
+   const byte *dgram= pai->dgram;
+   int ti, tc, l, startbyte;
+   adns_status st;
+ 
+   startbyte= cbyte;
+   if (cbyte >= max) return adns_s_invaliddata;
+   tc= 0;
+   while (cbyte < max) {
+     GET_B(cbyte,l);
+     cbyte+= l;
+     tc++;
+   }
+   if (cbyte != max || !tc) return adns_s_invaliddata;
+ 
+   table= adns__alloc_interim(pai->qu,sizeof(*table)*(tc+1));
+   if (!table) R_NOMEM;
+ 
+   for (cbyte=startbyte, ti=0, te=table; ti<tc; ti++, te++) {
+     st= pap_qstring(pai, &cbyte, max, &te->i, &te->str);
+     if (st) return st;
+   }
+   assert(cbyte == max);
+ 
+   te->i= -1;
+   te->str= 0;
+   
+   *rrp= table;
+   return adns_s_ok;
+ }
+ 
+ static adns_status cs_txt(vbuf *vb, const void *datap) {
+   const adns_rr_intstr *const *rrp= datap;
+   const adns_rr_intstr *current;
+   adns_status st;
+   int spc;
+ 
+   for (current= *rrp, spc=0;  current->i >= 0;  current++, spc=1) {
+     if (spc) CSP_ADDSTR(" ");
+     st= csp_qstring(vb,current->str,current->i); if (st) return st;
+   }
+   return adns_s_ok;
+ }
+ 
+ /*
+  * _hinfo   (cs)
+  */
+ 
+ static adns_status cs_hinfo(vbuf *vb, const void *datap) {
+   const adns_rr_intstrpair *rrp= datap;
+   adns_status st;
+ 
+   st= csp_qstring(vb,rrp->array[0].str,rrp->array[0].i);  if (st) return st;
+   CSP_ADDSTR(" ");
+   st= csp_qstring(vb,rrp->array[1].str,rrp->array[1].i);  if (st) return st;
+   return adns_s_ok;
+ }
+ 
+ /*
+  * _inaddr   (pa,dip,di)
+  */
+ 
+ static adns_status pa_inaddr(const parseinfo *pai, int cbyte, int max, void *datap) {
+   struct in_addr *storeto= datap;
+   
+   if (max-cbyte != 4) return adns_s_invaliddata;
+   memcpy(storeto, pai->dgram + cbyte, 4);
+   return adns_s_ok;
+ }
+ 
+ static int search_sortlist(adns_state ads, struct in_addr ad) {
+   const struct sortlist *slp;
+   int i;
+   
+   for (i=0, slp=ads->sortlist;
+        i<ads->nsortlist && !((ad.s_addr & slp->mask.s_addr) == slp->base.s_addr);
+        i++, slp++);
+   return i;
+ }
+ 
+ static int dip_inaddr(adns_state ads, struct in_addr a, struct in_addr b) {
+   int ai, bi;
+   
+   if (!ads->nsortlist) return 0;
+ 
+   ai= search_sortlist(ads,a);
+   bi= search_sortlist(ads,b);
+   return bi<ai;
+ }
+ 
+ static int di_inaddr(adns_state ads, const void *datap_a, const void *datap_b) {
+   const struct in_addr *ap= datap_a, *bp= datap_b;
+ 
+   return dip_inaddr(ads,*ap,*bp);
+ }
+ 
+ static adns_status cs_inaddr(vbuf *vb, const void *datap) {
+   const struct in_addr *rrp= datap, rr= *rrp;
+   const char *ia;
+ 
+   ia= inet_ntoa(rr); assert(ia);
+   CSP_ADDSTR(ia);
+   return adns_s_ok;
+ }
+ 
+ /*
+  * _addr   (pa,di,csp,cs)
+  */
+ 
+ static adns_status pa_addr(const parseinfo *pai, int cbyte, int max, void *datap) {
+   adns_rr_addr *storeto= datap;
+   const byte *dgram= pai->dgram;
+ 
+   if (max-cbyte != 4) return adns_s_invaliddata;
+   storeto->len= sizeof(storeto->addr.inet);
+   memset(&storeto->addr,0,sizeof(storeto->addr.inet));
+   storeto->addr.inet.sin_family= AF_INET;
+   memcpy(&storeto->addr.inet.sin_addr,dgram+cbyte,4);
+   return adns_s_ok;
+ }
+ 
+ static int di_addr(adns_state ads, const void *datap_a, const void *datap_b) {
+   const adns_rr_addr *ap= datap_a, *bp= datap_b;
+ 
+   assert(ap->addr.sa.sa_family == AF_INET);
+   return dip_inaddr(ads, ap->addr.inet.sin_addr, bp->addr.inet.sin_addr);
+ }
+ 
+ static int div_addr(void *context, const void *datap_a, const void *datap_b) {
+   const adns_state ads= context;
+ 
+   return di_addr(ads, datap_a, datap_b);
+ }                   
+ 
+ static adns_status csp_addr(vbuf *vb, const adns_rr_addr *rrp) {
+   const char *ia;
+   static char buf[30];
+ 
+   switch (rrp->addr.inet.sin_family) {
+   case AF_INET:
+     CSP_ADDSTR("INET ");
+     ia= inet_ntoa(rrp->addr.inet.sin_addr); assert(ia);
+     CSP_ADDSTR(ia);
+     break;
+   default:
+     sprintf(buf,"AF=%u",rrp->addr.sa.sa_family);
+     CSP_ADDSTR(buf);
+     break;
+   }
+   return adns_s_ok;
+ }
+ 
+ static adns_status cs_addr(vbuf *vb, const void *datap) {
+   const adns_rr_addr *rrp= datap;
+ 
+   return csp_addr(vb,rrp);
+ }
+ 
+ /*
+  * _domain      (pap,csp,cs)
+  * _dom_raw     (pa)
+  */
+ 
+ static adns_status pap_domain(const parseinfo *pai, int *cbyte_io, int max,
+                              char **domain_r, parsedomain_flags flags) {
+   adns_status st;
+   char *dm;
+   
+   st= adns__parse_domain(pai->qu->ads, pai->serv, pai->qu, &pai->qu->vb, flags,
+                         pai->dgram,pai->dglen, cbyte_io, max);
+   if (st) return st;
+   if (!pai->qu->vb.used) return adns_s_invaliddata;
+ 
+   dm= adns__alloc_interim(pai->qu, pai->qu->vb.used+1);
+   if (!dm) R_NOMEM;
+ 
+   dm[pai->qu->vb.used]= 0;
+   memcpy(dm,pai->qu->vb.buf,pai->qu->vb.used);
+   
+   *domain_r= dm;
+   return adns_s_ok;
+ }
+ 
+ static adns_status csp_domain(vbuf *vb, const char *domain) {
+   CSP_ADDSTR(domain);
+   if (!*domain) CSP_ADDSTR(".");
+   return adns_s_ok;
+ }
+ 
+ static adns_status cs_domain(vbuf *vb, const void *datap) {
+   const char *const *domainp= datap;
+   return csp_domain(vb,*domainp);
+ }
+ 
+ static adns_status pa_dom_raw(const parseinfo *pai, int cbyte, int max, void *datap) {
+   char **rrp= datap;
+   adns_status st;
+ 
+   st= pap_domain(pai, &cbyte, max, rrp, pdf_quoteok);
+   if (st) return st;
+   
+   if (cbyte != max) return adns_s_invaliddata;
+   return adns_s_ok;
+ }
+ 
+ /*
+  * _host_raw   (pa)
+  */
+ 
+ static adns_status pa_host_raw(const parseinfo *pai, int cbyte, int max, void *datap) {
+   char **rrp= datap;
+   adns_status st;
+ 
+   st= pap_domain(pai, &cbyte, max, rrp,
+                 pai->qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0);
+   if (st) return st;
+   
+   if (cbyte != max) return adns_s_invaliddata;
+   return adns_s_ok;
+ }
+ 
+ /*
+  * _hostaddr   (pap,pa,dip,di,mfp,mf,csp,cs +icb_hostaddr, pap_findaddrs)
+  */
+ 
+ static adns_status pap_findaddrs(const parseinfo *pai, adns_rr_hostaddr *ha,
+                                 int *cbyte_io, int count, int dmstart) {
+   int rri, naddrs;
+   int type, class, rdlen, rdstart, ownermatched;
+   unsigned long ttl;
+   adns_status st;
+   
+   for (rri=0, naddrs=-1; rri<count; rri++) {
+     st= adns__findrr_anychk(pai->qu, pai->serv, pai->dgram, pai->dglen, cbyte_io,
+                            &type, &class, &ttl, &rdlen, &rdstart,
+                            pai->dgram, pai->dglen, dmstart, &ownermatched);
+     if (st) return st;
+     if (!ownermatched || class != DNS_CLASS_IN || type != adns_r_a) {
+       if (naddrs>0) break; else continue;
+     }
+     if (naddrs == -1) {
+       naddrs= 0;
+     }
+     if (!adns__vbuf_ensure(&pai->qu->vb, (naddrs+1)*sizeof(adns_rr_addr))) R_NOMEM;
+     adns__update_expires(pai->qu,ttl,pai->now);
+     st= pa_addr(pai, rdstart,rdstart+rdlen,
+                pai->qu->vb.buf + naddrs*sizeof(adns_rr_addr));
+     if (st) return st;
+     naddrs++;
+   }
+   if (naddrs >= 0) {
+     ha->addrs= adns__alloc_interim(pai->qu, naddrs*sizeof(adns_rr_addr));
+     if (!ha->addrs) R_NOMEM;
+     memcpy(ha->addrs, pai->qu->vb.buf, naddrs*sizeof(adns_rr_addr));
+     ha->naddrs= naddrs;
+     ha->astatus= adns_s_ok;
+ 
+     adns__isort(ha->addrs, naddrs, sizeof(adns_rr_addr), pai->qu->vb.buf,
+                div_addr, pai->ads);
+   }
+   return adns_s_ok;
+ }
+ 
+ static void icb_hostaddr(adns_query parent, adns_query child) {
+   adns_answer *cans= child->answer;
+   adns_rr_hostaddr *rrp= child->ctx.info.hostaddr;
+   adns_state ads= parent->ads;
+   adns_status st;
+ 
+   st= cans->status;
+   rrp->astatus= st;
+   rrp->naddrs= (st>0 && st<=adns_s_max_tempfail) ? -1 : cans->nrrs;
+   rrp->addrs= cans->rrs.addr;
+   adns__transfer_interim(child, parent, rrp->addrs, rrp->naddrs*sizeof(adns_rr_addr));
+ 
+   if (parent->children.head) {
+     LIST_LINK_TAIL(ads->childw,parent);
+   } else {
+     adns__query_done(parent);
+   }
+ }
+ 
+ static adns_status pap_hostaddr(const parseinfo *pai, int *cbyte_io,
+                                int max, adns_rr_hostaddr *rrp) {
+   adns_status st;
+   int dmstart, cbyte;
+   qcontext ctx;
+   int id;
+   adns_query nqu;
+   adns_queryflags nflags;
+ 
+   dmstart= cbyte= *cbyte_io;
+   st= pap_domain(pai, &cbyte, max, &rrp->host,
+                 pai->qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0);
+   if (st) return st;
+   *cbyte_io= cbyte;
+ 
+   rrp->astatus= adns_s_ok;
+   rrp->naddrs= -1;
+   rrp->addrs= 0;
+ 
+   cbyte= pai->nsstart;
+ 
+   st= pap_findaddrs(pai, rrp, &cbyte, pai->nscount, dmstart);
+   if (st) return st;
+   if (rrp->naddrs != -1) return adns_s_ok;
+ 
+   st= pap_findaddrs(pai, rrp, &cbyte, pai->arcount, dmstart);
+   if (st) return st;
+   if (rrp->naddrs != -1) return adns_s_ok;
+ 
+   st= adns__mkquery_frdgram(pai->ads, &pai->qu->vb, &id,
+                            pai->dgram, pai->dglen, dmstart,
+                            adns_r_addr, adns_qf_quoteok_query);
+   if (st) return st;
+ 
+   ctx.ext= 0;
+   ctx.callback= icb_hostaddr;
+   ctx.info.hostaddr= rrp;
+   
+   nflags= adns_qf_quoteok_query;
+   if (!(pai->qu->flags & adns_qf_cname_loose)) nflags |= adns_qf_cname_forbid;
+   
+   st= adns__internal_submit(pai->ads, &nqu, adns__findtype(adns_r_addr),
+                            &pai->qu->vb, id, nflags, pai->now, &ctx);
+   if (st) return st;
+ 
+   nqu->parent= pai->qu;
+   LIST_LINK_TAIL_PART(pai->qu->children,nqu,siblings.);
+ 
+   return adns_s_ok;
+ }
+ 
+ static adns_status pa_hostaddr(const parseinfo *pai, int cbyte, int max, void *datap) {
+   adns_rr_hostaddr *rrp= datap;
+   adns_status st;
+ 
+   st= pap_hostaddr(pai, &cbyte, max, rrp);
+   if (st) return st;
+   if (cbyte != max) return adns_s_invaliddata;
+ 
+   return adns_s_ok;
+ }
+ 
+ static int dip_hostaddr(adns_state ads, const adns_rr_hostaddr *ap, const adns_rr_hostaddr *bp) {
+   if (ap->astatus != bp->astatus) return ap->astatus;
+   if (ap->astatus) return 0;
+ 
+   assert(ap->addrs[0].addr.sa.sa_family == AF_INET);
+   assert(bp->addrs[0].addr.sa.sa_family == AF_INET);
+   return dip_inaddr(ads,
+                    ap->addrs[0].addr.inet.sin_addr,
+                    bp->addrs[0].addr.inet.sin_addr);
+ }
+ 
+ static int di_hostaddr(adns_state ads, const void *datap_a, const void *datap_b) {
+   const adns_rr_hostaddr *ap= datap_a, *bp= datap_b;
+ 
+   return dip_hostaddr(ads, ap,bp);
+ }
+ 
+ static void mfp_hostaddr(adns_query qu, adns_rr_hostaddr *rrp) {
+   void *tablev;
+ 
+   adns__makefinal_str(qu,&rrp->host);
+   tablev= rrp->addrs;
+   adns__makefinal_block(qu, &tablev, rrp->naddrs*sizeof(*rrp->addrs));
+   rrp->addrs= tablev;
+ }
+ 
+ static void mf_hostaddr(adns_query qu, void *datap) {
+   adns_rr_hostaddr *rrp= datap;
+ 
+   mfp_hostaddr(qu,rrp);
+ }
+ 
+ static adns_status csp_hostaddr(vbuf *vb, const adns_rr_hostaddr *rrp) {
+   const char *errstr;
+   adns_status st;
+   char buf[20];
+   int i;
+ 
+   st= csp_domain(vb,rrp->host);  if (st) return st;
+ 
+   CSP_ADDSTR(" ");
+   CSP_ADDSTR(adns_errtypeabbrev(rrp->astatus));
+ 
+   sprintf(buf," %d ",rrp->astatus);
+   CSP_ADDSTR(buf);
+ 
+   CSP_ADDSTR(adns_errabbrev(rrp->astatus));
+   CSP_ADDSTR(" ");
+ 
+   errstr= adns_strerror(rrp->astatus);
+   st= csp_qstring(vb,errstr,strlen(errstr));  if (st) return st;
+   
+   if (rrp->naddrs >= 0) {
+     CSP_ADDSTR(" (");
+     for (i=0; i<rrp->naddrs; i++) {
+       CSP_ADDSTR(" ");
+       st= csp_addr(vb,&rrp->addrs[i]);
+     }
+     CSP_ADDSTR(" )");
+   } else {
+     CSP_ADDSTR(" ?");
+   }
+   return adns_s_ok;
+ }
+ 
+ static adns_status cs_hostaddr(vbuf *vb, const void *datap) {
+   const adns_rr_hostaddr *rrp= datap;
+ 
+   return csp_hostaddr(vb,rrp);
+ }
+ 
+ /*
+  * _mx_raw   (pa,di)
+  */
+ 
+ static adns_status pa_mx_raw(const parseinfo *pai, int cbyte, int max, void *datap) {
+   const byte *dgram= pai->dgram;
+   adns_rr_intstr *rrp= datap;
+   adns_status st;
+   int pref;
+ 
+   if (cbyte+2 > max) return adns_s_invaliddata;
+   GET_W(cbyte,pref);
+   rrp->i= pref;
+   st= pap_domain(pai, &cbyte, max, &rrp->str,
+                 pai->qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0);
+   if (st) return st;
+   
+   if (cbyte != max) return adns_s_invaliddata;
+   return adns_s_ok;
+ }
+ 
+ static int di_mx_raw(adns_state ads, const void *datap_a, const void *datap_b) {
+   const adns_rr_intstr *ap= datap_a, *bp= datap_b;
+ 
+   if (ap->i < bp->i) return 0;
+   if (ap->i > bp->i) return 1;
+   return 0;
+ }
+ 
+ /*
+  * _mx   (pa,di)
+  */
+ 
+ static adns_status pa_mx(const parseinfo *pai, int cbyte, int max, void *datap) {
+   const byte *dgram= pai->dgram;
+   adns_rr_inthostaddr *rrp= datap;
+   adns_status st;
+   int pref;
+ 
+   if (cbyte+2 > max) return adns_s_invaliddata;
+   GET_W(cbyte,pref);
+   rrp->i= pref;
+   st= pap_hostaddr(pai, &cbyte, max, &rrp->ha);
+   if (st) return st;
+   
+   if (cbyte != max) return adns_s_invaliddata;
+   return adns_s_ok;
+ }
+ 
+ static int di_mx(adns_state ads, const void *datap_a, const void *datap_b) {
+   const adns_rr_inthostaddr *ap= datap_a, *bp= datap_b;
+ 
+   if (ap->i < bp->i) return 0;
+   if (ap->i > bp->i) return 1;
+   return dip_hostaddr(ads, &ap->ha, &bp->ha);
+ }
+ 
+ /*
+  * _inthostaddr  (mf,cs)
+  */
+ 
+ static void mf_inthostaddr(adns_query qu, void *datap) {
+   adns_rr_inthostaddr *rrp= datap;
+ 
+   mfp_hostaddr(qu,&rrp->ha);
+ }
+ 
+ static adns_status cs_inthostaddr(vbuf *vb, const void *datap) {
+   const adns_rr_inthostaddr *rrp= datap;
+   char buf[10];
+ 
+   sprintf(buf,"%u ",rrp->i);
+   CSP_ADDSTR(buf);
+ 
+   return csp_hostaddr(vb,&rrp->ha);
+ }
+ 
+ /*
+  * _inthost  (cs)
+  */
+ 
+ static adns_status cs_inthost(vbuf *vb, const void *datap) {
+   const adns_rr_intstr *rrp= datap;
+   char buf[10];
+ 
+   sprintf(buf,"%u ",rrp->i);
+   CSP_ADDSTR(buf);
+   return csp_domain(vb,rrp->str);
+ }
+ 
+ /*
+  * _ptr   (pa, +icb_ptr)
+  */
+ 
+ static void icb_ptr(adns_query parent, adns_query child) {
+   adns_answer *cans= child->answer;
+   const adns_rr_addr *queried, *found;
+   adns_state ads= parent->ads;
+   int i;
+ 
+   if (cans->status == adns_s_nxdomain || cans->status == adns_s_nodata) {
+     adns__query_fail(parent,adns_s_inconsistent);
+     return;
+   } else if (cans->status) {
+     adns__query_fail(parent,cans->status);
+     return;
+   }
+ 
+   queried= &parent->ctx.info.ptr_parent_addr;
+   for (i=0, found=cans->rrs.addr; i<cans->nrrs; i++, found++) {
+     if (queried->len == found->len &&
+        !memcmp(&queried->addr,&found->addr,queried->len)) {
+       if (!parent->children.head) {
+        adns__query_done(parent);
+        return;
+       } else {
+        LIST_LINK_TAIL(ads->childw,parent);
+        return;
+       }
+     }
+   }
+ 
+   adns__query_fail(parent,adns_s_inconsistent);
+ }
+ 
+ static adns_status pa_ptr(const parseinfo *pai, int dmstart, int max, void *datap) {
+   static const char *(expectdomain[])= { DNS_INADDR_ARPA };
+   
+   char **rrp= datap;
+   adns_status st;
+   adns_rr_addr *ap;
+   findlabel_state fls;
+   char *ep;
+   byte ipv[4];
+   char labbuf[4];
+   int cbyte, i, lablen, labstart, l, id;
+   adns_query nqu;
+   qcontext ctx;
+ 
+   cbyte= dmstart;
+   st= pap_domain(pai, &cbyte, max, rrp,
+                 pai->qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0);
+   if (st) return st;
+   if (cbyte != max) return adns_s_invaliddata;
+ 
+   ap= &pai->qu->ctx.info.ptr_parent_addr;
+   if (!ap->len) {
+     adns__findlabel_start(&fls, pai->ads, -1, pai->qu,
+                          pai->qu->query_dgram, pai->qu->query_dglen,
+                          pai->qu->query_dglen, DNS_HDRSIZE, 0);
+     for (i=0; i<4; i++) {
+       st= adns__findlabel_next(&fls,&lablen,&labstart); assert(!st);
+       if (lablen<=0 || lablen>3) return adns_s_querydomainwrong;
+       memcpy(labbuf, pai->qu->query_dgram + labstart, lablen);  labbuf[lablen]= 0;
+       ipv[3-i]= strtoul(labbuf,&ep,10);  if (*ep) return adns_s_querydomainwrong;
+       if (lablen>1 && pai->qu->query_dgram[labstart]=='0')
+        return adns_s_querydomainwrong;
+     }
+     for (i=0; i<sizeof(expectdomain)/sizeof(*expectdomain); i++) {
+       st= adns__findlabel_next(&fls,&lablen,&labstart); assert(!st);
+       l= strlen(expectdomain[i]);
+       if (lablen != l || memcmp(pai->qu->query_dgram + labstart, expectdomain[i], l))
+        return adns_s_querydomainwrong;
+     }
+     st= adns__findlabel_next(&fls,&lablen,0); assert(!st);
+     if (lablen) return adns_s_querydomainwrong;
+     
+     ap->len= sizeof(struct sockaddr_in);
+     memset(&ap->addr,0,sizeof(ap->addr.inet));
+     ap->addr.inet.sin_family= AF_INET;
+     ap->addr.inet.sin_addr.s_addr=
+       htonl((ipv[0]<<24) | (ipv[1]<<16) | (ipv[2]<<8) | (ipv[3]));
+   }
+ 
+   st= adns__mkquery_frdgram(pai->ads, &pai->qu->vb, &id,
+                            pai->dgram, pai->dglen, dmstart,
+                            adns_r_addr, adns_qf_quoteok_query);
+   if (st) return st;
+ 
+   ctx.ext= 0;
+   ctx.callback= icb_ptr;
+   memset(&ctx.info,0,sizeof(ctx.info));
+   st= adns__internal_submit(pai->ads, &nqu, adns__findtype(adns_r_addr),
+                            &pai->qu->vb, id,
+                            adns_qf_quoteok_query, pai->now, &ctx);
+   if (st) return st;
+ 
+   nqu->parent= pai->qu;
+   LIST_LINK_TAIL_PART(pai->qu->children,nqu,siblings.);
+   return adns_s_ok;
+ }
+ 
+ /*
+  * _strpair   (mf)
+  */
+ 
+ static void mf_strpair(adns_query qu, void *datap) {
+   adns_rr_strpair *rrp= datap;
+ 
+   adns__makefinal_str(qu,&rrp->array[0]);
+   adns__makefinal_str(qu,&rrp->array[1]);
+ }
+ 
+ /*
+  * _intstrpair   (mf)
+  */
+ 
+ static void mf_intstrpair(adns_query qu, void *datap) {
+   adns_rr_intstrpair *rrp= datap;
+ 
+   adns__makefinal_str(qu,&rrp->array[0].str);
+   adns__makefinal_str(qu,&rrp->array[1].str);
+ }
+ 
+ /*
+  * _hinfo   (pa)
+  */
+ 
+ static adns_status pa_hinfo(const parseinfo *pai, int cbyte, int max, void *datap) {
+   adns_rr_intstrpair *rrp= datap;
+   adns_status st;
+   int i;
+ 
+   for (i=0; i<2; i++) {
+     st= pap_qstring(pai, &cbyte, max, &rrp->array[i].i, &rrp->array[i].str);
+     if (st) return st;
+   }
+ 
+   if (cbyte != max) return adns_s_invaliddata;
+   
+   return adns_s_ok;
+ }
+ 
+ /*
+  * _mailbox   (pap,cs)
+  */
+ 
+ static adns_status pap_mailbox822(const parseinfo *pai, int *cbyte_io, int max,
+                                  char **mb_r) {
+   int lablen, labstart, i, needquote, c, r, neednorm;
+   const unsigned char *p;
+   char *str;
+   findlabel_state fls;
+   adns_status st;
+   vbuf *vb;
+ 
+   vb= &pai->qu->vb;
+   vb->used= 0;
+   adns__findlabel_start(&fls, pai->ads,
+                        -1, pai->qu,
+                        pai->dgram, pai->dglen, max,
+                        *cbyte_io, cbyte_io);
+   st= adns__findlabel_next(&fls,&lablen,&labstart);
+   if (!lablen) {
+     adns__vbuf_appendstr(vb,".");
+     goto x_ok;
+   }
+ 
+   neednorm= 1;
+   for (i=0, needquote=0, p= pai->dgram+labstart; i<lablen; i++) {
+     c= *p++;
+     if ((c&~128) < 32 || (c&~128) == 127) return adns_s_invaliddata;
+     if (c == '.' && !neednorm) neednorm= 1;
+     else if (c==' ' || c>=127 || ctype_822special(c)) needquote++;
+     else neednorm= 0;
+   }
+ 
+   if (needquote || neednorm) {
+     r= adns__vbuf_ensure(vb, lablen+needquote+4); if (!r) R_NOMEM;
+     adns__vbuf_appendq(vb,"\"",1);
+     for (i=0, needquote=0, p= pai->dgram+labstart; i<lablen; i++, p++) {
+       c= *p;
+       if (c == '"' || c=='\\') adns__vbuf_appendq(vb,"\\",1);
+       adns__vbuf_appendq(vb,p,1);
+     }
+     adns__vbuf_appendq(vb,"\"",1);
+   } else {
+     r= adns__vbuf_append(vb, pai->dgram+labstart, lablen); if (!r) R_NOMEM;
+   }
+ 
+   r= adns__vbuf_appendstr(vb,"@"); if (!r) R_NOMEM;
+ 
+   st= adns__parse_domain_more(&fls,pai->ads, pai->qu,vb,0, pai->dgram);
+   if (st) return st;
+ 
+  x_ok:
+   str= adns__alloc_interim(pai->qu, vb->used+1); if (!str) R_NOMEM;
+   memcpy(str,vb->buf,vb->used);
+   str[vb->used]= 0;
+   *mb_r= str;
+   return adns_s_ok;
+ }
+ 
+ static adns_status pap_mailbox(const parseinfo *pai, int *cbyte_io, int max,
+                               char **mb_r) {
+   if (pai->qu->typei->type & adns__qtf_mail822) {
+     return pap_mailbox822(pai, cbyte_io, max, mb_r);
+   } else {
+     return pap_domain(pai, cbyte_io, max, mb_r, pdf_quoteok);
+   }
+ }
+ 
+ static adns_status csp_mailbox(vbuf *vb, const char *mailbox) {
+   return csp_domain(vb,mailbox);
+ }
+ 
+ /*
+  * _rp   (pa,cs)
+  */
+ 
+ static adns_status pa_rp(const parseinfo *pai, int cbyte, int max, void *datap) {
+   adns_rr_strpair *rrp= datap;
+   adns_status st;
+ 
+   st= pap_mailbox(pai, &cbyte, max, &rrp->array[0]);
+   if (st) return st;
+ 
+   st= pap_domain(pai, &cbyte, max, &rrp->array[1], pdf_quoteok);
+   if (st) return st;
+ 
+   if (cbyte != max) return adns_s_invaliddata;
+   return adns_s_ok;
+ }
+ 
+ static adns_status cs_rp(vbuf *vb, const void *datap) {
+   const adns_rr_strpair *rrp= datap;
+   adns_status st;
+ 
+   st= csp_mailbox(vb,rrp->array[0]);  if (st) return st;
+   CSP_ADDSTR(" ");
+   st= csp_domain(vb,rrp->array[1]);  if (st) return st;
+ 
+   return adns_s_ok;
+ }  
+ 
+ /*
+  * _soa   (pa,mf,cs)
+  */
+ 
+ static adns_status pa_soa(const parseinfo *pai, int cbyte, int max, void *datap) {
+   adns_rr_soa *rrp= datap;
+   const byte *dgram= pai->dgram;
+   adns_status st;
+   int msw, lsw, i;
+ 
+   st= pap_domain(pai, &cbyte, max, &rrp->mname,
+                 pai->qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0);
+   if (st) return st;
+ 
+   st= pap_mailbox(pai, &cbyte, max, &rrp->rname);
+   if (st) return st;
+ 
+   if (cbyte+20 != max) return adns_s_invaliddata;
+   
+   for (i=0; i<5; i++) {
+     GET_W(cbyte,msw);
+     GET_W(cbyte,lsw);
+     (&rrp->serial)[i]= (msw<<16) | lsw;
+   }
+ 
+   return adns_s_ok;
+ }
+ 
+ static void mf_soa(adns_query qu, void *datap) {
+   adns_rr_soa *rrp= datap;
+ 
+   adns__makefinal_str(qu,&rrp->mname);
+   adns__makefinal_str(qu,&rrp->rname);
+ }
+ 
+ static adns_status cs_soa(vbuf *vb, const void *datap) {
+   const adns_rr_soa *rrp= datap;
+   char buf[20];
+   int i;
+   adns_status st;
+   
+   st= csp_domain(vb,rrp->mname);  if (st) return st;
+   CSP_ADDSTR(" ");
+   st= csp_mailbox(vb,rrp->rname);  if (st) return st;
+ 
+   for (i=0; i<5; i++) {
+     sprintf(buf," %lu",(&rrp->serial)[i]);
+     CSP_ADDSTR(buf);
+   }
+ 
+   return adns_s_ok;
+ }
+ 
+ /*
+  * _flat   (mf)
+  */
+ 
+ static void mf_flat(adns_query qu, void *data) { }
+ 
+ /*
+  * Now the table.
+  */
+ 
+ #define TYPESZ_M(member)           (sizeof(*((adns_answer*)0)->rrs.member))
+ 
+ #define DEEP_MEMB(memb) TYPESZ_M(memb), mf_##memb, cs_##memb
+ #define FLAT_MEMB(memb) TYPESZ_M(memb), mf_flat, cs_##memb
+ 
+ #define DEEP_TYPE(code,rrt,fmt,memb,parser,comparer,printer) \
+  { adns_r_##code, rrt, fmt, TYPESZ_M(memb), mf_##memb, printer, parser, comparer }
+ #define FLAT_TYPE(code,rrt,fmt,memb,parser,comparer,printer) \
+  { adns_r_##code, rrt, fmt, TYPESZ_M(memb), mf_flat, printer, parser, comparer }
+ 
+ static const typeinfo typeinfos[] = {
+ /* Must be in ascending order of rrtype ! */
+ /* mem-mgmt code  rrt     fmt     member      parser      comparer    printer       */
+                                                                                       
+ FLAT_TYPE(a,      "A",     0,     inaddr,     pa_inaddr,  di_inaddr,  cs_inaddr     ),
+ DEEP_TYPE(ns_raw, "NS",   "raw",  str,        pa_host_raw,0,          cs_domain     ),
+ DEEP_TYPE(cname,  "CNAME", 0,     str,        pa_dom_raw, 0,          cs_domain     ),
+ DEEP_TYPE(soa_raw,"SOA",  "raw",  soa,        pa_soa,     0,          cs_soa        ),
+ DEEP_TYPE(ptr_raw,"PTR",  "raw",  str,        pa_host_raw,0,          cs_domain     ),
+ DEEP_TYPE(hinfo,  "HINFO", 0,     intstrpair, pa_hinfo,   0,          cs_hinfo      ),
+ DEEP_TYPE(mx_raw, "MX",   "raw",  intstr,     pa_mx_raw,  di_mx_raw,  cs_inthost    ),
+ DEEP_TYPE(txt,    "TXT",   0,     manyistr,   pa_txt,     0,          cs_txt        ),
+ DEEP_TYPE(rp_raw, "RP",   "raw",  strpair,    pa_rp,      0,          cs_rp         ),
+                                                                                       
+ FLAT_TYPE(addr,   "A",  "addr",   addr,       pa_addr,    di_addr,    cs_addr       ),
+ DEEP_TYPE(ns,     "NS", "+addr",  hostaddr,   pa_hostaddr,di_hostaddr,cs_hostaddr   ),
+ DEEP_TYPE(ptr,    "PTR","checked",str,        pa_ptr,     0,          cs_domain     ),
+ DEEP_TYPE(mx,     "MX", "+addr",  inthostaddr,pa_mx,      di_mx,      cs_inthostaddr),
+                                                                              
+ DEEP_TYPE(soa,    "SOA","822",    soa,        pa_soa,     0,          cs_soa        ),
+ DEEP_TYPE(rp,     "RP", "822",    strpair,    pa_rp,      0,          cs_rp         ),
+ };
+ 
+ const typeinfo *adns__findtype(adns_rrtype type) {
+   const typeinfo *begin, *end, *mid;
+ 
+   begin= typeinfos;  end= typeinfos+(sizeof(typeinfos)/sizeof(typeinfo));
+ 
+   while (begin < end) {
+     mid= begin + ((end-begin)>>1);
+     if (mid->type == type) return mid;
+     if (type > mid->type) begin= mid+1;
+     else end= mid;
+   }
+   return 0;
+ }


ossp-pkg/adns/configure.in 1.1.1.3 -> 1.1.1.4

--- configure.in 2000/08/12 11:35:14     1.1.1.3
+++ configure.in 2000/09/19 15:46:53     1.1.1.4
@@ -5,7 +5,7 @@
 #
 #  It is part of adns, which is
 #    Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk>
-#    Copyright (C) 1999 Tony Finch <dot@dotat.at>
+#    Copyright (C) 1999-2000 Tony Finch <dot@dotat.at>
 #  
 #  This program is free software; you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
@@ -24,6 +24,21 @@
 AC_INIT(src/adns.h)
 AC_CONFIG_HEADER(src/config.h)
 
+dnl DPKG_CACHED_TRY_COMPILE(<description>,<cachevar>,<include>,<program>,<ifyes>,<ifno>)
+define(DPKG_CACHED_TRY_COMPILE,[
+ AC_MSG_CHECKING($1)
+ AC_CACHE_VAL($2,[
+  AC_TRY_COMPILE([$3],[$4],[$2=yes],[$2=no])
+ ])
+ if test "x$$2" = xyes; then
+  true
+  $5
+ else
+  true
+  $6
+ fi
+])
+
 AC_MSG_CHECKING(whether you requested dynamic linking)
 AC_SUBST(ENABLE_DYNAMIC)
 AC_ARG_ENABLE(dynamic,
@@ -42,7 +57,7 @@
                 ;;
         esac
 ],[
-                ENABLE_DYNAMIC=yes
+                ENABLE_DYNAMIC=elf
                 AC_MSG_RESULT([yes, by default])
 ])
 
@@ -91,7 +106,14 @@
  AC_MSG_WARN([inet_aton is in libresolv, urgh.  Must use -lresolv.])
 ])
 
+DPKG_CACHED_TRY_COMPILE(inlines,dpkg_cv_c_inline,,
+ [} inline int foo (int x) {],
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_INLINE),
+ AC_MSG_RESULT(no))
+
 ADNS_C_GCCATTRIB
+AC_CHECK_HEADERS(sys/select.h)
 
 AC_SUBST(WARNS)
 

CVSTrac 2.0.1