Browse files

ares 1.1.1 with collected applied patches

  • Loading branch information...
0 parents commit 5e847a14bd65383ce65f143c578e120899981fd9 @bagder bagder committed Oct 7, 2003
Showing with 11,352 additions and 0 deletions.
  1. +9 −0 CHANGES
  2. +87 −0 Makefile.in
  3. +18 −0 NEWS
  4. +41 −0 README
  5. +358 −0 aclocal.m4
  6. +623 −0 adig.c
  7. +122 −0 ahost.c
  8. +130 −0 ares.h
  9. +57 −0 ares__close_sockets.c
  10. +171 −0 ares__get_hostent.c
  11. +64 −0 ares__read_line.c
  12. +43 −0 ares_destroy.3
  13. +45 −0 ares_destroy.c
  14. +81 −0 ares_dns.h
  15. +65 −0 ares_expand_name.3
  16. +159 −0 ares_expand_name.c
  17. +62 −0 ares_fds.3
  18. +58 −0 ares_fds.c
  19. +42 −0 ares_free_errmem.3
  20. +26 −0 ares_free_errmem.c
  21. +49 −0 ares_free_hostent.3
  22. +39 −0 ares_free_hostent.c
  23. +37 −0 ares_free_string.3
  24. +24 −0 ares_free_string.c
  25. +100 −0 ares_gethostbyaddr.3
  26. +174 −0 ares_gethostbyaddr.c
  27. +103 −0 ares_gethostbyname.3
  28. +297 −0 ares_gethostbyname.c
  29. +170 −0 ares_init.3
  30. +776 −0 ares_init.c
  31. +2 −0 ares_init_options.3
  32. +79 −0 ares_mkquery.3
  33. +161 −0 ares_mkquery.c
  34. +65 −0 ares_parse_a_reply.3
  35. +173 −0 ares_parse_a_reply.c
  36. +77 −0 ares_parse_ptr_reply.3
  37. +159 −0 ares_parse_ptr_reply.c
  38. +145 −0 ares_private.h
  39. +79 −0 ares_process.3
  40. +625 −0 ares_process.c
  41. +142 −0 ares_query.3
  42. +112 −0 ares_query.c
  43. +144 −0 ares_search.3
  44. +273 −0 ares_search.c
  45. +117 −0 ares_send.3
  46. +104 −0 ares_send.c
  47. +44 −0 ares_strerror.3
  48. +47 −0 ares_strerror.c
  49. +64 −0 ares_timeout.3
  50. +67 −0 ares_timeout.c
  51. +1,388 −0 config.guess
  52. +1,489 −0 config.sub
  53. +18 −0 configure.in
  54. +205 −0 nameser.h
  55. +2 −0 vc/adig/adig.dep
  56. +106 −0 vc/adig/adig.dsp
  57. +213 −0 vc/adig/adig.mak
  58. +77 −0 vc/adig/adig.plg
  59. +2 −0 vc/ahost/ahost.dep
  60. +100 −0 vc/ahost/ahost.dsp
  61. +223 −0 vc/ahost/ahost.mak
  62. +16 −0 vc/ahost/ahost.plg
  63. +2 −0 vc/areslib/areslib.dep
  64. +196 −0 vc/areslib/areslib.dsp
  65. +361 −0 vc/areslib/areslib.mak
  66. +125 −0 vc/areslib/areslib.plg
  67. +59 −0 vc/vc.dsw
  68. BIN vc/vc.ncb
  69. BIN vc/vc.opt
  70. +61 −0 windows_port.c
9 CHANGES
@@ -0,0 +1,9 @@
+- James Bursa made it run on RISC OS
+
+- Dominick Meglio made it run fine on NT4
+
+- Duncan Wilcox made it fine on Mac OS X
+
+- Daniel Stenberg adjusted the windows port
+
+- liren at vivisimo.com made the initial windows port
87 Makefile.in
@@ -0,0 +1,87 @@
+# $Id$
+
+SHELL=/bin/sh
+INSTALL=@INSTALL@
+RANLIB=@RANLIB@
+VPATH=@srcdir@
+srcdir=@srcdir@
+top_srcdir=@top_srcdir@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+mandir=@mandir@
+
+CC=@CC@
+CPPFLAGS=@CPPFLAGS@
+CFLAGS=@CFLAGS@ ${WARN_CFLAGS} ${ERROR_CFLAGS}
+DEFS=@DEFS@
+LDFLAGS=@LDFLAGS@
+LIBS=@LIBS@
+ALL_CFLAGS=${CPPFLAGS} ${CFLAGS} ${DEFS}
+OBJS= ares__close_sockets.o ares__get_hostent.o ares__read_line.o \
+ ares_destroy.o ares_expand_name.o ares_fds.o ares_free_errmem.o \
+ ares_free_hostent.o ares_free_string.o ares_gethostbyaddr.o \
+ ares_gethostbyname.o ares_init.o ares_mkquery.o ares_parse_a_reply.o \
+ ares_parse_ptr_reply.o ares_process.o ares_query.o ares_search.o \
+ ares_send.o ares_strerror.o ares_timeout.o
+
+all: libares.a adig ahost
+
+libares.a: ${OBJS}
+ ar cru $@ ${OBJS}
+ ${RANLIB} $@
+
+adig: adig.o libares.a
+ ${CC} ${LDFLAGS} -o $@ adig.o libares.a ${LIBS}
+
+ahost: ahost.o libares.a
+ ${CC} ${LDFLAGS} -o $@ ahost.o libares.a ${LIBS}
+
+${OBJS}: ares.h ares_dns.h ares_private.h
+
+.c.o:
+ ${CC} -c ${ALL_CFLAGS} $<
+
+check:
+
+install:
+ ${top_srcdir}/mkinstalldirs ${DESTDIR}${libdir}
+ ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}
+ ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 644 libares.a ${DESTDIR}${libdir}
+ ${RANLIB} ${DESTDIR}${libdir}/libares.a
+ chmod u-w ${DESTDIR}${libdir}/libares.a
+ ${INSTALL} -m 444 ${srcdir}/ares.h ${DESTDIR}${includedir}
+ ${INSTALL} -m 444 ${srcdir}/ares_destroy.3 ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 444 ${srcdir}/ares_expand_name.3 ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 444 ${srcdir}/ares_fds.3 ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 444 ${srcdir}/ares_free_errmem.3 ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 444 ${srcdir}/ares_free_hostent.3 \
+ ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 444 ${srcdir}/ares_free_string.3 \
+ ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 444 ${srcdir}/ares_gethostbyaddr.3 \
+ ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 444 ${srcdir}/ares_gethostbyname.3 \
+ ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 444 ${srcdir}/ares_init.3 ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 444 ${srcdir}/ares_init_options.3 \
+ ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 444 ${srcdir}/ares_mkquery.3 ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 444 ${srcdir}/ares_parse_a_reply.3 \
+ ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 444 ${srcdir}/ares_parse_ptr_reply.3 \
+ ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 444 ${srcdir}/ares_process.3 ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 444 ${srcdir}/ares_query.3 ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 444 ${srcdir}/ares_search.3 ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 444 ${srcdir}/ares_send.3 ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 444 ${srcdir}/ares_strerror.3 ${DESTDIR}${mandir}/man3
+ ${INSTALL} -m 444 ${srcdir}/ares_timeout.3 ${DESTDIR}${mandir}/man3
+
+clean:
+ rm -f ${OBJS} libares.a adig.o adig ahost.o ahost
+
+distclean: clean
+ rm -f config.cache config.log config.status Makefile
18 NEWS
@@ -0,0 +1,18 @@
+Major changes in release 1.1.1:
+* ares should now compile as C++ code (no longer uses reserved word
+ "class").
+* Added SRV support to adig test program.
+* Fixed a few error handling bugs in query processing.
+
+Major changes in release 1.1.0:
+* Added ares_free_string() function so that memory can be freed in the
+ same layer as it is allocated, a desirable feature in some
+ environments.
+* A few of the ares_dns.h macros are fixed to use the proper bitwise
+ operator.
+* Fixed a couple of fenceposts fixed in ares_expand_name()'s
+ bounds-checking.
+* In process_timeouts(), extract query->next before calling
+ next_server() and possibly freeing the query structure.
+* Casted arguments to ctype macros casted to unsigned char, since not
+ all char values are valid inputs to those macros according to ANSI.
41 README
@@ -0,0 +1,41 @@
+This is ares, an asynchronous resolver library. It is intended for
+applications which need to perform DNS queries without blocking, or
+need to perform multiple DNS queries in parallel. The primary
+examples of such applications are servers which communicate with
+multiple clients and programs with graphical user interfaces.
+
+This library implementation is not especially portable to crufty old
+systems like SunOS 4. It assumes a compiler which can handle ANSI C
+syntax, a system malloc which properly handles realloc(NULL, foo) and
+free(NULL), and a reasonably up-to-date <arpa/nameser.h>.
+
+I have attempted to preserve the externally visible behavior of the
+BIND resolver in nearly all respects. The API of the library is, of
+course, very different from the synchronous BIND API; instead of
+invoking a function like res_send() and getting a return value back
+indicating the number of bytes in the response, you invoke a function
+like ares_send() and give it a callback function to invoke when the
+response arrives. You then have to select() on the file descriptors
+indicated by ares_fds(), with a timeout given by ares_timeout(). You
+call ares_process() when select() returns.
+
+Some features are missing from the current version of ares, relative
+to the BIND resolver:
+
+ * There is no IPV6 support.
+ * There is no hostname verification.
+ * There is no logging of unexpected events.
+ * There is no debugging-oriented logging.
+ * There is no YP support.
+
+libares requires an ANSI compiler to compile and use. To build the
+library, just run "./configure" and "make". To install it, run "make
+install". Run "./configure --help" to see a list of options you can
+provide to configure to change how the library builds. libares has no
+data files, so you can move the include file and library around freely
+without leaving behind any dependencies on old paths. Building the
+library will also build the "adig" program, a little toy for trying
+out the library. It doesn't get installed.
+
+libares is distributed at athena-dist.mit.edu:pub/ATHENA/ares. Please
+send bug reports and comments to ghudson@mit.edu.
358 aclocal.m4
@@ -0,0 +1,358 @@
+dnl $Id$
+
+dnl Copyright 1996 by the Massachusetts Institute of Technology.
+dnl
+dnl Permission to use, copy, modify, and distribute this
+dnl software and its documentation for any purpose and without
+dnl fee is hereby granted, provided that the above copyright
+dnl notice appear in all copies and that both that copyright
+dnl notice and this permission notice appear in supporting
+dnl documentation, and that the name of M.I.T. not be used in
+dnl advertising or publicity pertaining to distribution of the
+dnl software without specific, written prior permission.
+dnl M.I.T. makes no representations about the suitability of
+dnl this software for any purpose. It is provided "as is"
+dnl without express or implied warranty.
+
+dnl This file provides local macros for packages which use specific
+dnl external libraries. The public macros are:
+dnl
+dnl ATHENA_UTIL_COM_ERR
+dnl Generates error if com_err not found.
+dnl ATHENA_UTIL_SS
+dnl Generates error if ss not found.
+dnl ATHENA_REGEXP
+dnl Sets REGEX_LIBS if rx library used; ensures POSIX
+dnl regexp support.
+dnl ATHENA_MOTIF
+dnl Sets MOTIF_LIBS and defines HAVE_MOTIF if Motif used.
+dnl ATHENA_MOTIF_REQUIRED
+dnl Generates error if Motif not found.
+dnl ATHENA_AFS
+dnl Sets AFS_LIBS and defines HAVE_AFS if AFS used. Pass
+dnl in an argument giving the desired AFS libraries;
+dnl AFS_LIBS will be set to that value if AFS is found.
+dnl AFS_DIR will be set to the prefix given.
+dnl ATHENA_AFS_REQUIRED
+dnl Generates error if AFS libraries not found. AFS_DIR
+dnl will be set to the prefix given.
+dnl ATHENA_KRB4
+dnl Sets KRB4_LIBS and defines HAVE_KRB4 if krb4 used.
+dnl ATHENA_KRB4_REQUIRED
+dnl Generates error if krb4 not found. Sets KRB4_LIBS
+dnl otherwise. (Special behavior because krb4 libraries
+dnl may be different if using krb4 compatibility libraries
+dnl from krb5.)
+dnl ATHENA_KRB5
+dnl Sets KRB5_LIBS and defines HAVE_KRB5 if krb5 used.
+dnl ATHENA_KRB5_REQUIRED
+dnl Generates error if krb5 not found.
+dnl ATHENA_HESIOD
+dnl Sets HESIOD_LIBS and defines HAVE_HESIOD if Hesiod
+dnl used.
+dnl ATHENA_HESIOD_REQUIRED
+dnl Generates error if Hesiod not found.
+dnl ATHENA_ARES
+dnl Sets ARES_LIBS and defines HAVE_ARES if libares
+dnl used.
+dnl ATHENA_ARES_REQUIRED
+dnl Generates error if libares not found.
+dnl ATHENA_ZEPHYR
+dnl Sets ZEPHYR_LIBS and defines HAVE_ZEPHYR if zephyr
+dnl used.
+dnl ATHENA_ZEPHYR_REQUIRED
+dnl Generates error if zephyr not found.
+dnl
+dnl All of the macros may extend CPPFLAGS and LDFLAGS to let the
+dnl compiler find the requested libraries. Put ATHENA_UTIL_COM_ERR
+dnl and ATHENA_UTIL_SS before ATHENA_AFS or ATHENA_AFS_REQUIRED; there
+dnl is a com_err library in the AFS libraries which requires -lutil.
+
+dnl ----- com_err -----
+
+AC_DEFUN(ATHENA_UTIL_COM_ERR,
+[AC_ARG_WITH(com_err,
+ [ --with-com_err=PREFIX Specify location of com_err],
+ [com_err="$withval"], [com_err=yes])
+if test "$com_err" != no; then
+ if test "$com_err" != yes; then
+ CPPFLAGS="$CPPFLAGS -I$com_err/include"
+ LDFLAGS="$LDFLAGS -L$com_err/lib"
+ fi
+ AC_CHECK_LIB(com_err, com_err, :,
+ [AC_MSG_ERROR(com_err library not found)])
+else
+ AC_MSG_ERROR(This package requires com_err.)
+fi])
+
+dnl ----- ss -----
+
+AC_DEFUN(ATHENA_UTIL_SS,
+[AC_ARG_WITH(ss,
+ [ --with-ss=PREFIX Specify location of ss (requires com_err)],
+ [ss="$withval"], [ss=yes])
+if test "$ss" != no; then
+ if test "$ss" != yes; then
+ CPPFLAGS="$CPPFLAGS -I$ss/include"
+ LDFLAGS="$LDFLAGS -L$ss/lib"
+ fi
+ AC_CHECK_LIB(ss, ss_perror, :,
+ [AC_MSG_ERROR(ss library not found)], -lcom_err)
+else
+ AC_MSG_ERROR(This package requires ss.)
+fi])
+
+dnl ----- Regular expressions -----
+
+AC_DEFUN(ATHENA_REGEXP,
+[AC_ARG_WITH(regex,
+ [ --with-regex=PREFIX Use installed regex library],
+ [regex="$withval"], [regex=no])
+if test "$regex" != no; then
+ if test "$regex" != yes; then
+ CPPFLAGS="$CPPFLAGS -I$regex/include"
+ LDFLAGS="$LDFLAGS -L$regex/lib"
+ fi
+ AC_CHECK_LIB(regex, regcomp, REGEX_LIBS=-lregex,
+ [AC_MSG_ERROR(regex library not found)])
+else
+ AC_CHECK_FUNC(regcomp, :,
+ [AC_MSG_ERROR(can't find POSIX regexp support)])
+fi
+AC_SUBST(REGEX_LIBS)])
+
+dnl ----- Motif -----
+
+AC_DEFUN(ATHENA_MOTIF_CHECK,
+[if test "$motif" != yes; then
+ CPPFLAGS="$CPPFLAGS -I$motif/include"
+ LDFLAGS="$LDFLAGS -L$motif/lib"
+fi
+AC_CHECK_LIB(Xm, XmStringFree, :, [AC_MSG_ERROR(Motif library not found)])])
+
+AC_DEFUN(ATHENA_MOTIF,
+[AC_ARG_WITH(motif,
+ [ --with-motif=PREFIX Use Motif],
+ [motif="$withval"], [motif=no])
+if test "$motif" != no; then
+ ATHENA_MOTIF_CHECK
+ MOTIF_LIBS=-lXm
+ AC_DEFINE(HAVE_MOTIF)
+fi
+AC_SUBST(MOTIF_LIBS)])
+
+AC_DEFUN(ATHENA_MOTIF_REQUIRED,
+[AC_ARG_WITH(motif,
+ [ --with-motif=PREFIX Specify location of Motif],
+ [motif="$withval"], [motif=yes])
+if test "$motif" != no; then
+ ATHENA_MOTIF_CHECK
+else
+ AC_MSG_ERROR(This package requires Motif.)
+fi])
+
+dnl ----- AFS -----
+
+AC_DEFUN(ATHENA_AFS_CHECK,
+[AC_CHECK_FUNC(insque, :, AC_CHECK_LIB(compat, insque))
+AC_CHECK_FUNC(gethostbyname, :, AC_CHECK_LIB(nsl, gethostbyname))
+AC_CHECK_FUNC(socket, :, AC_CHECK_LIB(socket, socket))
+if test "$afs" != yes; then
+ CPPFLAGS="$CPPFLAGS -I$afs/include"
+ LDFLAGS="$LDFLAGS -L$afs/lib -L$afs/lib/afs"
+fi
+AC_CHECK_LIB(sys, pioctl, :, [AC_MSG_ERROR(AFS libraries not found)],
+ -lrx -llwp -lsys)
+AFS_DIR=$afs
+AC_SUBST(AFS_DIR)])
+
+dnl Specify desired AFS libraries as a parameter.
+AC_DEFUN(ATHENA_AFS,
+[AC_ARG_WITH(afs,
+ [ --with-afs=PREFIX Use AFS libraries],
+ [afs="$withval"], [afs=no])
+if test "$afs" != no; then
+ ATHENA_AFS_CHECK
+ AFS_LIBS=$1
+ AC_DEFINE(HAVE_AFS)
+fi
+AC_SUBST(AFS_LIBS)])
+
+AC_DEFUN(ATHENA_AFS_REQUIRED,
+[AC_ARG_WITH(afs,
+ [ --with-afs=PREFIX Specify location of AFS libraries],
+ [afs="$withval"], [afs=/usr/afsws])
+if test "$afs" != no; then
+ ATHENA_AFS_CHECK
+else
+ AC_MSG_ERROR(This package requires AFS libraries.)
+fi])
+
+dnl ----- Kerberos 4 -----
+
+AC_DEFUN(ATHENA_KRB4_CHECK,
+[AC_CHECK_FUNC(gethostbyname, :, AC_CHECK_LIB(nsl, gethostbyname))
+AC_CHECK_FUNC(socket, :, AC_CHECK_LIB(socket, socket))
+AC_CHECK_LIB(gen, compile)
+if test "$krb4" != yes; then
+ CPPFLAGS="$CPPFLAGS -I$krb4/include"
+ if test -d "$krb4/include/kerberosIV"; then
+ CPPFLAGS="$CPPFLAGS -I$krb4/include/kerberosIV"
+ fi
+ LDFLAGS="$LDFLAGS -L$krb4/lib"
+fi
+AC_CHECK_LIB(krb4, krb_rd_req,
+ [KRB4_LIBS="-lkrb4 -ldes425 -lkrb5 -lk5crypto -lcom_err"],
+ [AC_CHECK_LIB(krb, krb_rd_req,
+ [KRB4_LIBS="-lkrb -ldes"],
+ [AC_MSG_ERROR(Kerberos 4 libraries not found)],
+ -ldes)],
+ -ldes425 -lkrb5 -lk5crypto -lcom_err)])
+
+AC_DEFUN(ATHENA_KRB4,
+[AC_ARG_WITH(krb4,
+ [ --with-krb4=PREFIX Use Kerberos 4],
+ [krb4="$withval"], [krb4=no])
+if test "$krb4" != no; then
+ ATHENA_KRB4_CHECK
+ AC_DEFINE(HAVE_KRB4)
+fi
+AC_SUBST(KRB4_LIBS)])
+
+AC_DEFUN(ATHENA_KRB4_REQUIRED,
+[AC_ARG_WITH(krb4,
+ [ --with-krb4=PREFIX Specify location of Kerberos 4],
+ [krb4="$withval"], [krb4=yes])
+if test "$krb4" != no; then
+ ATHENA_KRB4_CHECK
+ AC_SUBST(KRB4_LIBS)
+else
+ AC_MSG_ERROR(This package requires Kerberos 4.)
+fi])
+
+dnl ----- Kerberos 5 -----
+
+AC_DEFUN(ATHENA_KRB5_CHECK,
+[AC_SEARCH_LIBS(gethostbyname, nsl)
+AC_SEARCH_LIBS(socket, socket)
+AC_CHECK_LIB(gen, compile)
+if test "$krb5" != yes; then
+ CPPFLAGS="$CPPFLAGS -I$krb5/include"
+ LDFLAGS="$LDFLAGS -L$krb5/lib"
+fi
+AC_CHECK_LIB(krb5, krb5_init_context, :,
+ [AC_MSG_ERROR(Kerberos 5 libraries not found)],
+ -lk5crypto -lcom_err)])
+
+AC_DEFUN(ATHENA_KRB5,
+[AC_ARG_WITH(krb5,
+ [ --with-krb5=PREFIX Use Kerberos 5],
+ [krb5="$withval"], [krb5=no])
+if test "$krb5" != no; then
+ ATHENA_KRB5_CHECK
+ KRB5_LIBS="-lkrb5 -lk5crypto -lcom_err"
+ AC_DEFINE(HAVE_KRB5)
+fi
+AC_SUBST(KRB5_LIBS)])
+
+AC_DEFUN(ATHENA_KRB5_REQUIRED,
+[AC_ARG_WITH(krb5,
+ [ --with-krb5=PREFIX Specify location of Kerberos 5],
+ [krb5="$withval"], [krb5=yes])
+if test "$krb5" != no; then
+ ATHENA_KRB5_CHECK
+else
+ AC_MSG_ERROR(This package requires Kerberos 5.)
+fi])
+
+dnl ----- Hesiod -----
+
+AC_DEFUN(ATHENA_HESIOD_CHECK,
+[AC_CHECK_FUNC(res_send, :, AC_CHECK_LIB(resolv, res_send))
+if test "$hesiod" != yes; then
+ CPPFLAGS="$CPPFLAGS -I$hesiod/include"
+ LDFLAGS="$LDFLAGS -L$hesiod/lib"
+fi
+AC_CHECK_LIB(hesiod, hes_resolve, :,
+ [AC_MSG_ERROR(Hesiod library not found)])])
+
+AC_DEFUN(ATHENA_HESIOD,
+[AC_ARG_WITH(hesiod,
+ [ --with-hesiod=PREFIX Use Hesiod],
+ [hesiod="$withval"], [hesiod=no])
+if test "$hesiod" != no; then
+ ATHENA_HESIOD_CHECK
+ HESIOD_LIBS="-lhesiod"
+ AC_DEFINE(HAVE_HESIOD)
+fi
+AC_SUBST(HESIOD_LIBS)])
+
+AC_DEFUN(ATHENA_HESIOD_REQUIRED,
+[AC_ARG_WITH(hesiod,
+ [ --with-hesiod=PREFIX Specify location of Hesiod],
+ [hesiod="$withval"], [hesiod=yes])
+if test "$hesiod" != no; then
+ ATHENA_HESIOD_CHECK
+else
+ AC_MSG_ERROR(This package requires Hesiod.)
+fi])
+
+dnl ----- libares -----
+
+AC_DEFUN(ATHENA_ARES_CHECK,
+[AC_CHECK_FUNC(res_send, :, AC_CHECK_LIB(resolv, res_send))
+if test "$ares" != yes; then
+ CPPFLAGS="$CPPFLAGS -I$ares/include"
+ LDFLAGS="$LDFLAGS -L$ares/lib"
+fi
+AC_CHECK_LIB(ares, ares_init, :, [AC_MSG_ERROR(libares not found)])])
+
+AC_DEFUN(ATHENA_ARES,
+[AC_ARG_WITH(ares,
+ [ --with-ares=PREFIX Use libares],
+ [ares="$withval"], [ares=no])
+if test "$ares" != no; then
+ ATHENA_ARES_CHECK
+ ARES_LIBS="-lares"
+ AC_DEFINE(HAVE_ARES)
+fi
+AC_SUBST(ARES_LIBS)])
+
+AC_DEFUN(ATHENA_ARES_REQUIRED,
+[AC_ARG_WITH(ares,
+ [ --with-ares=PREFIX Specify location of libares],
+ [ares="$withval"], [ares=yes])
+if test "$ares" != no; then
+ ATHENA_ARES_CHECK
+else
+ AC_MSG_ERROR(This package requires libares.)
+fi])
+dnl ----- zephyr -----
+
+AC_DEFUN(ATHENA_ZEPHYR_CHECK,
+[if test "$zephyr" != yes; then
+ CPPFLAGS="$CPPFLAGS -I$zephyr/include"
+ LDFLAGS="$LDFLAGS -L$zephyr/lib"
+fi
+AC_CHECK_LIB(zephyr, ZFreeNotice, :, [AC_MSG_ERROR(zephyr not found)])])
+
+AC_DEFUN(ATHENA_ZEPHYR,
+[AC_ARG_WITH(zephyr,
+ [ --with-zephyr=PREFIX Use zephyr],
+ [zephyr="$withval"], [zephyr=no])
+if test "$zephyr" != no; then
+ ATHENA_ZEPHYR_CHECK
+ ZEPHYR_LIBS="-lzephyr"
+ AC_DEFINE(HAVE_ZEPHYR)
+fi
+AC_SUBST(ZEPHYR_LIBS)])
+
+AC_DEFUN(ATHENA_ZEPHYR_REQUIRED,
+[AC_ARG_WITH(zephyr,
+ [ --with-zephyr=PREFIX Specify location of zephyr],
+ [zephyr="$withval"], [zephyr=yes])
+if test "$zephyr" != no; then
+ ATHENA_ZEPHYR_CHECK
+else
+ AC_MSG_ERROR(This package requires zephyr.)
+fi])
623 adig.c
@@ -0,0 +1,623 @@
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+static const char rcsid[] = "$Id$";
+
+#include <sys/types.h>
+
+#ifdef WIN32
+#include "nameser.h"
+#else
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <unistd.h>
+#include <netdb.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include "ares.h"
+#include "ares_dns.h"
+
+#ifndef INADDR_NONE
+#define INADDR_NONE 0xffffffff
+#endif
+
+/* Mac OS X portability check */
+#ifndef T_SRV
+#define T_SRV 33 /* server selection */
+#endif
+
+extern int optind;
+extern char *optarg;
+
+struct nv {
+ const char *name;
+ int value;
+};
+
+static const struct nv flags[] = {
+ { "usevc", ARES_FLAG_USEVC },
+ { "primary", ARES_FLAG_PRIMARY },
+ { "igntc", ARES_FLAG_IGNTC },
+ { "norecurse", ARES_FLAG_NORECURSE },
+ { "stayopen", ARES_FLAG_STAYOPEN },
+ { "noaliases", ARES_FLAG_NOALIASES }
+};
+static const int nflags = sizeof(flags) / sizeof(flags[0]);
+
+static const struct nv classes[] = {
+ { "IN", C_IN },
+ { "CHAOS", C_CHAOS },
+ { "HS", C_HS },
+ { "ANY", C_ANY }
+};
+static const int nclasses = sizeof(classes) / sizeof(classes[0]);
+
+static const struct nv types[] = {
+ { "A", T_A },
+ { "NS", T_NS },
+ { "MD", T_MD },
+ { "MF", T_MF },
+ { "CNAME", T_CNAME },
+ { "SOA", T_SOA },
+ { "MB", T_MB },
+ { "MG", T_MG },
+ { "MR", T_MR },
+ { "NULL", T_NULL },
+ { "WKS", T_WKS },
+ { "PTR", T_PTR },
+ { "HINFO", T_HINFO },
+ { "MINFO", T_MINFO },
+ { "MX", T_MX },
+ { "TXT", T_TXT },
+ { "RP", T_RP },
+ { "AFSDB", T_AFSDB },
+ { "X25", T_X25 },
+ { "ISDN", T_ISDN },
+ { "RT", T_RT },
+ { "NSAP", T_NSAP },
+ { "NSAP_PTR", T_NSAP_PTR },
+ { "SIG", T_SIG },
+ { "KEY", T_KEY },
+ { "PX", T_PX },
+ { "GPOS", T_GPOS },
+ { "AAAA", T_AAAA },
+ { "LOC", T_LOC },
+ { "SRV", T_SRV },
+ { "AXFR", T_AXFR },
+ { "MAILB", T_MAILB },
+ { "MAILA", T_MAILA },
+ { "ANY", T_ANY }
+};
+static const int ntypes = sizeof(types) / sizeof(types[0]);
+
+static const char *opcodes[] = {
+ "QUERY", "IQUERY", "STATUS", "(reserved)", "NOTIFY",
+ "(unknown)", "(unknown)", "(unknown)", "(unknown)",
+ "UPDATEA", "UPDATED", "UPDATEDA", "UPDATEM", "UPDATEMA",
+ "ZONEINIT", "ZONEREF"
+};
+
+static const char *rcodes[] = {
+ "NOERROR", "FORMERR", "SERVFAIL", "NXDOMAIN", "NOTIMP", "REFUSED",
+ "(unknown)", "(unknown)", "(unknown)", "(unknown)", "(unknown)",
+ "(unknown)", "(unknown)", "(unknown)", "(unknown)", "NOCHANGE"
+};
+
+static void callback(void *arg, int status, unsigned char *abuf, int alen);
+static const unsigned char *display_question(const unsigned char *aptr,
+ const unsigned char *abuf,
+ int alen);
+static const unsigned char *display_rr(const unsigned char *aptr,
+ const unsigned char *abuf, int alen);
+static const char *type_name(int type);
+static const char *class_name(int dnsclass);
+static void usage(void);
+
+int main(int argc, char **argv)
+{
+ ares_channel channel;
+ int c, i, optmask = ARES_OPT_FLAGS, dnsclass = C_IN, type = T_A;
+ int status, nfds, count;
+ struct ares_options options;
+ struct hostent *hostent;
+ fd_set read_fds, write_fds;
+ struct timeval *tvp, tv;
+ char *errmem;
+
+#ifdef WIN32
+ WORD wVersionRequested = MAKEWORD(1,1);
+ WSADATA wsaData;
+ WSAStartup(wVersionRequested, &wsaData);
+#endif
+
+ options.flags = ARES_FLAG_NOCHECKRESP;
+ options.servers = NULL;
+ options.nservers = 0;
+ while ((c = getopt(argc, argv, "f:s:c:t:T:U:")) != -1)
+ {
+ switch (c)
+ {
+ case 'f':
+ /* Add a flag. */
+ for (i = 0; i < nflags; i++)
+ {
+ if (strcmp(flags[i].name, optarg) == 0)
+ break;
+ }
+ if (i == nflags)
+ usage();
+ options.flags |= flags[i].value;
+ break;
+
+ case 's':
+ /* Add a server, and specify servers in the option mask. */
+ hostent = gethostbyname(optarg);
+ if (!hostent || hostent->h_addrtype != AF_INET)
+ {
+ fprintf(stderr, "adig: server %s not found.\n", optarg);
+ return 1;
+ }
+ options.servers = realloc(options.servers, (options.nservers + 1)
+ * sizeof(struct in_addr));
+ if (!options.servers)
+ {
+ fprintf(stderr, "Out of memory!\n");
+ return 1;
+ }
+ memcpy(&options.servers[options.nservers], hostent->h_addr,
+ sizeof(struct in_addr));
+ options.nservers++;
+ optmask |= ARES_OPT_SERVERS;
+ break;
+
+ case 'c':
+ /* Set the query class. */
+ for (i = 0; i < nclasses; i++)
+ {
+ if (strcasecmp(classes[i].name, optarg) == 0)
+ break;
+ }
+ if (i == nclasses)
+ usage();
+ dnsclass = classes[i].value;
+ break;
+
+ case 't':
+ /* Set the query type. */
+ for (i = 0; i < ntypes; i++)
+ {
+ if (strcasecmp(types[i].name, optarg) == 0)
+ break;
+ }
+ if (i == ntypes)
+ usage();
+ type = types[i].value;
+ break;
+
+ case 'T':
+ /* Set the TCP port number. */
+ if (!isdigit((unsigned char)*optarg))
+ usage();
+ options.tcp_port = strtol(optarg, NULL, 0);
+ optmask |= ARES_OPT_TCP_PORT;
+ break;
+
+ case 'U':
+ /* Set the UDP port number. */
+ if (!isdigit((unsigned char)*optarg))
+ usage();
+ options.udp_port = strtol(optarg, NULL, 0);
+ optmask |= ARES_OPT_UDP_PORT;
+ break;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 0)
+ usage();
+
+ status = ares_init_options(&channel, &options, optmask);
+
+ if (status != ARES_SUCCESS)
+ {
+ fprintf(stderr, "ares_init_options: %s\n",
+ ares_strerror(status, &errmem));
+ ares_free_errmem(errmem);
+ return 1;
+ }
+
+ /* Initiate the queries, one per command-line argument. If there is
+ * only one query to do, supply NULL as the callback argument;
+ * otherwise, supply the query name as an argument so we can
+ * distinguish responses for the user when printing them out.
+ */
+ if (argc == 1)
+ ares_query(channel, *argv, dnsclass, type, callback, (char *) NULL);
+ else
+ {
+ for (; *argv; argv++)
+ ares_query(channel, *argv, dnsclass, type, callback, *argv);
+ }
+
+ /* Wait for all queries to complete. */
+ while (1)
+ {
+ FD_ZERO(&read_fds);
+ FD_ZERO(&write_fds);
+ nfds = ares_fds(channel, &read_fds, &write_fds);
+ if (nfds == 0)
+ break;
+ tvp = ares_timeout(channel, NULL, &tv);
+ count = select(nfds, &read_fds, &write_fds, NULL, tvp);
+ if (count < 0 && errno != EINVAL)
+ {
+ perror("select");
+ return 1;
+ }
+ ares_process(channel, &read_fds, &write_fds);
+ }
+
+ ares_destroy(channel);
+ return 0;
+}
+
+static void callback(void *arg, int status, unsigned char *abuf, int alen)
+{
+ char *name = (char *) arg, *errmem;
+ int id, qr, opcode, aa, tc, rd, ra, rcode, i;
+ unsigned int qdcount, ancount, nscount, arcount;
+ const unsigned char *aptr;
+
+ /* Display the query name if given. */
+ if (name)
+ printf("Answer for query %s:\n", name);
+
+ /* Display an error message if there was an error, but only stop if
+ * we actually didn't get an answer buffer.
+ */
+ if (status != ARES_SUCCESS)
+ {
+ printf("%s\n", ares_strerror(status, &errmem));
+ ares_free_errmem(errmem);
+ if (!abuf)
+ return;
+ }
+
+ /* Won't happen, but check anyway, for safety. */
+ if (alen < HFIXEDSZ)
+ return;
+
+ /* Parse the answer header. */
+ id = DNS_HEADER_QID(abuf);
+ qr = DNS_HEADER_QR(abuf);
+ opcode = DNS_HEADER_OPCODE(abuf);
+ aa = DNS_HEADER_AA(abuf);
+ tc = DNS_HEADER_TC(abuf);
+ rd = DNS_HEADER_RD(abuf);
+ ra = DNS_HEADER_RA(abuf);
+ rcode = DNS_HEADER_RCODE(abuf);
+ qdcount = DNS_HEADER_QDCOUNT(abuf);
+ ancount = DNS_HEADER_ANCOUNT(abuf);
+ nscount = DNS_HEADER_NSCOUNT(abuf);
+ arcount = DNS_HEADER_ARCOUNT(abuf);
+
+ /* Display the answer header. */
+ printf("id: %d\n", id);
+ printf("flags: %s%s%s%s%s\n",
+ qr ? "qr " : "",
+ aa ? "aa " : "",
+ tc ? "tc " : "",
+ rd ? "rd " : "",
+ ra ? "ra " : "");
+ printf("opcode: %s\n", opcodes[opcode]);
+ printf("rcode: %s\n", rcodes[rcode]);
+
+ /* Display the questions. */
+ printf("Questions:\n");
+ aptr = abuf + HFIXEDSZ;
+ for (i = 0; i < qdcount; i++)
+ {
+ aptr = display_question(aptr, abuf, alen);
+ if (aptr == NULL)
+ return;
+ }
+
+ /* Display the answers. */
+ printf("Answers:\n");
+ for (i = 0; i < ancount; i++)
+ {
+ aptr = display_rr(aptr, abuf, alen);
+ if (aptr == NULL)
+ return;
+ }
+
+ /* Display the NS records. */
+ printf("NS records:\n");
+ for (i = 0; i < nscount; i++)
+ {
+ aptr = display_rr(aptr, abuf, alen);
+ if (aptr == NULL)
+ return;
+ }
+
+ /* Display the additional records. */
+ printf("Additional records:\n");
+ for (i = 0; i < arcount; i++)
+ {
+ aptr = display_rr(aptr, abuf, alen);
+ if (aptr == NULL)
+ return;
+ }
+}
+
+static const unsigned char *display_question(const unsigned char *aptr,
+ const unsigned char *abuf,
+ int alen)
+{
+ char *name;
+ int type, dnsclass, status, len;
+
+ /* Parse the question name. */
+ status = ares_expand_name(aptr, abuf, alen, &name, &len);
+ if (status != ARES_SUCCESS)
+ return NULL;
+ aptr += len;
+
+ /* Make sure there's enough data after the name for the fixed part
+ * of the question.
+ */
+ if (aptr + QFIXEDSZ > abuf + alen)
+ {
+ free(name);
+ return NULL;
+ }
+
+ /* Parse the question type and class. */
+ type = DNS_QUESTION_TYPE(aptr);
+ dnsclass = DNS_QUESTION_CLASS(aptr);
+ aptr += QFIXEDSZ;
+
+ /* Display the question, in a format sort of similar to how we will
+ * display RRs.
+ */
+ printf("\t%-15s.\t", name);
+ if (dnsclass != C_IN)
+ printf("\t%s", class_name(dnsclass));
+ printf("\t%s\n", type_name(type));
+ free(name);
+ return aptr;
+}
+
+static const unsigned char *display_rr(const unsigned char *aptr,
+ const unsigned char *abuf, int alen)
+{
+ const unsigned char *p;
+ char *name;
+ int type, dnsclass, ttl, dlen, status, len;
+ struct in_addr addr;
+
+ /* Parse the RR name. */
+ status = ares_expand_name(aptr, abuf, alen, &name, &len);
+ if (status != ARES_SUCCESS)
+ return NULL;
+ aptr += len;
+
+ /* Make sure there is enough data after the RR name for the fixed
+ * part of the RR.
+ */
+ if (aptr + RRFIXEDSZ > abuf + alen)
+ {
+ free(name);
+ return NULL;
+ }
+
+ /* Parse the fixed part of the RR, and advance to the RR data
+ * field. */
+ type = DNS_RR_TYPE(aptr);
+ dnsclass = DNS_RR_CLASS(aptr);
+ ttl = DNS_RR_TTL(aptr);
+ dlen = DNS_RR_LEN(aptr);
+ aptr += RRFIXEDSZ;
+ if (aptr + dlen > abuf + alen)
+ {
+ free(name);
+ return NULL;
+ }
+
+ /* Display the RR name, class, and type. */
+ printf("\t%-15s.\t%d", name, ttl);
+ if (dnsclass != C_IN)
+ printf("\t%s", class_name(dnsclass));
+ printf("\t%s", type_name(type));
+ free(name);
+
+ /* Display the RR data. Don't touch aptr. */
+ switch (type)
+ {
+ case T_CNAME:
+ case T_MB:
+ case T_MD:
+ case T_MF:
+ case T_MG:
+ case T_MR:
+ case T_NS:
+ case T_PTR:
+ /* For these types, the RR data is just a domain name. */
+ status = ares_expand_name(aptr, abuf, alen, &name, &len);
+ if (status != ARES_SUCCESS)
+ return NULL;
+ printf("\t%s.", name);
+ free(name);
+ break;
+
+ case T_HINFO:
+ /* The RR data is two length-counted character strings. */
+ p = aptr;
+ len = *p;
+ if (p + len + 1 > aptr + dlen)
+ return NULL;
+ printf("\t%.*s", len, p + 1);
+ p += len + 1;
+ len = *p;
+ if (p + len + 1 > aptr + dlen)
+ return NULL;
+ printf("\t%.*s", len, p + 1);
+ break;
+
+ case T_MINFO:
+ /* The RR data is two domain names. */
+ p = aptr;
+ status = ares_expand_name(p, abuf, alen, &name, &len);
+ if (status != ARES_SUCCESS)
+ return NULL;
+ printf("\t%s.", name);
+ free(name);
+ p += len;
+ status = ares_expand_name(p, abuf, alen, &name, &len);
+ if (status != ARES_SUCCESS)
+ return NULL;
+ printf("\t%s.", name);
+ free(name);
+ break;
+
+ case T_MX:
+ /* The RR data is two bytes giving a preference ordering, and
+ * then a domain name.
+ */
+ if (dlen < 2)
+ return NULL;
+ printf("\t%d", (aptr[0] << 8) | aptr[1]);
+ status = ares_expand_name(aptr + 2, abuf, alen, &name, &len);
+ if (status != ARES_SUCCESS)
+ return NULL;
+ printf("\t%s.", name);
+ free(name);
+ break;
+
+ case T_SOA:
+ /* The RR data is two domain names and then five four-byte
+ * numbers giving the serial number and some timeouts.
+ */
+ p = aptr;
+ status = ares_expand_name(p, abuf, alen, &name, &len);
+ if (status != ARES_SUCCESS)
+ return NULL;
+ printf("\t%s.\n", name);
+ free(name);
+ p += len;
+ status = ares_expand_name(p, abuf, alen, &name, &len);
+ if (status != ARES_SUCCESS)
+ return NULL;
+ printf("\t\t\t\t\t\t%s.\n", name);
+ free(name);
+ p += len;
+ if (p + 20 > aptr + dlen)
+ return NULL;
+ printf("\t\t\t\t\t\t( %d %d %d %d %d )",
+ (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3],
+ (p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7],
+ (p[8] << 24) | (p[9] << 16) | (p[10] << 8) | p[11],
+ (p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15],
+ (p[16] << 24) | (p[17] << 16) | (p[18] << 8) | p[19]);
+ break;
+
+ case T_TXT:
+ /* The RR data is one or more length-counted character
+ * strings. */
+ p = aptr;
+ while (p < aptr + dlen)
+ {
+ len = *p;
+ if (p + len + 1 > aptr + dlen)
+ return NULL;
+ printf("\t%.*s", len, p + 1);
+ p += len + 1;
+ }
+ break;
+
+ case T_A:
+ /* The RR data is a four-byte Internet address. */
+ if (dlen != 4)
+ return NULL;
+ memcpy(&addr, aptr, sizeof(struct in_addr));
+ printf("\t%s", inet_ntoa(addr));
+ break;
+
+ case T_WKS:
+ /* Not implemented yet */
+ break;
+
+ case T_SRV:
+ /* The RR data is three two-byte numbers representing the
+ * priority, weight, and port, followed by a domain name.
+ */
+
+ printf("\t%d", DNS__16BIT(aptr));
+ printf(" %d", DNS__16BIT(aptr + 2));
+ printf(" %d", DNS__16BIT(aptr + 4));
+
+ status = ares_expand_name(aptr + 6, abuf, alen, &name, &len);
+ if (status != ARES_SUCCESS)
+ return NULL;
+ printf("\t%s.", name);
+ free(name);
+ break;
+
+ default:
+ printf("\t[Unknown RR; cannot parse]");
+ }
+ printf("\n");
+
+ return aptr + dlen;
+}
+
+static const char *type_name(int type)
+{
+ int i;
+
+ for (i = 0; i < ntypes; i++)
+ {
+ if (types[i].value == type)
+ return types[i].name;
+ }
+ return "(unknown)";
+}
+
+static const char *class_name(int dnsclass)
+{
+ int i;
+
+ for (i = 0; i < nclasses; i++)
+ {
+ if (classes[i].value == dnsclass)
+ return classes[i].name;
+ }
+ return "(unknown)";
+}
+
+static void usage(void)
+{
+ fprintf(stderr, "usage: adig [-f flag] [-s server] [-c class] "
+ "[-t type] [-p port] name ...\n");
+ exit(1);
+}
122 ahost.c
@@ -0,0 +1,122 @@
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+static const char rcsid[] = "$Id$";
+
+#include <sys/types.h>
+
+#ifdef WIN32
+#else
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ares.h"
+#include "ares_dns.h"
+
+#ifndef INADDR_NONE
+#define INADDR_NONE 0xffffffff
+#endif
+
+static void callback(void *arg, int status, struct hostent *host);
+static void usage(void);
+
+int main(int argc, char **argv)
+{
+ ares_channel channel;
+ int status, nfds;
+ fd_set read_fds, write_fds;
+ struct timeval *tvp, tv;
+ char *errmem;
+ struct in_addr addr;
+
+#ifdef WIN32
+ WORD wVersionRequested = MAKEWORD(1,1);
+ WSADATA wsaData;
+ WSAStartup(wVersionRequested, &wsaData);
+#endif
+
+ if (argc == 0)
+ usage();
+
+ status = ares_init(&channel);
+ if (status != ARES_SUCCESS)
+ {
+ fprintf(stderr, "ares_init: %s\n", ares_strerror(status, &errmem));
+ ares_free_errmem(errmem);
+ return 1;
+ }
+
+ /* Initiate the queries, one per command-line argument. */
+ for (argv++; *argv; argv++)
+ {
+ addr.s_addr = inet_addr(*argv);
+ if (addr.s_addr == INADDR_NONE)
+ ares_gethostbyname(channel, *argv, AF_INET, callback, *argv);
+ else
+ {
+ ares_gethostbyaddr(channel, &addr, sizeof(addr), AF_INET, callback,
+ *argv);
+ }
+ }
+
+ /* Wait for all queries to complete. */
+ while (1)
+ {
+ FD_ZERO(&read_fds);
+ FD_ZERO(&write_fds);
+ nfds = ares_fds(channel, &read_fds, &write_fds);
+ if (nfds == 0)
+ break;
+ tvp = ares_timeout(channel, NULL, &tv);
+ select(nfds, &read_fds, &write_fds, NULL, tvp);
+ ares_process(channel, &read_fds, &write_fds);
+ }
+
+ ares_destroy(channel);
+ return 0;
+}
+
+static void callback(void *arg, int status, struct hostent *host)
+{
+ struct in_addr addr;
+ char *mem, **p;
+
+ if (status != ARES_SUCCESS)
+ {
+ fprintf(stderr, "%s: %s\n", (char *) arg, ares_strerror(status, &mem));
+ ares_free_errmem(mem);
+ return;
+ }
+
+ for (p = host->h_addr_list; *p; p++)
+ {
+ memcpy(&addr, *p, sizeof(struct in_addr));
+ printf("%-32s\t%s\n", host->h_name, inet_ntoa(addr));
+ }
+}
+
+static void usage(void)
+{
+ fprintf(stderr, "usage: ahost {host|addr} ...\n");
+ exit(1);
+}
130 ares.h
@@ -0,0 +1,130 @@
+/* $Id$ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#ifndef ARES__H
+#define ARES__H
+
+#include <sys/types.h>
+
+#ifdef WIN32
+#include <winsock.h>
+#include <windows.h>
+#else
+#include <netinet/in.h>
+#endif
+
+#define ARES_SUCCESS 0
+
+/* Server error codes (ARES_ENODATA indicates no relevant answer) */
+#define ARES_ENODATA 1
+#define ARES_EFORMERR 2
+#define ARES_ESERVFAIL 3
+#define ARES_ENOTFOUND 4
+#define ARES_ENOTIMP 5
+#define ARES_EREFUSED 6
+
+/* Locally generated error codes */
+#define ARES_EBADQUERY 7
+#define ARES_EBADNAME 8
+#define ARES_EBADFAMILY 9
+#define ARES_EBADRESP 10
+#define ARES_ECONNREFUSED 11
+#define ARES_ETIMEOUT 12
+#define ARES_EOF 13
+#define ARES_EFILE 14
+#define ARES_ENOMEM 15
+#define ARES_EDESTRUCTION 16
+
+/* Flag values */
+#define ARES_FLAG_USEVC (1 << 0)
+#define ARES_FLAG_PRIMARY (1 << 1)
+#define ARES_FLAG_IGNTC (1 << 2)
+#define ARES_FLAG_NORECURSE (1 << 3)
+#define ARES_FLAG_STAYOPEN (1 << 4)
+#define ARES_FLAG_NOSEARCH (1 << 5)
+#define ARES_FLAG_NOALIASES (1 << 6)
+#define ARES_FLAG_NOCHECKRESP (1 << 7)
+
+/* Option mask values */
+#define ARES_OPT_FLAGS (1 << 0)
+#define ARES_OPT_TIMEOUT (1 << 1)
+#define ARES_OPT_TRIES (1 << 2)
+#define ARES_OPT_NDOTS (1 << 3)
+#define ARES_OPT_UDP_PORT (1 << 4)
+#define ARES_OPT_TCP_PORT (1 << 5)
+#define ARES_OPT_SERVERS (1 << 6)
+#define ARES_OPT_DOMAINS (1 << 7)
+#define ARES_OPT_LOOKUPS (1 << 8)
+
+struct ares_options {
+ int flags;
+ int timeout;
+ int tries;
+ int ndots;
+ unsigned short udp_port;
+ unsigned short tcp_port;
+ struct in_addr *servers;
+ int nservers;
+ char **domains;
+ int ndomains;
+ char *lookups;
+};
+
+struct hostent;
+struct timeval;
+struct ares_channeldata;
+typedef struct ares_channeldata *ares_channel;
+typedef void (*ares_callback)(void *arg, int status, unsigned char *abuf,
+ int alen);
+typedef void (*ares_host_callback)(void *arg, int status,
+ struct hostent *hostent);
+
+int ares_init(ares_channel *channelptr);
+int ares_init_options(ares_channel *channelptr, struct ares_options *options,
+ int optmask);
+void ares_destroy(ares_channel channel);
+
+void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
+ ares_callback callback, void *arg);
+void ares_query(ares_channel channel, const char *name, int dnsclass,
+ int type, ares_callback callback, void *arg);
+void ares_search(ares_channel channel, const char *name, int dnsclass,
+ int type, ares_callback callback, void *arg);
+void ares_gethostbyname(ares_channel channel, const char *name, int family,
+ ares_host_callback callback, void *arg);
+void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
+ int family, ares_host_callback callback, void *arg);
+
+int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds);
+struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv,
+ struct timeval *tv);
+void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds);
+
+int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id,
+ int rd, unsigned char **buf, int *buflen);
+int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
+ int alen, char **s, int *enclen);
+int ares_parse_a_reply(const unsigned char *abuf, int alen,
+ struct hostent **host);
+int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
+ int addrlen, int family, struct hostent **host);
+void ares_free_string(char *str);
+void ares_free_hostent(struct hostent *host);
+const char *ares_strerror(int code, char **memptr);
+void ares_free_errmem(char *mem);
+
+#endif /* ARES__H */
57 ares__close_sockets.c
@@ -0,0 +1,57 @@
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+static const char rcsid[] = "$Id$";
+
+#include <stdlib.h>
+#ifdef WIN32
+#else
+#include <unistd.h>
+#endif
+#include "ares.h"
+#include "ares_private.h"
+
+void ares__close_sockets(struct server_state *server)
+{
+ struct send_request *sendreq;
+
+ /* Free all pending output buffers. */
+ while (server->qhead)
+ {
+ /* Advance server->qhead; pull out query as we go. */
+ sendreq = server->qhead;
+ server->qhead = sendreq->next;
+ free(sendreq);
+ }
+ server->qtail = NULL;
+
+ /* Reset any existing input buffer. */
+ if (server->tcp_buffer)
+ free(server->tcp_buffer);
+ server->tcp_buffer = NULL;
+ server->tcp_lenbuf_pos = 0;
+
+ /* Close the TCP and UDP sockets. */
+ if (server->tcp_socket != -1)
+ {
+ closesocket(server->tcp_socket);
+ server->tcp_socket = -1;
+ }
+ if (server->udp_socket != -1)
+ {
+ closesocket(server->udp_socket);
+ server->udp_socket = -1;
+ }
+}
171 ares__get_hostent.c
@@ -0,0 +1,171 @@
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+static const char rcsid[] = "$Id$";
+
+#include <sys/types.h>
+
+#ifdef WIN32
+
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "ares.h"
+#include "ares_private.h"
+
+int ares__get_hostent(FILE *fp, struct hostent **host)
+{
+ char *line = NULL, *p, *q, *canonical, **alias;
+ int status, linesize, end_at_hostname, naliases;
+ struct in_addr addr;
+ struct hostent *hostent = NULL;
+
+ while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
+ {
+ /* Skip comment lines; terminate line at comment character. */
+ if (*line == '#' || !*line)
+ continue;
+ p = strchr(line, '#');
+ if (p)
+ *p = 0;
+
+ /* Get the address part. */
+ p = line;
+ while (*p && !isspace((unsigned char)*p))
+ p++;
+ if (!*p)
+ continue;
+ *p = 0;
+ addr.s_addr = inet_addr(line);
+ if (addr.s_addr == INADDR_NONE)
+ continue;
+
+ /* Get the canonical hostname. */
+ p++;
+ while (isspace((unsigned char)*p))
+ p++;
+ if (!*p)
+ continue;
+ q = p;
+ while (*q && !isspace((unsigned char)*q))
+ q++;
+ end_at_hostname = (*q == 0);
+ *q = 0;
+ canonical = p;
+
+ naliases = 0;
+ if (!end_at_hostname)
+ {
+ /* Count the aliases. */
+ p = q + 1;
+ while (isspace((unsigned char)*p))
+ p++;
+ while (*p)
+ {
+ while (*p && !isspace((unsigned char)*p))
+ p++;
+ while (isspace((unsigned char)*p))
+ p++;
+ naliases++;
+ }
+ }
+
+ /* Allocate memory for the host structure. */
+ hostent = malloc(sizeof(struct hostent));
+ if (!hostent)
+ break;
+ hostent->h_aliases = NULL;
+ hostent->h_addr_list = NULL;
+ hostent->h_name = strdup(canonical);
+ if (!hostent->h_name)
+ break;
+ hostent->h_addr_list = malloc(2 * sizeof(char *));
+ if (!hostent->h_addr_list)
+ break;
+ hostent->h_addr_list[0] = malloc(sizeof(struct in_addr));
+ if (!hostent->h_addr_list[0])
+ break;
+ hostent->h_aliases = malloc((naliases + 1) * sizeof(char *));
+ if (!hostent->h_aliases)
+ break;
+
+ /* Copy in aliases. */
+ naliases = 0;
+ if (!end_at_hostname)
+ {
+ p = canonical + strlen(canonical) + 1;
+ while (isspace((unsigned char)*p))
+ p++;
+ while (*p)
+ {
+ q = p;
+ while (*q && !isspace((unsigned char)*q))
+ q++;
+ hostent->h_aliases[naliases] = malloc(q - p + 1);
+ if (hostent->h_aliases[naliases] == NULL)
+ break;
+ memcpy(hostent->h_aliases[naliases], p, q - p);
+ hostent->h_aliases[naliases][q - p] = 0;
+ p = q;
+ while (isspace((unsigned char)*p))
+ p++;
+ naliases++;
+ }
+ if (*p)
+ break;
+ }
+ hostent->h_aliases[naliases] = NULL;
+
+ hostent->h_addrtype = AF_INET;
+ hostent->h_length = sizeof(struct in_addr);
+ memcpy(hostent->h_addr_list[0], &addr, sizeof(struct in_addr));
+ hostent->h_addr_list[1] = NULL;
+ *host = hostent;
+ free(line);
+ return ARES_SUCCESS;
+ }
+ free(line);
+
+ if (status == ARES_SUCCESS)
+ {
+ /* Memory allocation failure; clean up. */
+ if (hostent)
+ {
+ free((char *) hostent->h_name);
+ if (hostent->h_aliases)
+ {
+ for (alias = hostent->h_aliases; *alias; alias++)
+ free(*alias);
+ }
+ free(hostent->h_aliases);
+ if (hostent->h_addr_list)
+ free(hostent->h_addr_list[0]);
+ free(hostent->h_addr_list);
+ }
+ free(hostent);
+ return ARES_ENOMEM;
+ }
+
+ return status;
+}
64 ares__read_line.c
@@ -0,0 +1,64 @@
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+static const char rcsid[] = "$Id$";
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ares.h"
+#include "ares_private.h"
+
+/* This is an internal function. Its contract is to read a line from
+ * a file into a dynamically allocated buffer, zeroing the trailing
+ * newline if there is one. The calling routine may call
+ * ares__read_line multiple times with the same buf and bufsize
+ * pointers; *buf will be reallocated and *bufsize adjusted as
+ * appropriate. The initial value of *buf should be NULL. After the
+ * calling routine is done reading lines, it should free *buf.
+ */
+int ares__read_line(FILE *fp, char **buf, int *bufsize)
+{
+ char *newbuf;
+ int offset = 0, len;
+
+ if (*buf == NULL)
+ {
+ *buf = malloc(128);
+ if (!*buf)
+ return ARES_ENOMEM;
+ *bufsize = 128;
+ }
+
+ while (1)
+ {
+ if (!fgets(*buf + offset, *bufsize - offset, fp))
+ return (offset != 0) ? 0 : (ferror(fp)) ? ARES_EFILE : ARES_EOF;
+ len = offset + strlen(*buf + offset);
+ if ((*buf)[len - 1] == '\n')
+ {
+ (*buf)[len - 1] = 0;
+ return ARES_SUCCESS;
+ }
+ offset = len;
+
+ /* Allocate more space. */
+ newbuf = realloc(*buf, *bufsize * 2);
+ if (!newbuf)
+ return ARES_ENOMEM;
+ *buf = newbuf;
+ *bufsize *= 2;
+ }
+}
43 ares_destroy.3
@@ -0,0 +1,43 @@
+.\" $Id$
+.\"
+.\" Copyright 1998 by the Massachusetts Institute of Technology.
+.\"
+.\" Permission to use, copy, modify, and distribute this
+.\" software and its documentation for any purpose and without
+.\" fee is hereby granted, provided that the above copyright
+.\" notice appear in all copies and that both that copyright
+.\" notice and this permission notice appear in supporting
+.\" documentation, and that the name of M.I.T. not be used in
+.\" advertising or publicity pertaining to distribution of the
+.\" software without specific, written prior permission.
+.\" M.I.T. makes no representations about the suitability of
+.\" this software for any purpose. It is provided "as is"
+.\" without express or implied warranty.
+.\"
+.TH ARES_DESTROY 3 "23 July 1998"
+.SH NAME
+ares_destroy \- Destroy a resolver channel
+.SH SYNOPSIS
+.nf
+.B #include <ares.h>
+.PP
+.B int ares_destroy(ares_channel \fIchannel\fP)
+.fi
+.SH DESCRIPTION
+The
+.B ares_destroy
+function destroys the name service channel identified by
+.IR channel ,
+freeing all memory and closing all sockets used by the channel.
+.B ares_destroy
+invokes the callbacks for each pending query on the channel, passing a
+status of
+.BR ARES_EDESTRUCTION .
+These calls give the callbacks a chance to clean up any state which
+might have been stored in their arguments.
+.SH SEE ALSO
+.BR ares_init (3)
+.SH AUTHOR
+Greg Hudson, MIT Information Systems
+.br
+Copyright 1998 by the Massachusetts Institute of Technology.
45 ares_destroy.c
@@ -0,0 +1,45 @@
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+static const char rcsid[] = "$Id$";
+
+#include <stdlib.h>
+#include "ares.h"
+#include "ares_private.h"
+
+void ares_destroy(ares_channel channel)
+{
+ int i;
+ struct query *query;
+
+ for (i = 0; i < channel->nservers; i++)
+ ares__close_sockets(&channel->servers[i]);
+ free(channel->servers);
+ for (i = 0; i < channel->ndomains; i++)
+ free(channel->domains[i]);
+ free(channel->domains);
+ free(channel->sortlist);
+ free(channel->lookups);
+ while (channel->queries)
+ {
+ query = channel->queries;
+ channel->queries = query->next;
+ query->callback(query->arg, ARES_EDESTRUCTION, NULL, 0);
+ free(query->tcpbuf);
+ free(query->skip_server);
+ free(query);
+ }
+ free(channel);
+}
81 ares_dns.h
@@ -0,0 +1,81 @@
+/* $Id$ */
+
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#ifndef ARES__DNS_H
+#define ARES__DNS_H
+
+#define DNS__16BIT(p) (((p)[0] << 8) | (p)[1])
+#define DNS__32BIT(p) (((p)[0] << 24) | ((p)[1] << 16) | \
+ ((p)[2] << 8) | (p)[3])
+#define DNS__SET16BIT(p, v) (((p)[0] = ((v) >> 8) & 0xff), \
+ ((p)[1] = (v) & 0xff))
+#define DNS__SET32BIT(p, v) (((p)[0] = ((v) >> 24) & 0xff), \
+ ((p)[1] = ((v) >> 16) & 0xff), \
+ ((p)[2] = ((v) >> 8) & 0xff), \
+ ((p)[3] = (v) & 0xff))
+
+/* Macros for parsing a DNS header */
+#define DNS_HEADER_QID(h) DNS__16BIT(h)
+#define DNS_HEADER_QR(h) (((h)[2] >> 7) & 0x1)
+#define DNS_HEADER_OPCODE(h) (((h)[2] >> 3) & 0xf)
+#define DNS_HEADER_AA(h) (((h)[2] >> 2) & 0x1)
+#define DNS_HEADER_TC(h) (((h)[2] >> 1) & 0x1)
+#define DNS_HEADER_RD(h) ((h)[2] & 0x1)
+#define DNS_HEADER_RA(h) (((h)[3] >> 7) & 0x1)
+#define DNS_HEADER_Z(h) (((h)[3] >> 4) & 0x7)
+#define DNS_HEADER_RCODE(h) ((h)[3] & 0xf)
+#define DNS_HEADER_QDCOUNT(h) DNS__16BIT((h) + 4)
+#define DNS_HEADER_ANCOUNT(h) DNS__16BIT((h) + 6)
+#define DNS_HEADER_NSCOUNT(h) DNS__16BIT((h) + 8)
+#define DNS_HEADER_ARCOUNT(h) DNS__16BIT((h) + 10)
+
+/* Macros for constructing a DNS header */
+#define DNS_HEADER_SET_QID(h, v) DNS__SET16BIT(h, v)
+#define DNS_HEADER_SET_QR(h, v) ((h)[2] |= (((v) & 0x1) << 7))
+#define DNS_HEADER_SET_OPCODE(h, v) ((h)[2] |= (((v) & 0xf) << 3))
+#define DNS_HEADER_SET_AA(h, v) ((h)[2] |= (((v) & 0x1) << 2))
+#define DNS_HEADER_SET_TC(h, v) ((h)[2] |= (((v) & 0x1) << 1))
+#define DNS_HEADER_SET_RD(h, v) ((h)[2] |= (((v) & 0x1)))
+#define DNS_HEADER_SET_RA(h, v) ((h)[3] |= (((v) & 0x1) << 7))
+#define DNS_HEADER_SET_Z(h, v) ((h)[3] |= (((v) & 0x7) << 4))
+#define DNS_HEADER_SET_RCODE(h, v) ((h)[3] |= (((v) & 0xf)))
+#define DNS_HEADER_SET_QDCOUNT(h, v) DNS__SET16BIT((h) + 4, v)
+#define DNS_HEADER_SET_ANCOUNT(h, v) DNS__SET16BIT((h) + 6, v)
+#define DNS_HEADER_SET_NSCOUNT(h, v) DNS__SET16BIT((h) + 8, v)
+#define DNS_HEADER_SET_ARCOUNT(h, v) DNS__SET16BIT((h) + 10, v)
+
+/* Macros for parsing the fixed part of a DNS question */
+#define DNS_QUESTION_TYPE(q) DNS__16BIT(q)
+#define DNS_QUESTION_CLASS(q) DNS__16BIT((q) + 2)
+
+/* Macros for constructing the fixed part of a DNS question */
+#define DNS_QUESTION_SET_TYPE(q, v) DNS__SET16BIT(q, v)
+#define DNS_QUESTION_SET_CLASS(q, v) DNS__SET16BIT((q) + 2, v)
+
+/* Macros for parsing the fixed part of a DNS resource record */
+#define DNS_RR_TYPE(r) DNS__16BIT(r)
+#define DNS_RR_CLASS(r) DNS__16BIT((r) + 2)
+#define DNS_RR_TTL(r) DNS__32BIT((r) + 4)
+#define DNS_RR_LEN(r) DNS__16BIT((r) + 8)
+
+/* Macros for constructing the fixed part of a DNS resource record */
+#define DNS_RR_SET_TYPE(r) DNS__SET16BIT(r, v)
+#define DNS_RR_SET_CLASS(r) DNS__SET16BIT((r) + 2, v)
+#define DNS_RR_SET_TTL(r) DNS__SET32BIT((r) + 4, v)
+#define DNS_RR_SET_LEN(r) DNS__SET16BIT((r) + 8, v)
+
+#endif /* ARES__DNS_H */
65 ares_expand_name.3
@@ -0,0 +1,65 @@
+.\" $Id$
+.\"
+.\" Copyright 1998 by the Massachusetts Institute of Technology.
+.\"
+.\" Permission to use, copy, modify, and distribute this
+.\" software and its documentation for any purpose and without
+.\" fee is hereby granted, provided that the above copyright
+.\" notice appear in all copies and that both that copyright
+.\" notice and this permission notice appear in supporting
+.\" documentation, and that the name of M.I.T. not be used in
+.\" advertising or publicity pertaining to distribution of the
+.\" software without specific, written prior permission.
+.\" M.I.T. makes no representations about the suitability of
+.\" this software for any purpose. It is provided "as is"
+.\" without express or implied warranty.
+.\"
+.TH ARES_EXPAND_NAME 3 "23 July 1998"
+.SH NAME
+ares_expand_name \- Expand a DNS-encoded domain name
+.SH SYNOPSIS
+.nf
+.B #include <ares.h>
+.PP
+.B int ares_expand_name(const unsigned char *\fIencoded\fP,
+.B
+ const unsigned char *\fIabuf\fP, int \fIalen\fP, char **\fIs\fP,
+.B int *\fIenclen\fP)
+.fi
+.SH DESCRIPTION
+The
+.B ares_expand_name
+function converts a DNS-encoded domain name to a dot-separated C
+string. The argument
+.I encoded
+gives the beginning of the encoded domain name, and the arguments
+.I abuf
+and
+.I alen
+give the containing message buffer (necessary for the processing of
+indirection pointers within the encoded domain name). The result is
+placed in a NUL-terminated allocated buffer, a pointer to which is
+stored in the variable pointed to by
+.IR s .
+The length of the encoded name is stored in the variable pointed to by
+.I enclen
+so that the caller can advance past the encoded domain name to read
+further data in the message.
+.SH RETURN VALUES
+.B ares_expand_name
+can return any of the following values:
+.TP 15
+.B ARES_SUCCESS
+Expansion of the encoded name succeeded.
+.TP 15
+.B ARES_EBADNAME
+The encoded domain name was malformed and could not be expanded.
+.TP 15
+.B ARES_ENOMEM
+Memory was exhausted.
+.SH SEE ALSO
+.BR ares_mkquery (3)
+.SH AUTHOR
+Greg Hudson, MIT Information Systems
+.br
+Copyright 1998 by the Massachusetts Institute of Technology.
159 ares_expand_name.c
@@ -0,0 +1,159 @@
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+static const char rcsid[] = "$Id$";
+
+#include <sys/types.h>
+
+#ifdef WIN32
+#include "nameser.h"
+#else
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#endif
+
+#include <stdlib.h>
+#include "ares.h"
+
+static int name_length(const unsigned char *encoded, const unsigned char *abuf,
+ int alen);
+
+/* Expand an RFC1035-encoded domain name given by encoded. The
+ * containing message is given by abuf and alen. The result given by
+ * *s, which is set to a NUL-terminated allocated buffer. *enclen is
+ * set to the length of the encoded name (not the length of the
+ * expanded name; the goal is to tell the caller how many bytes to
+ * move forward to get past the encoded name).
+ *
+ * In the simple case, an encoded name is a series of labels, each
+ * composed of a one-byte length (limited to values between 0 and 63
+ * inclusive) followed by the label contents. The name is terminated
+ * by a zero-length label.
+ *
+ * In the more complicated case, a label may be terminated by an
+ * indirection pointer, specified by two bytes with the high bits of
+ * the first byte (corresponding to INDIR_MASK) set to 11. With the
+ * two high bits of the first byte stripped off, the indirection
+ * pointer gives an offset from the beginning of the containing
+ * message with more labels to decode. Indirection can happen an
+ * arbitrary number of times, so we have to detect loops.
+ *
+ * Since the expanded name uses '.' as a label separator, we use
+ * backslashes to escape periods or backslashes in the expanded name.
+ */
+
+int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
+ int alen, char **s, int *enclen)
+{
+ int len, indir = 0;
+ char *q;
+ const unsigned char *p;
+
+ len = name_length(encoded, abuf, alen);
+ if (len == -1)
+ return ARES_EBADNAME;
+
+ *s = malloc(len + 1);
+ if (!*s)
+ return ARES_ENOMEM;
+ q = *s;
+
+ /* No error-checking necessary; it was all done by name_length(). */
+ p = encoded;
+ while (*p)
+ {
+ if ((*p & INDIR_MASK) == INDIR_MASK)
+ {
+ if (!indir)
+ {
+ *enclen = p + 2 - encoded;
+ indir = 1;
+ }
+ p = abuf + ((*p & ~INDIR_MASK) << 8 | *(p + 1));
+ }
+ else
+ {
+ len = *p;
+ p++;
+ while (len--)
+ {
+ if (*p == '.' || *p == '\\')
+ *q++ = '\\';
+ *q++ = *p;
+ p++;
+ }
+ *q++ = '.';
+ }
+ }
+ if (!indir)
+ *enclen = p + 1 - encoded;
+
+ /* Nuke the trailing period if we wrote one. */
+ if (q > *s)
+ *(q - 1) = 0;
+
+ return ARES_SUCCESS;
+}
+
+/* Return the length of the expansion of an encoded domain name, or
+ * -1 if the encoding is invalid.
+ */
+static int name_length(const unsigned char *encoded, const unsigned char *abuf,
+ int alen)
+{
+ int n = 0, offset, indir = 0;
+
+ /* Allow the caller to pass us abuf + alen and have us check for it. */
+ if (encoded == abuf + alen)
+ return -1;
+
+ while (*encoded)
+ {
+ if ((*encoded & INDIR_MASK) == INDIR_MASK)
+ {
+ /* Check the offset and go there. */
+ if (encoded + 1 >= abuf + alen)
+ return -1;
+ offset = (*encoded & ~INDIR_MASK) << 8 | *(encoded + 1);
+ if (offset >= alen)
+ return -1;
+ encoded = abuf + offset;
+
+ /* If we've seen more indirects than the message length,
+ * then there's a loop.
+ */
+ if (++indir > alen)
+ return -1;
+ }
+ else
+ {
+ offset = *encoded;
+ if (encoded + offset + 1 >= abuf + alen)
+ return -1;
+ encoded++;
+ while (offset--)
+ {
+ n += (*encoded == '.' || *encoded == '\\') ? 2 : 1;
+ encoded++;
+ }
+ n++;
+ }
+ }
+
+ /* If there were any labels at all, then the number of dots is one
+ * less than the number of labels, so subtract one.
+ */
+ return (n) ? n - 1 : n;
+}
62 ares_fds.3
@@ -0,0 +1,62 @@
+.\" $Id$
+.\"
+.\" Copyright 1998 by the Massachusetts Institute of Technology.
+.\"
+.\" Permission to use, copy, modify, and distribute this
+.\" software and its documentation for any purpose and without
+.\" fee is hereby granted, provided that the above copyright
+.\" notice appear in all copies and that both that copyright
+.\" notice and this permission notice appear in supporting
+.\" documentation, and that the name of M.I.T. not be used in
+.\" advertising or publicity pertaining to distribution of the
+.\" software without specific, written prior permission.
+.\" M.I.T. makes no representations about the suitability of
+.\" this software for any purpose. It is provided "as is"
+.\" without express or implied warranty.
+.\"
+.TH ARES_FDS 3 "23 July 1998"
+.SH NAME
+ares_fds \- Get file descriptors to select on for name service
+.SH SYNOPSIS
+.nf
+.B #include <ares.h>
+.PP
+.B int ares_fds(ares_channel \fIchannel\fP, fd_set *\fIread_fds\fP,
+.B fd_set *\fIwrite_fds\fP)
+.fi
+.SH DESCRIPTION
+The
+.B ares_fds
+function retrieves the set of file descriptors which the calling
+application should select on for reading and writing for the
+processing of name service queries pending on the name service channel
+identified by
+.IR channel .
+File descriptors will be set in the file descriptor sets pointed to by
+.I read_fds
+and
+.I write_fds
+as appropriate. File descriptors already set in
+.I read_fds
+and
+.I write_fds
+will remain set; initialization of the file descriptor sets
+(using
+.BR FD_ZERO )
+is the responsibility of the caller.
+.SH RETURN VALUES
+.B ares_fds
+returns one greater than the number of the highest socket set in either
+.I read_fds
+or
+.IR write_fds .
+If no queries are active,
+.B ares_fds
+will return 0.
+.SH SEE ALSO
+.BR ares_timeout (3),
+.BR ares_process (3)
+.SH AUTHOR
+Greg Hudson, MIT Information Systems
+.br
+Copyright 1998 by the Massachusetts Institute of Technology.
58 ares_fds.c
@@ -0,0 +1,58 @@
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+static const char rcsid[] = "$Id$";
+
+#include <sys/types.h>
+
+#ifdef WIN32
+
+#else
+#include <sys/time.h>
+#endif
+
+#include "ares.h"
+#include "ares_private.h"
+
+int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds)
+{
+ struct server_state *server;
+ int i, nfds;
+
+ /* No queries, no file descriptors. */
+ if (!channel->queries)
+ return 0;
+
+ nfds = 0;
+ for (i = 0; i < channel->nservers; i++)
+ {
+ server = &channel->servers[i];
+ if (server->udp_socket != -1)
+ {
+ FD_SET(server->udp_socket, read_fds);
+ if (server->udp_socket >= nfds)
+ nfds = server->udp_socket + 1;
+ }
+ if (server->tcp_socket != -1)
+ {
+ FD_SET(server->tcp_socket, read_fds);
+ if (server->qhead)
+ FD_SET(server->tcp_socket, write_fds);
+ if (server->tcp_socket >= nfds)
+ nfds = server->tcp_socket + 1;
+ }
+ }
+ return nfds;
+}
42 ares_free_errmem.3
@@ -0,0 +1,42 @@
+.\" $Id$
+.\"
+.\" Copyright 1998 by the Massachusetts Institute of Technology.
+.\"
+.\" Permission to use, copy, modify, and distribute this
+.\" software and its documentation for any purpose and without
+.\" fee is hereby granted, provided that the above copyright
+.\" notice appear in all copies and that both that copyright
+.\" notice and this permission notice appear in supporting
+.\" documentation, and that the name of M.I.T. not be used in
+.\" advertising or publicity pertaining to distribution of the
+.\" software without specific, written prior permission.
+.\" M.I.T. makes no representations about the suitability of
+.\" this software for any purpose. It is provided "as is"
+.\" without express or implied warranty.
+.\"
+.TH ARES_FREE_ERRMEM 3 "23 July 1998"
+.SH NAME
+ares_free_errmem \- Free memory allocated by ares_strerror
+.SH SYNOPSIS
+.nf
+.B #include <ares.h>
+.PP
+.B void ares_free_errmem(char *\fIerrmem\fP)
+.fi
+.SH DESCRIPTION
+The
+.B ares_free_errmem
+function frees any memory which might have been allocated by the
+.BR ares_strerror (3)
+function. The parameter
+.I errmem
+should be set to the variable pointed to by the
+.I memptr
+argument previously passed to
+.IR ares_strerror .
+.SH SEE ALSO
+.BR ares_strerror (3)
+.SH AUTHOR
+Greg Hudson, MIT Information Systems
+.br
+Copyright 1998 by the Massachusetts Institute of Technology.
26 ares_free_errmem.c
@@ -0,0 +1,26 @@
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+static const char rcsid[] = "$Id$";
+
+#include "ares.h"
+
+/* Do nothing, for now. A future implementation may want to deal with
+ * internationalization, in which case ares_strerror() might allocate
+ * memory which we would then have to free.
+ */
+void ares_free_errmem(char *mem)
+{
+}
49 ares_free_hostent.3
@@ -0,0 +1,49 @@
+.\" $Id$
+.\"
+.\" Copyright 1998 by the Massachusetts Institute of Technology.
+.\"
+.\" Permission to use, copy, modify, and distribute this
+.\" software and its documentation for any purpose and without
+.\" fee is hereby granted, provided that the above copyright
+.\" notice appear in all copies and that both that copyright
+.\" notice and this permission notice appear in supporting
+.\" documentation, and that the name of M.I.T. not be used in
+.\" advertising or publicity pertaining to distribution of the
+.\" software without specific, written prior permission.
+.\" M.I.T. makes no representations about the suitability of
+.\" this software for any purpose. It is provided "as is"
+.\" without express or implied warranty.
+.\"
+.TH ARES_FREE_HOSTENT 3 "23 July 1998"
+.SH NAME
+ares_free_hostent \- Free host structure allocated by ares functions
+.SH SYNOPSIS
+.nf
+.B #include <ares.h>
+.PP
+.B void ares_free_hostent(struct hostent *\fIhost\fP)
+.fi
+.SH DESCRIPTION
+The
+.I ares_free_hostent
+function frees a
+.B struct hostent
+allocated by one of the functions
+.I ares_parse_a_reply
+or
+.IR ares_parse_ptr_reply .
+.SH SEE ALSO
+.BR ares_parse_a_reply (3),
+.BR ares_parse_ptr_reply (3)
+.SH NOTES
+It is not necessary (and is not correct) to free the host structure
+passed to the callback functions for
+.I ares_gethostbyname
+or
+.IR ares_gethostbyaddr .
+The ares library will automatically free such host structures when the
+callback returns.
+.SH AUTHOR
+Greg Hudson, MIT Information Systems
+.br
+Copyright 1998 by the Massachusetts Institute of Technology.
39 ares_free_hostent.c
@@ -0,0 +1,39 @@
+/* Copyright 1998 by the Massachusetts Institute of Technology.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+static const char rcsid[] = "$Id$";
+
+#include <stdlib.h>
+
+#ifdef WIN32
+
+#else
+#include <netdb.h>
+#endif
+
+#include "ares.h"
+
+void ares_free_hostent(struct hostent *host)
+{
+ char **p;
+
+ free(host->h_name);
+ for (p = host->h_aliases; *p; p++)
+ free(*p);
+ free(host->h_aliases);
+ free(host->h_addr_list[0]);
+ free(host->h_addr_list);
+ free(host);
+}
37 ares_free_string.3
@@ -0,0 +1,37 @@
+.\" $Id$
+.\"
+.\" Copyright 2000 by the Massachusetts Institute of Technology.
+.\"
+.\" Permission to use, copy, modify, and distribute this
+.\" software and its documentation for any purpose and without
+.\" fee is hereby granted, provided that the above copyright
+.\" notice appear in all copies and that both that copyright
+.\" notice and this permission notice appear in supporting
+.\" documentation, and that the name of M.I.T. not be used in
+.\" advertising or publicity pertaining to distribution of the
+.\" software without specific, written prior permission.
+.\" M.I.T. makes no representations about the suitability of
+.\" this software for any purpose. It is provided "as is"