commit
5e847a14bd
70 changed files with 11352 additions and 0 deletions
@ -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 |
@ -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
|
@ -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. |
@ -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. |
@ -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]) |
@ -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); |
||||
} |
@ -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); |
||||
} |
@ -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 */ |
@ -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; |
||||
} |
||||
} |
@ -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; |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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. |
@ -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); |
||||
} |
@ -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 */ |
@ -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. |
@ -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; |
||||
} |
@ -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. |
@ -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; |
||||
} |
@ -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. |
@ -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) |
||||
{ |
||||
} |
@ -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. |
@ -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); |
||||
} |
@ -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" |
||||
.\" without express or implied warranty. |
||||
.\" |
||||
.TH ARES_FREE_STRING 3 "4 January 2000" |
||||
.SH NAME |
||||
ares_free_string \- Free strings allocated by ares functions |
||||
.SH SYNOPSIS |
||||
.nf |
||||
.B #include <ares.h> |
||||
.PP |
||||
.B void ares_free_string(char *\fIstr\fP) |
||||
.fi |
||||
.SH DESCRIPTION |
||||
The |
||||
.I ares_free_string |
||||
function frees a string allocated by the |
||||
.I ares_mkquery |
||||
function. |
||||
.SH SEE ALSO |
||||
.BR ares_mkquery (3) |
||||
.SH AUTHOR |
||||
Greg Hudson, MIT Information Systems |
||||
.br |
||||
Copyright 2000 by the Massachusetts Institute of Technology. |
@ -0,0 +1,24 @@ |
||||
/* 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" |
||||
* without express or implied warranty. |
||||
*/ |
||||
|
||||
static const char rcsid[] = "$Id$"; |
||||
|
||||
#include <stdlib.h> |
||||
#include "ares.h" |
||||
|
||||
void ares_free_string(char *str) |
||||
{ |
||||
free(str); |
||||
} |
@ -0,0 +1,100 @@ |
||||
.\" $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_GETHOSTBYADDR 3 "24 July 1998" |
||||
.SH NAME |
||||
ares_gethostbyaddr \- Initiate a host query by address |
||||
.SH SYNOPSIS |
||||
.nf |
||||
.B #include <ares.h> |
||||
.PP |
||||
.B typedef void (*ares_host_callback)(void *\fIarg\fP, int \fIstatus\fP, |
||||
.B struct hostent *\fIhostent\fP) |
||||
.PP |
||||
.B void ares_gethostbyaddr(ares_channel \fIchannel\fP, const void *\fIaddr\fP, |
||||
.B int \fIaddrlen\fP, int \fIfamily\fP, ares_host_callback \fIcallback\fP, |
||||
.B void *\fIarg\fP) |
||||
.fi |
||||
.SH DESCRIPTION |
||||
The |
||||
.B ares_gethostbyaddr |
||||
function initiates a host query by address on the name service channel |
||||
identified by |
||||
.IR channel . |
||||
The parameters |
||||
.I addr |
||||
and |
||||
.I addrlen |
||||
give the address as a series of bytes, and |
||||
.I family |
||||
gives the type of address. When the query is complete or has failed, |
||||
the ares library will invoke |
||||
.IR callback . |
||||
Completion or failure of the query may happen immediately, or may |
||||
happen during a later call to |
||||
.BR ares_process (3) |
||||
or |
||||
.BR ares_destroy (3). |
||||
.PP |
||||
The callback argument |
||||
.I arg |
||||
is copied from the |
||||
.B ares_gethostbyaddr |
||||
argument |
||||
.IR arg . |
||||
The callback argument |
||||
.I status |
||||
indicates whether the query succeeded and, if not, how it failed. It |
||||
may have any of the following values: |
||||
.TP 19 |
||||
.B ARES_SUCCESS |
||||
The host lookup completed successfully. |
||||
.TP 19 |
||||
.B ARES_ENOTIMP |
||||
The ares library does not know how to look up addresses of type |
||||
.IR family . |
||||
.TP 19 |
||||
.B ARES_ENOTFOUND |
||||
The address |
||||
.I addr |
||||
was not found. |
||||
.TP 19 |
||||
.B ARES_ENOMEM |
||||
Memory was exhausted. |
||||
.TP 19 |
||||
.B ARES_EDESTRUCTION |
||||
The name service channel |
||||
.I channel |
||||
is being destroyed; the query will not be completed. |
||||
.PP |
||||
On successful completion of the query, the callback argument |
||||
.I hostent |
||||
points to a |
||||
.B struct hostent |
||||
containing the name of the host returned by the query. The callback |
||||
need not and should not attempt to free the memory pointed to by |
||||
.IR hostent ; |
||||
the ares library will free it when the callback returns. If the query |
||||
did not complete successfully, |
||||
.I hostent |
||||
will be |
||||
.BR NULL . |
||||
.SH SEE ALSO |
||||
.BR ares_process (3) |
||||
.SH AUTHOR |
||||
Greg Hudson, MIT Information Systems |
||||
.br |
||||
Copyright 1998 by the Massachusetts Institute of Technology. |
@ -0,0 +1,174 @@ |
||||
/* 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/socket.h> |
||||
#include <netinet/in.h> |
||||
#include <netdb.h> |
||||
#include <arpa/nameser.h> |
||||
#endif |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include "ares.h" |
||||
#include "ares_private.h" |
||||
|
||||
struct addr_query { |
||||
/* Arguments passed to ares_gethostbyaddr() */ |
||||
ares_channel channel; |
||||
struct in_addr addr; |
||||
ares_host_callback callback; |
||||
void *arg; |
||||
|
||||
const char *remaining_lookups; |
||||
}; |
||||
|
||||
static void next_lookup(struct addr_query *aquery); |
||||
static void addr_callback(void *arg, int status, unsigned char *abuf, |
||||
int alen); |
||||
static void end_aquery(struct addr_query *aquery, int status, |
||||
struct hostent *host); |
||||
static int file_lookup(struct in_addr *addr, struct hostent **host); |
||||
|
||||
void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen, |
||||
int family, ares_host_callback callback, void *arg) |
||||
{ |
||||
struct addr_query *aquery; |
||||
|
||||
if (family != AF_INET || addrlen != sizeof(struct in_addr)) |
||||
{ |
||||
callback(arg, ARES_ENOTIMP, NULL); |
||||
return; |
||||
} |
||||
|
||||
aquery = malloc(sizeof(struct addr_query)); |
||||
if (!aquery) |
||||
{ |
||||
callback(arg, ARES_ENOMEM, NULL); |
||||
return; |
||||
} |
||||
aquery->channel = channel; |
||||
memcpy(&aquery->addr, addr, sizeof(aquery->addr)); |
||||
aquery->callback = callback; |
||||
aquery->arg = arg; |
||||
aquery->remaining_lookups = channel->lookups; |
||||
|
||||
next_lookup(aquery); |
||||
} |
||||
|
||||
static void next_lookup(struct addr_query *aquery) |
||||
{ |
||||
const char *p; |
||||
char name[64]; |
||||
int a1, a2, a3, a4, status; |
||||
struct hostent *host; |
||||
unsigned long addr; |
||||
|
||||
for (p = aquery->remaining_lookups; *p; p++) |
||||
{ |
||||
switch (*p) |
||||
{ |
||||
case 'b': |
||||
addr = ntohl(aquery->addr.s_addr); |
||||
a1 = addr >> 24; |
||||
a2 = (addr >> 16) & 0xff; |
||||
a3 = (addr >> 8) & 0xff; |
||||
a4 = addr & 0xff; |
||||
sprintf(name, "%d.%d.%d.%d.in-addr.arpa", a4, a3, a2, a1); |
||||
aquery->remaining_lookups = p + 1; |
||||
ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback, |
||||
aquery); |
||||
return; |
||||
case 'f': |
||||
status = file_lookup(&aquery->addr, &host); |
||||
if (status != ARES_ENOTFOUND) |
||||
{ |
||||
end_aquery(aquery, status, host); |
||||
return; |
||||
} |
||||
break; |
||||
} |
||||
} |
||||
end_aquery(aquery, ARES_ENOTFOUND, NULL); |
||||
} |
||||
|
||||
static void addr_callback(void *arg, int status, unsigned char *abuf, int alen) |
||||
{ |
||||
struct addr_query *aquery = (struct addr_query *) arg; |
||||
struct hostent *host; |
||||
|
||||
if (status == ARES_SUCCESS) |
||||
{ |
||||
status = ares_parse_ptr_reply(abuf, alen, &aquery->addr, |
||||
sizeof(struct in_addr), AF_INET, &host); |
||||
end_aquery(aquery, status, host); |
||||
} |
||||
else if (status == ARES_EDESTRUCTION) |
||||
end_aquery(aquery, status, NULL); |
||||
else |
||||
next_lookup(aquery); |
||||
} |
||||
|
||||
static void end_aquery(struct addr_query *aquery, int status, |
||||
struct hostent *host) |
||||
{ |
||||
aquery->callback(aquery->arg, status, host); |
||||
if (host) |
||||
ares_free_hostent(host); |
||||
free(aquery); |
||||
} |
||||
|
||||
static int file_lookup(struct in_addr *addr, struct hostent **host) |
||||
{ |
||||
FILE *fp; |
||||
int status; |
||||
|
||||
#ifdef WIN32 |
||||
|
||||
char PATH_HOSTS[MAX_PATH]; |
||||
if (IsNT) { |
||||
GetSystemDirectory(PATH_HOSTS, MAX_PATH); |
||||
strcat(PATH_HOSTS, PATH_HOSTS_NT); |
||||
} else { |
||||
GetWindowsDirectory(PATH_HOSTS, MAX_PATH); |
||||
strcat(PATH_HOSTS, PATH_HOSTS_9X); |
||||
} |
||||
|
||||
#endif |
||||
|
||||
fp = fopen(PATH_HOSTS, "r"); |
||||
if (!fp) |
||||
return ARES_ENOTFOUND; |
||||
|
||||
while ((status = ares__get_hostent(fp, host)) == ARES_SUCCESS) |
||||
{ |
||||
if (memcmp((*host)->h_addr, addr, sizeof(struct in_addr)) == 0) |
||||
break; |
||||
ares_free_hostent(*host); |
||||
} |
||||
fclose(fp); |
||||
if (status == ARES_EOF) |
||||
status = ARES_ENOTFOUND; |
||||
if (status != ARES_SUCCESS) |
||||
*host = NULL; |
||||
return status; |
||||
} |
@ -0,0 +1,103 @@ |
||||
.\" $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_GETHOSTBYNAME 3 "25 July 1998" |
||||
.SH NAME |
||||
ares_gethostbyname \- Initiate a host query by name |
||||
.SH SYNOPSIS |
||||
.nf |
||||
.B #include <ares.h> |
||||
.PP |
||||
.B typedef void (*ares_host_callback)(void *\fIarg\fP, int \fIstatus\fP, |
||||
.B struct hostent *\fIhostent\fP) |
||||
.PP |
||||
.B void ares_gethostbyname(ares_channel \fIchannel\fP, const char *\fIname\fP, |
||||
.B int \fIfamily\fP, ares_host_callback \fIcallback\fP, void *\fIarg\fP) |
||||
.fi |
||||
.SH DESCRIPTION |
||||
The |
||||
.B ares_gethostbyname |
||||
function initiates a host query by name on the name service channel |
||||
identified by |
||||
.IR channel . |
||||
The parameter |
||||
.I name |
||||
gives the hostname as a NUL-terminated C string, and |
||||
.I family |
||||
gives the desired type of address for the resulting host entry. When |
||||
the query is complete or has failed, the ares library will invoke |
||||
.IR callback . |
||||
Completion or failure of the query may happen immediately, or may |
||||
happen during a later call to |
||||
.BR ares_process (3) |
||||
or |
||||
.BR ares_destroy (3). |
||||
.PP |
||||
The callback argument |
||||
.I arg |
||||
is copied from the |
||||
.B ares_gethostbyname |
||||
argument |
||||
.IR arg . |
||||
The callback argument |
||||
.I status |
||||
indicates whether the query succeeded and, if not, how it failed. It |
||||
may have any of the following values: |
||||
.TP 19 |
||||
.B ARES_SUCCESS |
||||
The host lookup completed successfully. |
||||
.TP 19 |
||||
.B ARES_ENOTIMP |
||||
The ares library does not know how to find addresses of type |
||||
.IR family . |
||||
.TP 19 |
||||
.B ARES_EBADNAME |
||||
The hostname |
||||
.B name |
||||
is composed entirely of numbers and periods, but is not a valid |
||||
representation of an Internet address. |
||||
.TP 19 |
||||
.B ARES_ENOTFOUND |
||||
The address |
||||
.I addr |
||||
was not found. |
||||
.TP 19 |
||||
.B ARES_ENOMEM |
||||
Memory was exhausted. |
||||
.TP 19 |
||||
.B ARES_EDESTRUCTION |
||||
The name service channel |
||||
.I channel |
||||
is being destroyed; the query will not be completed. |
||||
.PP |
||||
On successful completion of the query, the callback argument |
||||
.I hostent |
||||
points to a |
||||
.B struct hostent |
||||
containing the name of the host returned by the query. The callback |
||||
need not and should not attempt to free the memory pointed to by |
||||
.IR hostent ; |
||||
the ares library will free it when the callback returns. If the query |
||||
did not complete successfully, |
||||
.I hostent |
||||
will be |
||||
.BR NULL . |
||||
.SH SEE ALSO |
||||
.BR ares_process (3) |
||||
.SH AUTHOR |
||||
Greg Hudson, MIT Information Systems |
||||
.br |
||||
Copyright 1998 by the Massachusetts Institute of Technology. |
@ -0,0 +1,297 @@ |
||||
/* 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/socket.h> |
||||
#include <netinet/in.h> |
||||
#include <arpa/inet.h> |
||||
#include <netdb.h> |
||||
#include <arpa/nameser.h> |
||||
#endif |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include <ctype.h> |
||||
#include "ares.h" |
||||
#include "ares_private.h" |
||||
|
||||
struct host_query { |
||||
/* Arguments passed to ares_gethostbyname() */ |
||||
ares_channel channel; |
||||
char *name; |
||||
ares_host_callback callback; |
||||
void *arg; |
||||
|
||||
const char *remaining_lookups; |
||||
}; |
||||
|
||||
static void next_lookup(struct host_query *hquery); |
||||
static void host_callback(void *arg, int status, unsigned char *abuf, |
||||
int alen); |
||||
static void end_hquery(struct host_query *hquery, int status, |
||||
struct hostent *host); |
||||
static int fake_hostent(const char *name, ares_host_callback callback, |
||||
void *arg); |
||||
static int file_lookup(const char *name, struct hostent **host); |
||||
static void sort_addresses(struct hostent *host, struct apattern *sortlist, |
||||
int nsort); |
||||
static int get_address_index(struct in_addr *addr, struct apattern *sortlist, |
||||
int nsort); |
||||
|
||||
void ares_gethostbyname(ares_channel channel, const char *name, int family, |
||||
ares_host_callback callback, void *arg) |
||||
{ |
||||
struct host_query *hquery; |
||||
|
||||
/* Right now we only know how to look up Internet addresses. */ |
||||
if (family != AF_INET) |
||||
{ |
||||
callback(arg, ARES_ENOTIMP, NULL); |
||||
return; |
||||
} |
||||
|
||||
if (fake_hostent(name, callback, arg)) |
||||
return; |
||||
|
||||
/* Allocate and fill in the host query structure. */ |
||||
hquery = malloc(sizeof(struct host_query)); |
||||
if (!hquery) |
||||
{ |
||||
callback(arg, ARES_ENOMEM, NULL); |
||||
return; |
||||
} |
||||
hquery->channel = channel; |
||||
hquery->name = strdup(name); |
||||
if (!hquery->name) |
||||
{ |
||||
free(hquery); |
||||
callback(arg, ARES_ENOMEM, NULL); |
||||
return; |
||||
} |
||||
hquery->callback = callback; |
||||
hquery->arg = arg; |
||||
hquery->remaining_lookups = channel->lookups; |
||||
|
||||
/* Start performing lookups according to channel->lookups. */ |
||||
next_lookup(hquery); |
||||
} |
||||
|
||||
static void next_lookup(struct host_query *hquery) |
||||
{ |
||||
int status; |
||||
const char *p; |
||||
struct hostent *host; |
||||
|
||||
for (p = hquery->remaining_lookups; *p; p++) |
||||
{
|
||||
switch (*p) |
||||
{ |
||||
case 'b': |
||||
/* DNS lookup */ |
||||
hquery->remaining_lookups = p + 1; |
||||
ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, |
||||
hquery); |
||||
return; |
||||
|
||||
case 'f': |
||||
/* Host file lookup */ |
||||
status = file_lookup(hquery->name, &host); |
||||
if (status != ARES_ENOTFOUND) |
||||
{ |
||||
end_hquery(hquery, status, host); |
||||
return; |
||||
} |
||||
break; |
||||
} |
||||
} |
||||
end_hquery(hquery, ARES_ENOTFOUND, NULL); |
||||
} |
||||
|
||||
static void host_callback(void *arg, int status, unsigned char *abuf, int alen) |
||||
{ |
||||
struct host_query *hquery = (struct host_query *) arg; |
||||
ares_channel channel = hquery->channel; |
||||
struct hostent *host; |
||||
|
||||
if (status == ARES_SUCCESS) |
||||
{ |
||||
status = ares_parse_a_reply(abuf, alen, &host); |
||||
if (host && channel->nsort) |
||||
sort_addresses(host, channel->sortlist, channel->nsort); |
||||
end_hquery(hquery, status, host); |
||||
} |
||||
else if (status == ARES_EDESTRUCTION) |
||||
end_hquery(hquery, status, NULL); |
||||
else |
||||
next_lookup(hquery); |
||||
} |
||||
|
||||
static void end_hquery(struct host_query *hquery, int status, |
||||
struct hostent *host) |
||||
{ |
||||
hquery->callback(hquery->arg, status, host); |
||||
if (host) |
||||
ares_free_hostent(host); |
||||
free(hquery->name); |
||||
free(hquery); |
||||
} |
||||
|
||||
/* If the name looks like an IP address, fake up a host entry, end the
|
||||
* query immediately, and return true. Otherwise return false. |
||||
*/ |
||||
static int fake_hostent(const char *name, ares_host_callback callback, |
||||
void *arg) |
||||
{ |
||||
struct in_addr addr; |
||||
struct hostent hostent; |
||||
const char *p; |
||||
char *aliases[1] = { NULL }; |
||||
char *addrs[2]; |
||||
|
||||
/* It only looks like an IP address if it's all numbers and dots. */ |
||||
for (p = name; *p; p++) |
||||
{ |
||||
if (!isdigit((unsigned char)*p) && *p != '.') |
||||
return 0; |
||||
} |
||||
|
||||
/* It also only looks like an IP address if it's non-zero-length and
|
||||
* doesn't end with a dot. |
||||
*/ |
||||
if (p == name || *(p - 1) == '.') |
||||
return 0; |
||||
|
||||
/* It looks like an IP address. Figure out what IP address it is. */ |
||||
addr.s_addr = inet_addr(name); |
||||
if (addr.s_addr == INADDR_NONE) |
||||
{ |
||||
callback(arg, ARES_EBADNAME, NULL); |
||||
return 1; |
||||
} |
||||
|
||||
/* Duplicate the name, to avoid a constness violation. */ |
||||
hostent.h_name = strdup(name); |
||||
if (!hostent.h_name) |
||||
{ |
||||
callback(arg, ARES_ENOMEM, NULL); |
||||
return 1; |
||||
} |
||||
|
||||
/* Fill in the rest of the host structure and terminate the query. */ |
||||
addrs[0] = (char *) &addr; |
||||
addrs[1] = NULL; |
||||
hostent.h_aliases = aliases; |
||||
hostent.h_addrtype = AF_INET; |
||||
hostent.h_length = sizeof(struct in_addr); |
||||
hostent.h_addr_list = addrs; |
||||
callback(arg, ARES_SUCCESS, &hostent); |
||||
|
||||
free(hostent.h_name); |
||||
return 1; |
||||
} |
||||
|
||||
static int file_lookup(const char *name, struct hostent **host) |
||||
{ |
||||
FILE *fp; |
||||
char **alias; |
||||
int status; |
||||
|
||||
#ifdef WIN32 |
||||
|
||||
char PATH_HOSTS[MAX_PATH]; |
||||
if (IsNT) { |
||||
GetSystemDirectory(PATH_HOSTS, MAX_PATH); |
||||
strcat(PATH_HOSTS, PATH_HOSTS_NT); |
||||
} else { |
||||
GetWindowsDirectory(PATH_HOSTS, MAX_PATH); |
||||
strcat(PATH_HOSTS, PATH_HOSTS_9X); |
||||
} |
||||
|
||||
#endif |
||||
|
||||
fp = fopen(PATH_HOSTS, "r"); |
||||
if (!fp) |
||||
return ARES_ENOTFOUND; |
||||
|
||||
while ((status = ares__get_hostent(fp, host)) == ARES_SUCCESS) |
||||
{ |
||||
if (strcasecmp((*host)->h_name, name) == 0) |
||||
break; |
||||
for (alias = (*host)->h_aliases; *alias; alias++) |
||||
{ |
||||
if (strcasecmp(*alias, name) == 0) |
||||
break; |
||||
} |
||||
if (*alias) |
||||
break; |
||||
ares_free_hostent(*host); |
||||
} |
||||
fclose(fp); |
||||
if (status == ARES_EOF) |
||||
status = ARES_ENOTFOUND; |
||||
if (status != ARES_SUCCESS) |
||||
*host = NULL; |
||||
return status; |
||||
} |
||||
|
||||
static void sort_addresses(struct hostent *host, struct apattern *sortlist, |
||||
int nsort) |
||||
{ |
||||
struct in_addr a1, a2; |
||||
int i1, i2, ind1, ind2; |
||||
|
||||
/* This is a simple insertion sort, not optimized at all. i1 walks
|
||||
* through the address list, with the loop invariant that everything |
||||
* to the left of i1 is sorted. In the loop body, the value at i1 is moved |
||||
* back through the list (via i2) until it is in sorted order. |
||||
*/ |
||||
for (i1 = 0; host->h_addr_list[i1]; i1++) |
||||
{ |
||||
memcpy(&a1, host->h_addr_list[i1], sizeof(struct in_addr)); |
||||
ind1 = get_address_index(&a1, sortlist, nsort); |
||||
for (i2 = i1 - 1; i2 >= 0; i2--) |
||||
{ |
||||
memcpy(&a2, host->h_addr_list[i2], sizeof(struct in_addr)); |
||||
ind2 = get_address_index(&a2, sortlist, nsort); |
||||
if (ind2 <= ind1) |
||||
break; |
||||
memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct in_addr)); |
||||
} |
||||
memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct in_addr)); |
||||
} |
||||
} |
||||
|
||||
/* Find the first entry in sortlist which matches addr. Return nsort
|
||||
* if none of them match. |
||||
*/ |
||||
static int get_address_index(struct in_addr *addr, struct apattern *sortlist, |
||||
int nsort) |
||||
{ |
||||
int i; |
||||
|
||||
for (i = 0; i < nsort; i++) |
||||
{ |
||||
if ((addr->s_addr & sortlist[i].mask.s_addr) == sortlist[i].addr.s_addr) |
||||
break; |
||||
} |
||||
return i; |
||||
} |
@ -0,0 +1,170 @@ |
||||
.\" $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_INIT 3 "21 July 1998" |
||||
.SH NAME |
||||
ares_init, ares_init_options \- Initialize a resolver channel |
||||
.SH SYNOPSIS |
||||
.nf |
||||
.B #include <ares.h> |
||||
.PP |
||||
.B int ares_init(ares_channel *\fIchannel\fP) |
||||
.B int ares_init_options(ares_channel *\fIchannel\fP, |
||||
.B struct ares_options *\fIoptions\fP, int \fIoptmask\fP) |
||||
.PP |
||||
.B cc file.c -lares |
||||
.fi |
||||
.SH DESCRIPTION |
||||
The |
||||
.B ares_init |
||||
function initializes a communications channel for name service |
||||
lookups. If it returns successfully, |
||||
.B ares_init |
||||
will set the variable pointed to by |
||||
.I channel |
||||
to a handle used to identify the name service channel. The caller |
||||
should invoke |
||||
.BR ares_destroy (3) |
||||
on the handle when the channel is no longer needed. |
||||
.PP |
||||
The |
||||
.B ares_init_options |
||||
function also initializes a name service channel, with additional |
||||
options useful for applications requiring more control over name |
||||
service configuration. The |
||||
.I optmask |
||||
parameter specifies which fields in the structure pointed to by |
||||
.I options |
||||
are set, as follows: |
||||
.PP |
||||
.TP 18 |
||||
.B ARES_OPT_FLAGS |
||||
.B int \fIflags\fP; |
||||
.br |
||||
Flags controlling the behavior of the resolver. See below for a |
||||
description of possible flag values. |
||||
.TP 18 |
||||
.B ARES_OPT_TIMEOUT |
||||
.B int \fItimeout\fP; |
||||
.br |
||||
The number of seconds each name server is given to respond to a query |
||||
on the first try. (After the first try, the timeout algorithm becomes |
||||
more complicated, but scales linearly with the value of |
||||
\fItimeout\fP.) The default is five seconds. |
||||
.TP 18 |
||||
.B ARES_OPT_TRIES |
||||
.B int \fItries\fP; |
||||
.br |
||||
The number of tries the resolver will try contacting each name server |
||||
before giving up. The default is four tries. |
||||
.TP 18 |
||||
.B ARES_OPT_NDOTS |
||||
.B int \fIndots\fP; |
||||
.br |
||||
The number of dots which must be present in a domain name for it to be |
||||
queried for "as is" prior to querying for it with the default domain |
||||
extensions appended. The default value is 1 unless set otherwise by |
||||
resolv.conf or the RES_OPTIONS environment variable. |
||||
.TP 18 |
||||
.B ARES_OPT_PORT |
||||
.B unsigned short \fIport\fP; |
||||
.br |
||||
The port to use for queries (both TCP and UDP), in network byte order. |
||||
The default value is 53 (in network byte order), the standard name |
||||
service port. |
||||
.TP 18 |
||||
.B ARES_OPT_SERVERS |
||||
.B struct in_addr *\fIservers\fP; |
||||
.br |
||||
.B int \fInservers\fP; |
||||
.br |
||||
The list of servers to contact, instead of the servers specified in |
||||
resolv.conf or the local named. |
||||
.TP 18 |
||||
.B ARES_OPT_DOMAINS |
||||
.B char **\fIdomains\fP; |
||||
.br |
||||
.B int \fIndomains\fP; |
||||
.br |
||||
The domains to search, instead of the domains specified in resolv.conf |
||||
or the domain derived from the kernel hostname variable. |
||||
.TP 18 |
||||
.B ARES_OPT_LOOKUPS |
||||
.B char *\fIlookups\fP; |
||||
.br |
||||
The lookups to perform for host queries. |
||||
.I lookups |
||||
should be set to a string of the characters "b" or "f", where "b" |
||||
indicates a DNS lookup and "f" indicates a lookup in the hosts file. |
||||
.PP |
||||
The |
||||
.I flags |
||||
field should be the bitwise or of some subset of the following values: |
||||
.TP 23 |
||||
.B ARES_FLAG_USEVC |
||||
Always use TCP queries (the "virtual circuit") instead of UDP |
||||
queries. Normally, TCP is only used if a UDP query yields a truncated |
||||
result. |
||||
.TP 23 |
||||
.B ARES_FLAG_PRIMARY |
||||
Only query the first server in the list of servers to query. |
||||
.TP 23 |
||||
.B ARES_FLAG_IGNTC |
||||
If a truncated response to a UDP query is received, do not fall back |
||||
to TCP; simply continue on with the truncated response. |
||||
.TP 23 |
||||
.B ARES_FLAG_NORECURSE |
||||
Do not set the "recursion desired" bit on outgoing queries, so that |
||||
the name server being contacted will not try to fetch the answer from |
||||
other servers if it doesn't know the answer locally. |
||||
.TP 23 |
||||
.B ARES_FLAG_STAYOPEN |
||||
Do not close communciations sockets when the number of active queries |
||||
drops to zero. |
||||
.TP 23 |
||||
.B ARES_FLAG_NOSEARCH |
||||
Do not use the default search domains; only query hostnames as-is or |
||||
as aliases. |
||||
.TP 23 |
||||
.B ARES_FLAG_NOALIASES |
||||
Do not honor the HOSTALIASES environment variable, which normally |
||||
specifies a file of hostname translations. |
||||
.TP 23 |
||||
.B ARES_FLAG_NOCHECKRESP |
||||
Do not discard responses with the SERVFAIL, NOTIMP, or REFUSED |
||||
response code or responses whose questions don't match the questions |
||||
in the request. Primarily useful for writing clients which might be |
||||
used to test or debug name servers. |
||||
.SH RETURN VALUES |
||||
.I ares_init |
||||
or |
||||
.I ares_init_options |
||||
can return any of the following values: |
||||
.TP 14 |
||||
.B ARES_SUCCESS |
||||
Initialization succeeded. |
||||
.TP 14 |
||||
.B ARES_EFILE |
||||
A configuration file could not be read. |
||||
.TP 14 |
||||
.B ARES_ENOMEM |
||||
The process's available memory was exhausted. |
||||
.SH SEE ALSO |
||||
.BR ares_destroy (3) |
||||
.SH AUTHOR |
||||
Greg Hudson, MIT Information Systems |
||||
.br |
||||
Copyright 1998 by the Massachusetts Institute of Technology. |
@ -0,0 +1,776 @@ |
||||
/* 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/param.h> |
||||
#include <sys/time.h> |
||||
#include <netinet/in.h> |
||||
#include <arpa/inet.h> |
||||
#include <netdb.h> |
||||
#include <arpa/nameser.h> |
||||
#include <unistd.h> |
||||
#endif |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include <ctype.h> |
||||
#include <time.h> |
||||
#include <errno.h> |
||||
#include "ares.h" |
||||
#include "ares_private.h" |
||||
|
||||
static int init_by_options(ares_channel channel, struct ares_options *options, |
||||
int optmask); |
||||
static int init_by_environment(ares_channel channel); |
||||
static int init_by_resolv_conf(ares_channel channel); |
||||
static int init_by_defaults(ares_channel channel); |
||||
static int config_domain(ares_channel channel, char *str); |
||||
static int config_lookup(ares_channel channel, const char *str); |
||||
static int config_nameserver(struct server_state **servers, int *nservers, |
||||
const char *str); |
||||
static int config_sortlist(struct apattern **sortlist, int *nsort, |
||||
const char *str); |
||||
static int set_search(ares_channel channel, const char *str); |
||||
static int set_options(ares_channel channel, const char *str); |
||||
static char *try_config(char *s, char *opt); |
||||
static const char *try_option(const char *p, const char *q, const char *opt); |
||||
static int ip_addr(const char *s, int len, struct in_addr *addr); |
||||
static void natural_mask(struct apattern *pat); |
||||
|
||||
int ares_init(ares_channel *channelptr) |
||||
{ |
||||
return ares_init_options(channelptr, NULL, 0); |
||||
} |
||||
|
||||
int ares_init_options(ares_channel *channelptr, struct ares_options *options, |
||||
int optmask) |
||||
{ |
||||
ares_channel channel; |
||||
int i, status; |
||||
struct server_state *server; |
||||
struct timeval tv; |
||||
|
||||
channel = malloc(sizeof(struct ares_channeldata)); |
||||
if (!channel) |
||||
return ARES_ENOMEM; |
||||
|
||||
/* Set everything to distinguished values so we know they haven't
|
||||
* been set yet. |
||||
*/ |
||||
channel->flags = -1; |
||||
channel->timeout = -1; |
||||
channel->tries = -1; |
||||
channel->ndots = -1; |
||||
channel->udp_port = -1; |
||||
channel->tcp_port = -1; |
||||
channel->nservers = -1; |
||||
channel->ndomains = -1; |
||||
channel->nsort = -1; |
||||
channel->lookups = NULL; |
||||
channel->queries = NULL; |
||||
|
||||
/* Initialize configuration by each of the four sources, from highest
|
||||
* precedence to lowest. |
||||
*/ |
||||
status = init_by_options(channel, options, optmask); |
||||
if (status == ARES_SUCCESS) |
||||
status = init_by_environment(channel); |
||||
if (status == ARES_SUCCESS) |
||||
status = init_by_resolv_conf(channel); |
||||
if (status == ARES_SUCCESS) |
||||
status = init_by_defaults(channel); |
||||
if (status != ARES_SUCCESS) |
||||
{ |
||||
/* Something failed; clean up memory we may have allocated. */ |
||||
if (channel->nservers != -1) |
||||
free(channel->servers); |
||||
if (channel->ndomains != -1) |
||||
{ |
||||
for (i = 0; i < channel->ndomains; i++) |
||||
free(channel->domains[i]); |
||||
free(channel->domains); |
||||
} |
||||
if (channel->nsort != -1) |
||||
free(channel->sortlist); |
||||
free(channel->lookups); |
||||
free(channel); |
||||
return status; |
||||
} |
||||
|
||||
/* Trim to one server if ARES_FLAG_PRIMARY is set. */ |
||||
if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1) |
||||
channel->nservers = 1; |
||||
|
||||
/* Initialize server states. */ |
||||
for (i = 0; i < channel->nservers; i++) |
||||
{ |
||||
server = &channel->servers[i]; |
||||
server->udp_socket = -1; |
||||
server->tcp_socket = -1; |
||||
server->tcp_lenbuf_pos = 0; |
||||
server->tcp_buffer = NULL; |
||||
server->qhead = NULL; |
||||
server->qtail = NULL; |
||||
} |
||||
|
||||
/* Choose a somewhat random query ID. The main point is to avoid
|
||||
* collisions with stale queries. An attacker trying to spoof a DNS |
||||
* answer also has to guess the query ID, but it's only a 16-bit |
||||
* field, so there's not much to be done about that. |
||||
*/ |
||||
gettimeofday(&tv, NULL); |
||||
channel->next_id = (tv.tv_sec ^ tv.tv_usec ^ getpid()) & 0xffff; |
||||
|
||||
channel->queries = NULL; |
||||
|
||||
*channelptr = channel; |
||||
return ARES_SUCCESS; |
||||
} |
||||
|
||||
static int init_by_options(ares_channel channel, struct ares_options *options, |
||||
int optmask) |
||||
{ |
||||
int i; |
||||
|
||||
/* Easy stuff. */ |
||||
if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1) |
||||
channel->flags = options->flags; |
||||
if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1) |
||||
channel->timeout = options->timeout; |
||||
if ((optmask & ARES_OPT_TRIES) && channel->tries == -1) |
||||
channel->tries = options->tries; |
||||
if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1) |
||||
channel->ndots = options->ndots; |
||||
if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1) |
||||
channel->udp_port = options->udp_port; |
||||
if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1) |
||||
channel->tcp_port = options->tcp_port; |
||||
|
||||
/* Copy the servers, if given. */ |
||||
if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1) |
||||
{ |
||||
channel->servers = |
||||
malloc(options->nservers * sizeof(struct server_state)); |
||||
if (!channel->servers && options->nservers != 0) |
||||
return ARES_ENOMEM; |
||||
for (i = 0; i < options->nservers; i++) |
||||
channel->servers[i].addr = options->servers[i]; |
||||
channel->nservers = options->nservers; |
||||
} |
||||
|
||||
/* Copy the domains, if given. Keep channel->ndomains consistent so
|
||||
* we can clean up in case of error. |
||||
*/ |
||||
if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1) |
||||
{ |
||||
channel->domains = malloc(options->ndomains * sizeof(char *)); |
||||
if (!channel->domains && options->ndomains != 0) |
||||
return ARES_ENOMEM; |
||||
for (i = 0; i < options->ndomains; i++) |
||||
{ |
||||
channel->ndomains = i; |
||||
channel->domains[i] = strdup(options->domains[i]); |
||||
if (!channel->domains[i]) |
||||
return ARES_ENOMEM; |
||||
} |
||||
channel->ndomains = options->ndomains; |
||||
} |
||||
|
||||
/* Set lookups, if given. */ |
||||
if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups) |
||||
{ |
||||
channel->lookups = strdup(options->lookups); |
||||
if (!channel->lookups) |
||||
return ARES_ENOMEM; |
||||
} |
||||
|
||||
return ARES_SUCCESS; |
||||
} |
||||
|
||||
static int init_by_environment(ares_channel channel) |
||||
{ |
||||
const char *localdomain, *res_options; |
||||
int status; |
||||
|
||||
localdomain = getenv("LOCALDOMAIN"); |
||||
if (localdomain && channel->ndomains == -1) |
||||
{ |
||||
status = set_search(channel, localdomain); |
||||
if (status != ARES_SUCCESS) |
||||
return status; |
||||
} |
||||
|
||||
res_options = getenv("RES_OPTIONS"); |
||||
if (res_options) |
||||
{ |
||||
status = set_options(channel, res_options); |
||||
if (status != ARES_SUCCESS) |
||||
return status; |
||||
} |
||||
|
||||
return ARES_SUCCESS; |
||||
} |
||||
#ifdef WIN32 |
||||
static int get_res_size_nt(HKEY hKey, char *subkey, int *size) |
||||
{ |
||||
return RegQueryValueEx(hKey, subkey, 0, NULL, NULL, size); |
||||
} |
||||
|
||||
/* Warning: returns a dynamically allocated buffer, the user MUST
|
||||
* use free() if the function returns 1 |
||||
*/ |
||||
static int get_res_nt(HKEY hKey, char *subkey, char **obuf) |
||||
{ |
||||
/* Test for the size we need */ |
||||
int size = 0; |
||||
int result; |
||||
result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size); |
||||
if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size) |
||||
return 0; |
||||
*obuf = malloc(size+1); |
||||
|
||||
if (RegQueryValueEx(hKey, subkey, 0, NULL, *obuf, &size) != ERROR_SUCCESS) |
||||
{ |
||||
free(*obuf); |
||||
return 0; |
||||
} |
||||
if (size == 1) |
||||
{ |
||||
free(*obuf); |
||||
return 0; |
||||
} |
||||
return 1; |
||||
} |
||||
|
||||
static int get_res_interfaces_nt(HKEY hKey, char *subkey, char **obuf) |
||||
{ |
||||
char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */ |
||||
int enum_size = 39; |
||||
int idx = 0; |
||||
HKEY hVal; |
||||
while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0, NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS) |
||||
{ |
||||
enum_size = 39; |
||||
if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) != ERROR_SUCCESS) |
||||
continue; |
||||
if (!get_res_nt(hVal, subkey, obuf)) |
||||
RegCloseKey(hVal); |
||||
else |
||||
{ |
||||
RegCloseKey(hVal); |
||||
return 1; |
||||
} |
||||
} |
||||
return 0; |
||||
} |
||||
#endif |
||||
|
||||
static int init_by_resolv_conf(ares_channel channel) |
||||
{ |
||||
FILE *fp; |
||||
char *line = NULL, *p; |
||||
int linesize, status, nservers = 0, nsort = 0; |
||||
struct server_state *servers = NULL; |
||||
struct apattern *sortlist = NULL; |
||||
|
||||
#ifdef WIN32 |
||||
|
||||
/*
|
||||
NameServer Registry: |
||||
|
||||
On Windows 9X, the DNS server can be found in: |
||||
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer |
||||
|
||||
On Windows NT/2000/XP/2003: |
||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer |
||||
or |
||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer |
||||
or |
||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
|
||||
NameServer |
||||
or |
||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
|
||||
DhcpNameServer |
||||
*/ |
||||
|
||||
HKEY mykey; |
||||
HKEY subkey; |
||||
DWORD data_type; |
||||
DWORD bytes; |
||||
DWORD result; |
||||
DWORD index; |
||||
char name[MAX_PATH]; |
||||
DWORD keysize = MAX_PATH; |
||||
|
||||
status = ARES_EFILE; |
||||
|
||||
if (IsNT)
|
||||
{ |
||||
if (RegOpenKeyEx( |
||||
HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, |
||||
KEY_READ, &mykey |
||||
) == ERROR_SUCCESS) |
||||
{ |
||||
RegOpenKeyEx(mykey, "Interfaces", 0, KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey); |
||||
if (get_res_nt(mykey, NAMESERVER, &line)) |
||||
{ |
||||
status = config_nameserver(&servers, &nservers, line); |
||||
free(line); |
||||
} |
||||
else if (get_res_nt(mykey, DHCPNAMESERVER, &line)) |
||||
{ |
||||
status = config_nameserver(&servers, &nservers, line); |
||||
free(line); |
||||
} |
||||
/* Try the interfaces */ |
||||
else if (get_res_interfaces_nt(subkey, NAMESERVER, &line)) |
||||
{ |
||||
status = config_nameserver(&servers, &nservers, line); |
||||
free(line); |
||||
} |
||||
else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line)) |
||||
{ |
||||
status = config_nameserver(&servers, &nservers, line); |
||||
free(line); |
||||
} |
||||
RegCloseKey(subkey); |
||||
RegCloseKey(mykey); |
||||
} |
||||
} else { |
||||
if (RegOpenKeyEx( |
||||
HKEY_LOCAL_MACHINE, WIN_NS_9X, 0, |
||||
KEY_READ, &mykey |
||||
) == ERROR_SUCCESS) |
||||
{ |
||||
if ((result = RegQueryValueEx( |
||||
mykey, NAMESERVER, NULL, &data_type, |
||||
NULL, &bytes |
||||
)
|
||||
) == ERROR_SUCCESS || |
||||
result == ERROR_MORE_DATA) |
||||
{ |
||||
if (bytes) { |
||||
line = (char *)malloc(bytes+1); |
||||
if (RegQueryValueEx( |
||||
mykey, NAMESERVER, NULL, &data_type, |
||||
(unsigned char *)line, &bytes |
||||
) == ERROR_SUCCESS) { |
||||
status = config_nameserver(&servers, &nservers, line); |
||||
} |
||||
free(line); |
||||
} |
||||
} |
||||
}
|
||||
RegCloseKey(mykey); |
||||
} |
||||
|
||||
if (status != ARES_EFILE) { |
||||
/*
|
||||
if (!channel->lookups) { |
||||
status = config_lookup(channel, "file bind"); |
||||
} |
||||
*/ |
||||
status = ARES_EOF; |
||||
} |
||||
|
||||
#elif defined(riscos) |
||||
|
||||
/* Under RISC OS, name servers are listed in the
|
||||
system variable Inet$Resolvers, space separated. */ |
||||
|
||||
line = getenv("Inet$Resolvers"); |
||||
status = ARES_EFILE; |
||||
if (line) { |
||||
char *resolvers = strdup(line), *pos, *space; |
||||
|
||||
if (!resolvers) |
||||
return ARES_ENOMEM; |
||||
|
||||
pos = resolvers; |
||||
do { |
||||
space = strchr(pos, ' '); |
||||
if (space) |
||||
*space = 0; |
||||
status = config_nameserver(&servers, &nservers, pos); |
||||
if (status != ARES_SUCCESS) |
||||
break; |
||||
pos = space + 1; |
||||
} while (space); |
||||
|
||||
if (status == ARES_SUCCESS) |
||||
status = ARES_EOF; |
||||
|
||||
free(resolvers); |
||||
} |
||||
|
||||
#else |
||||
|
||||
fp = fopen(PATH_RESOLV_CONF, "r"); |
||||
if (!fp) |
||||
return (errno == ENOENT) ? ARES_SUCCESS : ARES_EFILE; |
||||
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) |
||||
{ |
||||
if ((p = try_config(line, "domain")) && channel->ndomains == -1) |
||||
status = config_domain(channel, p); |
||||
else if ((p = try_config(line, "lookup")) && !channel->lookups) |
||||
status = config_lookup(channel, p); |
||||
else if ((p = try_config(line, "search")) && channel->ndomains == -1) |
||||
status = set_search(channel, p); |
||||
else if ((p = try_config(line, "nameserver")) && channel->nservers == -1) |
||||
status = config_nameserver(&servers, &nservers, p); |
||||
else if ((p = try_config(line, "sortlist")) && channel->nsort == -1) |
||||
status = config_sortlist(&sortlist, &nsort, p); |
||||
else if ((p = try_config(line, "options"))) |
||||
status = set_options(channel, p); |
||||
else |
||||
status = ARES_SUCCESS; |
||||
if (status != ARES_SUCCESS) |
||||
break; |
||||
} |
||||
free(line); |
||||
fclose(fp); |
||||
|
||||
#endif |
||||
|
||||
/* Handle errors. */ |
||||
if (status != ARES_EOF) |
||||
{ |
||||
if (servers != NULL) free(servers); |
||||
if (sortlist != NULL) free(sortlist); |
||||
return status; |
||||
} |
||||
|
||||
/* If we got any name server entries, fill them in. */ |
||||
if (servers) |
||||
{ |
||||
channel->servers = servers; |
||||
channel->nservers = nservers; |
||||
} |
||||
|
||||
/* If we got any sortlist entries, fill them in. */ |
||||
if (sortlist) |
||||
{ |
||||
channel->sortlist = sortlist; |
||||
channel->nsort = nsort; |
||||
} |
||||
|
||||
return ARES_SUCCESS; |
||||
} |
||||
|
||||
static int init_by_defaults(ares_channel channel) |
||||
{ |
||||
char hostname[MAXHOSTNAMELEN + 1]; |
||||
|
||||
if (channel->flags == -1) |
||||
channel->flags = 0; |
||||
if (channel->timeout == -1) |
||||
channel->timeout = DEFAULT_TIMEOUT; |
||||
if (channel->tries == -1) |
||||
channel->tries = DEFAULT_TRIES; |
||||
if (channel->ndots == -1) |
||||
channel->ndots = 1; |
||||
if (channel->udp_port == -1) |
||||
channel->udp_port = htons(NAMESERVER_PORT); |
||||
if (channel->tcp_port == -1) |
||||
channel->tcp_port = htons(NAMESERVER_PORT); |
||||
|
||||
if (channel->nservers == -1) |
||||
{ |
||||
/* If nobody specified servers, try a local named. */ |
||||
channel->servers = malloc(sizeof(struct server_state)); |
||||
if (!channel->servers) |
||||
return ARES_ENOMEM; |
||||
channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK); |
||||
channel->nservers = 1; |
||||
} |
||||
|
||||
if (channel->ndomains == -1) |
||||
{ |
||||
/* Derive a default domain search list from the kernel hostname,
|
||||
* or set it to empty if the hostname isn't helpful. |
||||
*/ |
||||
if (gethostname(hostname, sizeof(hostname)) == -1 |
||||
|| !strchr(hostname, '.')) |
||||
{ |
||||
channel->domains = malloc(0); |
||||
channel->ndomains = 0; |
||||
} |
||||
else |
||||
{ |
||||
channel->domains = malloc(sizeof(char *)); |
||||
if (!channel->domains) |
||||
return ARES_ENOMEM; |
||||
channel->ndomains = 0; |
||||
channel->domains[0] = strdup(strchr(hostname, '.') + 1); |
||||
if (!channel->domains[0]) |
||||
return ARES_ENOMEM; |
||||
channel->ndomains = 1; |
||||
} |
||||
} |
||||
|
||||
if (channel->nsort == -1) |
||||
{ |
||||
channel->sortlist = NULL; |
||||
channel->nsort = 0; |
||||
} |
||||
|
||||
if (!channel->lookups) |
||||
{ |
||||
channel->lookups = strdup("bf"); |
||||
if (!channel->lookups) |
||||
return ARES_ENOMEM; |
||||
} |
||||
|
||||
return ARES_SUCCESS; |
||||
} |
||||
|
||||
static int config_domain(ares_channel channel, char *str) |
||||
{ |
||||
char *q; |
||||
|
||||
/* Set a single search domain. */ |
||||
q = str; |
||||
while (*q && !isspace((unsigned char)*q)) |
||||
q++; |
||||
*q = 0; |
||||
return set_search(channel, str); |
||||
} |
||||
|
||||
static int config_lookup(ares_channel channel, const char *str) |
||||
{ |
||||
char lookups[3], *l; |
||||
const char *p; |
||||
|
||||
/* Set the lookup order. Only the first letter of each work
|
||||
* is relevant, and it has to be "b" for DNS or "f" for the |
||||
* host file. Ignore everything else. |
||||
*/ |
||||
l = lookups; |
||||
p = str; |
||||
while (*p) |
||||
{ |
||||
if ((*p == 'b' || *p == 'f') && l < lookups + 2) |
||||
*l++ = *p; |
||||
while (*p && !isspace((unsigned char)*p)) |
||||
p++; |
||||
while (isspace((unsigned char)*p)) |
||||
p++; |
||||
} |
||||
*l = 0; |
||||
channel->lookups = strdup(lookups); |
||||
return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM; |
||||
} |
||||
|
||||
static int config_nameserver(struct server_state **servers, int *nservers, |
||||
const char *str) |
||||
{ |
||||
struct in_addr addr; |
||||
struct server_state *newserv; |
||||
|
||||
/* Add a nameserver entry, if this is a valid address. */ |
||||
addr.s_addr = inet_addr(str); |
||||
if (addr.s_addr == INADDR_NONE) |
||||
return ARES_SUCCESS; |
||||
newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state)); |
||||
if (!newserv) |
||||
return ARES_ENOMEM; |
||||
newserv[*nservers].addr = addr; |
||||
*servers = newserv; |
||||
(*nservers)++; |
||||
return ARES_SUCCESS; |
||||
} |
||||
|
||||
static int config_sortlist(struct apattern **sortlist, int *nsort, |
||||
const char *str) |
||||
{ |
||||
struct apattern pat, *newsort; |
||||
const char *q; |
||||
|
||||
/* Add sortlist entries. */ |
||||
while (*str && *str != ';') |
||||
{ |
||||
q = str; |
||||
while (*q && *q != '/' && *q != ';' && !isspace((unsigned char)*q)) |
||||
q++; |
||||
if (ip_addr(str, q - str, &pat.addr) == 0) |
||||
{ |
||||
/* We have a pattern address; now determine the mask. */ |
||||
if (*q == '/') |
||||
{ |
||||
str = q + 1; |
||||
while (*q && *q != ';' && !isspace((unsigned char)*q)) |
||||
q++; |
||||
if (ip_addr(str, q - str, &pat.mask) != 0) |
||||
natural_mask(&pat); |
||||
} |
||||
else |
||||
natural_mask(&pat); |
||||
|
||||
/* Add this pattern to our list. */ |
||||
newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern)); |
||||
if (!newsort) |
||||
return ARES_ENOMEM; |
||||
newsort[*nsort] = pat; |
||||
*sortlist = newsort; |
||||
(*nsort)++; |
||||
} |
||||
else |
||||
{ |
||||
while (*q && *q != ';' && !isspace((unsigned char)*q)) |
||||
q++; |
||||
} |
||||
str = q; |
||||
while (isspace((unsigned char)*str)) |
||||
str++; |
||||
} |
||||
|
||||
return ARES_SUCCESS; |
||||
} |
||||
|
||||
static int set_search(ares_channel channel, const char *str) |
||||
{ |
||||
int n; |
||||
const char *p, *q; |
||||
|
||||
/* Count the domains given. */ |
||||
n = 0; |
||||
p = str; |
||||
while (*p) |
||||
{ |
||||
while (*p && !isspace((unsigned char)*p)) |
||||
p++; |
||||
while (isspace((unsigned char)*p)) |
||||
p++; |
||||
n++; |
||||
} |
||||
|
||||
channel->domains = malloc(n * sizeof(char *)); |
||||
if (!channel->domains && n) |
||||
return ARES_ENOMEM; |
||||
|
||||
/* Now copy the domains. */ |
||||
n = 0; |
||||
p = str; |
||||
while (*p) |
||||
{ |
||||
channel->ndomains = n; |
||||
q = p; |
||||
while (*q && !isspace((unsigned char)*q)) |
||||
q++; |
||||
channel->domains[n] = malloc(q - p + 1); |
||||
if (!channel->domains[n]) |
||||
return ARES_ENOMEM; |
||||
memcpy(channel->domains[n], p, q - p); |
||||
channel->domains[n][q - p] = 0; |
||||
p = q; |
||||
while (isspace((unsigned char)*p)) |
||||
p++; |
||||
n++; |
||||
} |
||||
channel->ndomains = n; |
||||
|
||||
return ARES_SUCCESS; |
||||
} |
||||
|
||||
static int set_options(ares_channel channel, const char *str) |
||||
{ |
||||
const char *p, *q, *val; |
||||
|
||||
p = str; |
||||
while (*p) |
||||
{ |
||||
q = p; |
||||
while (*q && !isspace((unsigned char)*q)) |
||||
q++; |
||||
val = try_option(p, q, "ndots:"); |
||||
if (val && channel->ndots == -1) |
||||
channel->ndots = atoi(val); |
||||
val = try_option(p, q, "retrans:"); |
||||
if (val && channel->timeout == -1) |
||||
channel->timeout = atoi(val); |
||||
val = try_option(p, q, "retry:"); |
||||
if (val && channel->tries == -1) |
||||
channel->tries = atoi(val); |
||||
p = q; |
||||
while (isspace((unsigned char)*p)) |
||||
p++; |
||||
} |
||||
|
||||
return ARES_SUCCESS; |
||||
} |
||||
|
||||
static char *try_config(char *s, char *opt) |
||||
{ |
||||
int len; |
||||
|
||||
len = strlen(opt); |
||||
if (strncmp(s, opt, len) != 0 || !isspace((unsigned char)s[len])) |
||||
return NULL; |
||||
s += len; |
||||
while (isspace((unsigned char)*s)) |
||||
s++; |
||||
return s; |
||||
} |
||||
|
||||
static const char *try_option(const char *p, const char *q, const char *opt) |
||||
{ |
||||
int len; |
||||
|
||||
len = strlen(opt); |
||||
return (q - p > len && strncmp(p, opt, len) == 0) ? p + len : NULL; |
||||
} |
||||
|
||||
static int ip_addr(const char *s, int len, struct in_addr *addr) |
||||
{ |
||||
char ipbuf[16]; |
||||
|
||||
/* Four octets and three periods yields at most 15 characters. */ |
||||
if (len > 15) |
||||
return -1; |
||||
memcpy(ipbuf, s, len); |
||||
ipbuf[len] = 0; |
||||
|
||||
addr->s_addr = inet_addr(ipbuf); |
||||
if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0) |
||||
return -1; |
||||
return 0; |
||||
} |
||||
|
||||
static void natural_mask(struct apattern *pat) |
||||
{ |
||||
struct in_addr addr; |
||||
|
||||
/* Store a host-byte-order copy of pat in a struct in_addr. Icky,
|
||||
* but portable. |
||||
*/ |
||||
addr.s_addr = ntohl(pat->addr.s_addr); |
||||
|
||||
/* This is out of date in the CIDR world, but some people might
|
||||
* still rely on it. |
||||
*/ |
||||
if (IN_CLASSA(addr.s_addr)) |
||||
pat->mask.s_addr = htonl(IN_CLASSA_NET); |
||||
else if (IN_CLASSB(addr.s_addr)) |
||||
pat->mask.s_addr = htonl(IN_CLASSB_NET); |
||||
else |
||||
pat->mask.s_addr = htonl(IN_CLASSC_NET); |
||||
} |
@ -0,0 +1,2 @@ |
||||
.so man3/ares_init.3 |
||||
.\" $Id$ |
@ -0,0 +1,79 @@ |
||||
.\" $Id$ |
||||
.\" |
||||
.\" Copyright 1998, 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" |
||||
.\" without express or implied warranty. |
||||
.\" |
||||
.TH ARES_MKQUERY 3 "4 January 2000" |
||||
.SH NAME |
||||
ares_mkquery \- Compose a single-question DNS query buffer |
||||
.SH SYNOPSIS |
||||
.nf |
||||
.B #include <ares.h> |
||||
.PP |
||||
.B |
||||
int ares_mkquery(const char *\fIname\fP, int \fIdnsclass\fP, int \fItype\fP, |
||||
.B |
||||
unsigned short \fIid\fP, int \fIrd\fP, char **\fIbuf\fP, |
||||
int *\fIbuflen\fP) |
||||
.fi |
||||
.SH DESCRIPTION |
||||
The |
||||
.B ares_mkquery |
||||
function composes a DNS query with a single question. |
||||
The parameter |
||||
.I name |
||||
gives the query name as a NUL-terminated C string of period-separated |
||||
labels optionally ending with a period; periods and backslashes within |
||||
a label must be escaped with a backlash. The parameters |
||||
.I dnsclass |
||||
and |
||||
.I type |
||||
give the class and type of the query using the values defined in |
||||
.BR <arpa/nameser.h> . |
||||
The parameter |
||||
.I id |
||||
gives a 16-bit identifier for the query. The parameter |
||||
.I rd |
||||
should be nonzero if recursion is desired, zero if not. The query |
||||
will be placed in an allocated buffer, a pointer to which will be |
||||
stored in the variable pointed to by |
||||
.IR buf , |
||||
and the length of which will be stored in the variable pointed to by |
||||
.IR buflen . |
||||
It is the caller's responsibility to free this buffer using |
||||
.B ares_free_string |
||||
when it is no longer needed. |
||||
.SH RETURN VALUES |
||||
.B ares_mkquery |
||||
can return any of the following values: |
||||
.TP 15 |
||||
.B ARES_SUCCESS |
||||
Construction of the DNS query succeeded. |
||||
.TP 15 |
||||
.B ARES_EBADNAME |
||||
The query name |
||||
.I name |
||||
could not be encoded as a domain name, either because it contained a |
||||
zero-length label or because it contained a label of more than 63 |
||||
characters. |
||||
.TP 15 |
||||
.B ARES_ENOMEM |
||||
Memory was exhausted. |
||||
.SH SEE ALSO |
||||
.BR ares_expand_name (3), |
||||
.BR ares_free_string (3) |
||||
.SH AUTHOR |
||||
Greg Hudson, MIT Information Systems |
||||
.br |
||||
Copyright 1998, 2000 by the Massachusetts Institute of Technology. |
@ -0,0 +1,161 @@ |
||||
/* 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 <string.h> |
||||
#include "ares.h" |
||||
#include "ares_dns.h" |
||||
|
||||
/* Header format, from RFC 1035:
|
||||
* 1 1 1 1 1 1 |
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 |
||||
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
||||
* | ID | |
||||
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
||||
* |QR| Opcode |AA|TC|RD|RA| Z | RCODE | |
||||
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
||||
* | QDCOUNT | |
||||
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
||||
* | ANCOUNT | |
||||
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
||||
* | NSCOUNT | |
||||
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
||||
* | ARCOUNT | |
||||
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
||||
* |
||||
* AA, TC, RA, and RCODE are only set in responses. Brief description |
||||
* of the remaining fields: |
||||
* ID Identifier to match responses with queries |
||||
* QR Query (0) or response (1) |
||||
* Opcode For our purposes, always QUERY |
||||
* RD Recursion desired |
||||
* Z Reserved (zero) |
||||
* QDCOUNT Number of queries |
||||
* ANCOUNT Number of answers |
||||
* NSCOUNT Number of name server records |
||||
* ARCOUNT Number of additional records |
||||
* |
||||
* Question format, from RFC 1035: |
||||
* 1 1 1 1 1 1 |
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 |
||||
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
||||
* | | |
||||
* / QNAME / |
||||
* / / |
||||
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
||||
* | QTYPE | |
||||
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
||||
* | QCLASS | |
||||
* +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
||||
* |
||||
* The query name is encoded as a series of labels, each represented |
||||
* as a one-byte length (maximum 63) followed by the text of the |
||||
* label. The list is terminated by a label of length zero (which can |
||||
* be thought of as the root domain). |
||||
*/ |
||||
|
||||
int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id, |
||||
int rd, unsigned char **buf, int *buflen) |
||||
{ |
||||
int len; |
||||
unsigned char *q; |
||||
const char *p; |
||||
|
||||
/* Compute the length of the encoded name so we can check buflen.
|
||||
* Start counting at 1 for the zero-length label at the end. */ |
||||
len = 1; |
||||
for (p = name; *p; p++) |
||||
{ |
||||
if (*p == '\\' && *(p + 1) != 0) |
||||
p++; |
||||
len++; |
||||
} |
||||
/* If there are n periods in the name, there are n + 1 labels, and
|
||||
* thus n + 1 length fields, unless the name is empty or ends with a |
||||
* period. So add 1 unless name is empty or ends with a period. |
||||
*/ |
||||
if (*name && *(p - 1) != '.') |
||||
len++; |
||||
|
||||
*buflen = len + HFIXEDSZ + QFIXEDSZ; |
||||
*buf = malloc(*buflen); |
||||
if (!*buf) |
||||
return ARES_ENOMEM; |
||||
|
||||
/* Set up the header. */ |
||||
q = *buf; |
||||
memset(q, 0, HFIXEDSZ); |
||||
DNS_HEADER_SET_QID(q, id); |
||||
DNS_HEADER_SET_OPCODE(q, QUERY); |
||||
DNS_HEADER_SET_RD(q, (rd) ? 1 : 0); |
||||
DNS_HEADER_SET_QDCOUNT(q, 1); |
||||
|
||||
/* A name of "." is a screw case for the loop below, so adjust it. */ |
||||
if (strcmp(name, ".") == 0) |
||||
name++; |
||||
|
||||
/* Start writing out the name after the header. */ |
||||
q += HFIXEDSZ; |
||||
while (*name) |
||||
{ |
||||
if (*name == '.') |
||||
return ARES_EBADNAME; |
||||
|
||||
/* Count the number of bytes in this label. */ |
||||
len = 0; |
||||
for (p = name; *p && *p != '.'; p++) |
||||
{ |
||||
if (*p == '\\' && *(p + 1) != 0) |
||||
p++; |
||||
len++; |
||||
} |
||||
if (len > MAXLABEL) |
||||
return ARES_EBADNAME; |
||||
|
||||
/* Encode the length and copy the data. */ |
||||
*q++ = len; |
||||
for (p = name; *p && *p != '.'; p++) |
||||
{ |
||||
if (*p == '\\' && *(p + 1) != 0) |
||||
p++; |
||||
*q++ = *p; |
||||
} |
||||
|
||||
/* Go to the next label and repeat, unless we hit the end. */ |
||||
if (!*p) |
||||
break; |
||||
name = p + 1; |
||||
} |
||||
|
||||
/* Add the zero-length label at the end. */ |
||||
*q++ = 0; |
||||
|
||||
/* Finish off the question with the type and class. */ |
||||
DNS_QUESTION_SET_TYPE(q, type); |
||||
DNS_QUESTION_SET_CLASS(q, dnsclass); |
||||
|
||||
return ARES_SUCCESS; |
||||
} |
@ -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_PARSE_A_REPLY 3 "25 July 1998" |
||||
.SH NAME |
||||
ares_parse_a_reply \- Parse a reply to a DNS query of type A into a hostent |
||||
.SH SYNOPSIS |
||||
.nf |
||||
.B #include <ares.h> |
||||
.PP |
||||
.B |
||||
int ares_parse_a_reply(const unsigned char *\fIabuf\fB, int \fIalen\fB, |
||||
.B struct hostent **\fIhost\fB); |
||||
.fi |
||||
.SH DESCRIPTION |
||||
The |
||||
.B ares_parse_a_reply |
||||
function parses the response to a query of type A into a |
||||
.BR "struct hostent" . |
||||
The parameters |
||||
.I abuf |
||||
and |
||||
.I alen |
||||
give the contents of the response. The result is stored in allocated |
||||
memory and a pointer to it stored into the variable pointed to by |
||||
.IR host . |
||||
It is the caller's responsibility to free the resulting host structure |
||||
using |
||||
.BR ares_free_hostent (3) |
||||
when it is no longer needed. |
||||
.SH RETURN VALUES |
||||
.B ares_parse_a_reply |
||||
can return any of the following values: |
||||
.TP 15 |
||||
.B ARES_SUCCESS |
||||
The response was successfully parsed. |
||||
.TP 15 |
||||
.B ARES_EBADRESP |
||||
The response was malformatted. |
||||
.TP 15 |
||||
.B ARES_ENODATA |
||||
The response did not contain an answer to the query. |
||||
.TP 15 |
||||
.B ARES_ENOMEM |
||||
Memory was exhausted. |
||||
.SH SEE ALSO |
||||
.BR ares_gethostbyname (3), |
||||
.BR ares_free_hostent (3) |
||||
.SH AUTHOR |
||||
Greg Hudson, MIT Information Systems |
||||
.br |
||||
Copyright 1998 by the Massachusetts Institute of Technology. |
@ -0,0 +1,173 @@ |
||||
/* 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/socket.h> |
||||
#include <netinet/in.h> |
||||
#include <arpa/inet.h> |
||||
#include <netdb.h> |
||||
#include <arpa/nameser.h> |
||||
#endif |
||||
|
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include "ares.h" |
||||
#include "ares_dns.h" |
||||
#include "ares_private.h" |
||||
|
||||
int ares_parse_a_reply(const unsigned char *abuf, int alen, |
||||
struct hostent **host) |
||||
{ |
||||
unsigned int qdcount, ancount; |
||||
int status, i, len, rr_type, rr_class, rr_len, naddrs; |
||||
int naliases; |
||||
const unsigned char *aptr; |
||||
char *hostname, *rr_name, *rr_data, **aliases; |
||||
struct in_addr *addrs; |
||||
struct hostent *hostent; |
||||
|
||||
/* Set *host to NULL for all failure cases. */ |
||||
*host = NULL; |
||||
|
||||
/* Give up if abuf doesn't have room for a header. */ |
||||
if (alen < HFIXEDSZ) |
||||
return ARES_EBADRESP; |
||||
|
||||
/* Fetch the question and answer count from the header. */ |
||||
qdcount = DNS_HEADER_QDCOUNT(abuf); |
||||
ancount = DNS_HEADER_ANCOUNT(abuf); |
||||
if (qdcount != 1) |
||||
return ARES_EBADRESP; |
||||
|
||||
/* Expand the name from the question, and skip past the question. */ |
||||
aptr = abuf + HFIXEDSZ; |
||||
status = ares_expand_name(aptr, abuf, alen, &hostname, &len); |
||||
if (status != ARES_SUCCESS) |
||||
return status; |
||||
if (aptr + len + QFIXEDSZ > abuf + alen) |
||||
{ |
||||
free(hostname); |
||||
return ARES_EBADRESP; |
||||
} |
||||
aptr += len + QFIXEDSZ; |
||||
|
||||
/* Allocate addresses and aliases; ancount gives an upper bound for both. */ |
||||
addrs = malloc(ancount * sizeof(struct in_addr)); |
||||
if (!addrs) |
||||
{ |
||||
free(hostname); |
||||
return ARES_ENOMEM; |
||||
} |
||||
aliases = malloc((ancount + 1) * sizeof(char *)); |
||||
if (!aliases) |
||||
{ |
||||
free(hostname); |
||||
free(addrs); |
||||
return ARES_ENOMEM; |
||||
} |
||||
naddrs = 0; |
||||
naliases = 0; |
||||
|
||||
/* Examine each answer resource record (RR) in turn. */ |
||||
for (i = 0; i < ancount; i++) |
||||
{ |
||||
/* Decode the RR up to the data field. */ |
||||
status = ares_expand_name(aptr, abuf, alen, &rr_name, &len); |
||||
if (status != ARES_SUCCESS) |
||||
break; |
||||
aptr += len; |
||||
if (aptr + RRFIXEDSZ > abuf + alen) |
||||
{ |
||||
status = ARES_EBADRESP; |
||||
break; |
||||
} |
||||
rr_type = DNS_RR_TYPE(aptr); |
||||
rr_class = DNS_RR_CLASS(aptr); |
||||
rr_len = DNS_RR_LEN(aptr); |
||||
aptr += RRFIXEDSZ; |
||||
|
||||
if (rr_class == C_IN && rr_type == T_A |
||||
&& rr_len == sizeof(struct in_addr) |
||||
&& strcasecmp(rr_name, hostname) == 0) |
||||
{ |
||||
memcpy(&addrs[naddrs], aptr, sizeof(struct in_addr)); |
||||
naddrs++; |
||||
status = ARES_SUCCESS; |
||||
} |
||||
|
||||
if (rr_class == C_IN && rr_type == T_CNAME) |
||||
{ |
||||
/* Record the RR name as an alias. */ |
||||
aliases[naliases] = rr_name; |
||||
naliases++; |
||||
|
||||
/* Decode the RR data and replace the hostname with it. */ |
||||
status = ares_expand_name(aptr, abuf, alen, &rr_data, &len); |
||||
if (status != ARES_SUCCESS) |
||||
break; |
||||
free(hostname); |
||||
hostname = rr_data; |
||||
} |
||||
else |
||||
free(rr_name); |
||||
|
||||
aptr += rr_len; |
||||
if (aptr > abuf + alen) |
||||
{ |
||||
status = ARES_EBADRESP; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (status == ARES_SUCCESS && naddrs == 0) |
||||
status = ARES_ENODATA; |
||||
if (status == ARES_SUCCESS) |
||||
{ |
||||
/* We got our answer. Allocate memory to build the host entry. */ |
||||
aliases[naliases] = NULL; |
||||
hostent = malloc(sizeof(struct hostent)); |
||||
if (hostent) |
||||
{ |
||||
hostent->h_addr_list = malloc((naddrs + 1) * sizeof(char *)); |
||||
if (hostent->h_addr_list) |
||||
{ |
||||
/* Fill in the hostent and return successfully. */ |
||||
hostent->h_name = hostname; |
||||
hostent->h_aliases = aliases; |
||||
hostent->h_addrtype = AF_INET; |
||||
hostent->h_length = sizeof(struct in_addr); |
||||
for (i = 0; i < naddrs; i++) |
||||
hostent->h_addr_list[i] = (char *) &addrs[i]; |
||||
hostent->h_addr_list[naddrs] = NULL; |
||||
*host = hostent; |
||||
return ARES_SUCCESS; |
||||
} |
||||
free(hostent); |
||||
} |
||||
status = ARES_ENOMEM; |
||||
} |
||||
for (i = 0; i < naliases; i++) |
||||
free(aliases[i]); |
||||
free(aliases); |
||||
free(addrs); |
||||
free(hostname); |
||||
return status; |
||||
} |
@ -0,0 +1,77 @@ |
||||
.\" $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_PARSE_PTR_REPLY 3 "25 July 1998" |
||||
.SH NAME |
||||
ares_parse_ptr_reply \- Parse a reply to a DNS query of type PTR into a hostent |
||||
.SH SYNOPSIS |
||||
.nf |
||||
.B #include <ares.h> |
||||
.PP |
||||
.B |
||||
int ares_parse_ptr_reply(const unsigned char *\fIabuf\fB, int \fIalen\fB, |
||||
.B |
||||
const void *\fIaddr\fP, int \fIaddrlen\fP, int \fIfamily\fP, |
||||
.B struct hostent **\fIhost\fB); |
||||
.fi |
||||
.SH DESCRIPTION |
||||
The |
||||
.B ares_parse_ptr_reply |
||||
function parses the response to a query of type PTR into a |
||||
.BR "struct hostent" . |
||||
The parameters |
||||
.I abuf |
||||
and |
||||
.I alen |
||||
give the contents of the response. The parameters |
||||
.IR addr , |
||||
.IR addrlen , |
||||
and |
||||
.I family |
||||
specify which address was queried for; they are not used to verify the |
||||
response, merely used to fill in the address of the |
||||
.BR "struct hostent" . |
||||
The resulting |
||||
.B struct hostent |
||||
is stored in allocated memory and a pointer to it stored into the |
||||
variable pointed to by |
||||
.IR host . |
||||
It is the caller's responsibility to free the resulting host structure |
||||
using |
||||
.BR ares_free_hostent (3) |
||||
when it is no longer needed. |
||||
.SH RETURN VALUES |
||||
.B ares_parse_ptr_reply |
||||
can return any of the following values: |
||||
.TP 15 |
||||
.B ARES_SUCCESS |
||||
The response was successfully parsed. |
||||
.TP 15 |
||||
.B ARES_EBADRESP |
||||
The response was malformatted. |
||||
.TP 15 |
||||
.B ARES_ENODATA |
||||
The response did not contain an answer to the query. |
||||
.TP 15 |
||||
.B ARES_ENOMEM |
||||
Memory was exhausted. |
||||
.SH SEE ALSO |
||||
.BR ares_gethostbyaddr (3), |
||||
.BR ares_free_hostent (3) |
||||
.SH AUTHOR |
||||
Greg Hudson, MIT Information Systems |
||||
.br |
||||
Copyright 1998 by the Massachusetts Institute of Technology. |
@ -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 <sys/socket.h> |
||||
#include <netinet/in.h> |
||||
#include <netdb.h> |
||||
#include <arpa/nameser.h> |
||||
#endif |
||||
|
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include "ares.h" |
||||
#include "ares_dns.h" |
||||
#include "ares_private.h" |
||||
|
||||
int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, |
||||
int addrlen, int family, struct hostent **host) |
||||
{ |
||||
unsigned int qdcount, ancount; |
||||
int status, i, len, rr_type, rr_class, rr_len; |
||||
const unsigned char *aptr; |
||||
char *ptrname, *hostname, *rr_name, *rr_data; |
||||
struct hostent *hostent; |
||||
|
||||
/* Set *host to NULL for all failure cases. */ |
||||
*host = NULL; |
||||
|
||||
/* Give up if abuf doesn't have room for a header. */ |
||||
if (alen < HFIXEDSZ) |
||||
return ARES_EBADRESP; |
||||
|
||||
/* Fetch the question and answer count from the header. */ |
||||
qdcount = DNS_HEADER_QDCOUNT(abuf); |
||||
ancount = DNS_HEADER_ANCOUNT(abuf); |
||||
if (qdcount != 1) |
||||
return ARES_EBADRESP; |
||||
|
||||
/* Expand the name from the question, and skip past the question. */ |
||||
aptr = abuf + HFIXEDSZ; |
||||
status = ares_expand_name(aptr, abuf, alen, &ptrname, &len); |
||||
if (status != ARES_SUCCESS) |
||||
return status; |
||||
if (aptr + len + QFIXEDSZ > abuf + alen) |
||||
{ |
||||
free(ptrname); |
||||
return ARES_EBADRESP; |
||||
} |
||||
aptr += len + QFIXEDSZ; |
||||
|
||||
/* Examine each answer resource record (RR) in turn. */ |
||||
hostname = NULL; |
||||
for (i = 0; i < ancount; i++) |
||||
{ |
||||
/* Decode the RR up to the data field. */ |
||||
status = ares_expand_name(aptr, abuf, alen, &rr_name, &len); |
||||
if (status != ARES_SUCCESS) |
||||
break; |
||||
aptr += len; |
||||
if (aptr + RRFIXEDSZ > abuf + alen) |
||||
{ |
||||
status = ARES_EBADRESP; |
||||
break; |
||||
} |
||||
rr_type = DNS_RR_TYPE(aptr); |
||||
rr_class = DNS_RR_CLASS(aptr); |
||||
rr_len = DNS_RR_LEN(aptr); |
||||
aptr += RRFIXEDSZ; |
||||
|
||||
if (rr_class == C_IN && rr_type == T_PTR |
||||
&& strcasecmp(rr_name, ptrname) == 0) |
||||
{ |
||||
/* Decode the RR data and set hostname to it. */ |
||||
status = ares_expand_name(aptr, abuf, alen, &rr_data, &len); |
||||
if (status != ARES_SUCCESS) |
||||
break; |
||||
if (hostname) |
||||
free(hostname); |
||||
hostname = rr_data; |
||||
} |
||||
|
||||
if (rr_class == C_IN && rr_type == T_CNAME) |
||||
{ |
||||
/* Decode the RR data and replace ptrname with it. */ |
||||
status = ares_expand_name(aptr, abuf, alen, &rr_data, &len); |
||||
if (status != ARES_SUCCESS) |
||||
break; |
||||
free(ptrname); |
||||
ptrname = rr_data; |
||||
} |
||||
|
||||
free(rr_name); |
||||
aptr += rr_len; |
||||
if (aptr > abuf + alen) |
||||
{ |
||||
status = ARES_EBADRESP; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (status == ARES_SUCCESS && !hostname) |
||||
status = ARES_ENODATA; |
||||
if (status == ARES_SUCCESS) |
||||
{ |
||||
/* We got our answer. Allocate memory to build the host entry. */ |
||||
hostent = malloc(sizeof(struct hostent)); |
||||
if (hostent) |
||||
{ |
||||
hostent->h_addr_list = malloc(2 * sizeof(char *)); |
||||
if (hostent->h_addr_list) |
||||
{ |
||||
hostent->h_addr_list[0] = malloc(addrlen); |
||||
if (hostent->h_addr_list[0]) |
||||
{ |
||||
hostent->h_aliases = malloc(sizeof (char *)); |
||||
if (hostent->h_aliases) |
||||
{ |
||||
/* Fill in the hostent and return successfully. */ |
||||
hostent->h_name = hostname; |
||||
hostent->h_aliases[0] = NULL; |
||||
hostent->h_addrtype = family; |
||||
hostent->h_length = addrlen; |
||||
memcpy(hostent->h_addr_list[0], addr, addrlen); |
||||
hostent->h_addr_list[1] = NULL; |
||||
*host = hostent; |
||||
free(ptrname); |
||||
return ARES_SUCCESS; |
||||
} |
||||
free(hostent->h_addr_list[0]); |
||||
} |
||||
free(hostent->h_addr_list); |
||||
} |
||||
free(hostent); |
||||
} |
||||
status = ARES_ENOMEM; |
||||
} |
||||
if (hostname) |
||||
free(hostname); |
||||
free(ptrname); |
||||
return status; |
||||
} |
@ -0,0 +1,145 @@ |
||||
/* $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. |
||||
*/ |
||||
|
||||
#include <stdio.h> |
||||
#include <sys/types.h> |
||||
|
||||
#ifdef WIN32 |
||||
|
||||
#else |
||||
#include <netinet/in.h> |
||||
/* We define closesocket() here so that we can use this function all over
|
||||
the source code for closing sockets. */ |
||||
#define closesocket(x) close(x) |
||||
#endif |
||||
|
||||
#define DEFAULT_TIMEOUT 5 |
||||
#define DEFAULT_TRIES 4 |
||||
#ifndef INADDR_NONE |
||||
#define INADDR_NONE 0xffffffff |
||||
#endif |
||||
|
||||
#ifdef WIN32 |
||||
|
||||
#define IsNT ((int)GetVersion()>0) |
||||
#define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP" |
||||
#define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters" |
||||
#define NAMESERVER "NameServer" |
||||
#define DHCPNAMESERVER "DhcpNameServer" |
||||
#define PATH_HOSTS_NT "\\drivers\\etc\\hosts" |
||||
#define PATH_HOSTS_9X "\\hosts" |
||||
|
||||
#else |
||||
|
||||
#define PATH_RESOLV_CONF "/etc/resolv.conf" |
||||
#ifdef ETC_INET |
||||
#define PATH_HOSTS "/etc/inet/hosts" |
||||
#else |
||||
#define PATH_HOSTS "/etc/hosts" |
||||
#endif |
||||
|
||||
#endif |
||||
|
||||
struct send_request { |
||||
/* Remaining data to send */ |
||||
const char *data; |
||||
int len; |
||||
|
||||
/* Next request in queue */ |
||||
struct send_request *next; |
||||
}; |
||||
|
||||
struct server_state { |
||||
struct in_addr addr; |
||||
int udp_socket; |
||||
int tcp_socket; |
||||
|
||||
/* Mini-buffer for reading the length word */ |
||||
unsigned char tcp_lenbuf[2]; |
||||
int tcp_lenbuf_pos; |
||||
int tcp_length; |
||||
|
||||
/* Buffer for reading actual TCP data */ |
||||
unsigned char *tcp_buffer; |
||||
int tcp_buffer_pos; |
||||
|
||||
/* TCP output queue */ |
||||
struct send_request *qhead; |
||||
struct send_request *qtail; |
||||
}; |
||||
|
||||
struct query { |
||||
/* Query ID from qbuf, for faster lookup, and current timeout */ |
||||
unsigned short qid; |
||||
time_t timeout; |
||||
|
||||
/* Query buf with length at beginning, for TCP transmission */ |
||||
char *tcpbuf; |
||||
int tcplen; |
||||
|
||||
/* Arguments passed to ares_send() (qbuf points into tcpbuf) */ |
||||
const char *qbuf; |
||||
int qlen; |
||||
ares_callback callback; |
||||
void *arg; |
||||
|
||||
/* Query status */ |
||||
int try; |
||||
int server; |
||||
int *skip_server; |
||||
int using_tcp; |
||||
int error_status; |
||||
|
||||
/* Next query in chain */ |
||||
struct query *next; |
||||
}; |
||||
|
||||
/* An IP address pattern; matches an IP address X if X & mask == addr */ |
||||
struct apattern { |
||||
struct in_addr addr; |
||||
struct in_addr mask; |
||||
}; |
||||
|
||||
struct ares_channeldata { |
||||
/* Configuration data */ |
||||
int flags; |
||||
int timeout; |
||||
int tries; |
||||
int ndots; |
||||
int udp_port; |
||||
int tcp_port; |
||||
char **domains; |
||||
int ndomains; |
||||
struct apattern *sortlist; |
||||
int nsort; |
||||
char *lookups; |
||||
|
||||
/* Server addresses and communications state */ |
||||
struct server_state *servers; |
||||
int nservers; |
||||
|
||||
/* ID to use for next query */ |
||||
unsigned short next_id; |
||||
|
||||
/* Active queries */ |
||||
struct query *queries; |
||||
}; |
||||
|
||||
void ares__send_query(ares_channel channel, struct query *query, time_t now); |
||||
void ares__close_sockets(struct server_state *server); |
||||
int ares__get_hostent(FILE *fp, struct hostent **host); |
||||
int ares__read_line(FILE *fp, char **buf, int *bufsize); |
@ -0,0 +1,79 @@ |
||||
.\" $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_PROCESS 3 "25 July 1998" |
||||
.SH NAME |
||||
ares_process \- Process events for name resolution |
||||
.SH SYNOPSIS |
||||
.nf |
||||
.B #include <ares.h> |
||||
.PP |
||||
.B void ares_process(ares_channel \fIchannel\fP, fd_set *\fIread_fds\fP, |
||||
.B fd_set *\fIwrite_fds\fP) |
||||
.fi |
||||
.SH DESCRIPTION |
||||
The |
||||
.B ares_process |
||||
function handles input/output events and timeouts associated with |
||||
queries pending on the name service channel identified by |
||||
.IR channel . |
||||
The file descriptor sets pointed to by |
||||
.I read_fds |
||||
and |
||||
.I write_fds |
||||
should have file descriptors set in them according to whether the file |
||||
descriptors specified by |
||||
.BR ares_fds (3) |
||||
are ready for reading and writing. (The easiest way to determine this |
||||
information is to invoke |
||||
.B select |
||||
with a timeout no greater than the timeout given by |
||||
.BR ares_timeout (3)). |
||||
.PP |
||||
The |
||||
.B ares_process |
||||
function will invoke callbacks for pending queries if they complete |
||||
successfully or fail. |
||||
.SS EXAMPLE |
||||
The following code fragment waits for all pending queries on a channel |
||||
to complete: |
||||
.PP |
||||
.RS |
||||
.nf |
||||
int nfds, count; |
||||
fd_set readers, writers; |
||||
struct timeval tv, *tvp; |
||||
|
||||
while (1) |
||||
{ |
||||
FD_ZERO(&readers); |
||||
FD_ZERO(&writers); |
||||
nfds = ares_fds(channel, &readers, &writers); |
||||
if (nfds == 0) |
||||
break; |
||||
tvp = ares_timeout(channel, NULL, &tv); |
||||
count = select(nfds, &readers, &writers, NULL, tvp); |
||||
ares_process(channel, &readers, &writers); |
||||
} |
||||
.fi |
||||
.RE |
||||
.SH SEE ALSO |
||||
.BR ares_fds (3), |
||||
.BR ares_timeout (3) |
||||
.SH AUTHOR |
||||
Greg Hudson, MIT Information Systems |
||||
.br |
||||
Copyright 1998 by the Massachusetts Institute of Technology. |
@ -0,0 +1,625 @@ |
||||
/* 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/socket.h> |
||||
#include <sys/uio.h> |
||||
#include <netinet/in.h> |
||||
#include <netdb.h> |
||||
#include <arpa/nameser.h> |
||||
#include <unistd.h> |
||||
#endif |
||||
|
||||
#include <string.h> |
||||
#include <stdlib.h> |
||||
#include <fcntl.h> |
||||
#include <time.h> |
||||
#include <errno.h> |
||||
#include "ares.h" |
||||
#include "ares_dns.h" |
||||
#include "ares_private.h" |
||||
|
||||
static void write_tcp_data(ares_channel channel, fd_set *write_fds, |
||||
time_t now); |
||||
static void read_tcp_data(ares_channel channel, fd_set *read_fds, time_t now); |
||||
static void read_udp_packets(ares_channel channel, fd_set *read_fds, |
||||
time_t now); |
||||
static void process_timeouts(ares_channel channel, time_t now); |
||||
static void process_answer(ares_channel channel, unsigned char *abuf, |
||||
int alen, int whichserver, int tcp, int now); |
||||
static void handle_error(ares_channel channel, int whichserver, time_t now); |
||||
static void next_server(ares_channel channel, struct query *query, time_t now); |
||||
static int open_tcp_socket(ares_channel channel, struct server_state *server); |
||||
static int open_udp_socket(ares_channel channel, struct server_state *server); |
||||
static int same_questions(const unsigned char *qbuf, int qlen, |
||||
const unsigned char *abuf, int alen); |
||||
static void end_query(ares_channel channel, struct query *query, int status, |
||||
unsigned char *abuf, int alen); |
||||
|
||||
/* Something interesting happened on the wire, or there was a timeout.
|
||||
* See what's up and respond accordingly. |
||||
*/ |
||||
void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds) |
||||
{ |
||||
time_t now; |
||||
|
||||
time(&now); |
||||
write_tcp_data(channel, write_fds, now); |
||||
read_tcp_data(channel, read_fds, now); |
||||
read_udp_packets(channel, read_fds, now); |
||||
process_timeouts(channel, now); |
||||
} |
||||
|
||||
/* If any TCP sockets select true for writing, write out queued data
|
||||
* we have for them. |
||||
*/ |
||||
static void write_tcp_data(ares_channel channel, fd_set *write_fds, time_t now) |
||||
{ |
||||
struct server_state *server; |
||||
struct send_request *sendreq; |
||||
struct iovec *vec; |
||||
int i, n, count; |
||||
|
||||
for (i = 0; i < channel->nservers; i++) |
||||
{ |
||||
/* Make sure server has data to send and is selected in write_fds. */ |
||||
server = &channel->servers[i]; |
||||
if (!server->qhead || server->tcp_socket == -1 |
||||
|| !FD_ISSET(server->tcp_socket, write_fds)) |
||||
continue; |
||||
|
||||
/* Count the number of send queue items. */ |
||||
n = 0; |
||||
for (sendreq = server->qhead; sendreq; sendreq = sendreq->next) |
||||
n++; |
||||
|
||||
#ifdef WIN32 |
||||
vec = NULL; |
||||
#else |
||||
/* Allocate iovecs so we can send all our data at once. */ |
||||
vec = malloc(n * sizeof(struct iovec)); |
||||
#endif |
||||
if (vec) |
||||
{ |
||||
#ifdef WIN32 |
||||
#else |
||||
/* Fill in the iovecs and send. */ |
||||
n = 0; |
||||
for (sendreq = server->qhead; sendreq; sendreq = sendreq->next) |
||||
{ |
||||
vec[n].iov_base = (char *) sendreq->data; |
||||
vec[n].iov_len = sendreq->len; |
||||
n++; |
||||
} |
||||
count = writev(server->tcp_socket, vec, n); |
||||
free(vec); |
||||
if (count < 0) |
||||
{ |
||||
handle_error(channel, i, now); |
||||
continue; |
||||
} |
||||
|
||||
/* Advance the send queue by as many bytes as we sent. */ |
||||
while (count) |
||||
{ |
||||
sendreq = server->qhead; |
||||
if (count >= sendreq->len) |
||||
{ |
||||
count -= sendreq->len; |
||||
server->qhead = sendreq->next; |
||||
if (server->qhead == NULL) |
||||
server->qtail = NULL; |
||||
free(sendreq); |
||||
} |
||||
else |
||||
{ |
||||
sendreq->data += count; |
||||
sendreq->len -= count; |
||||
break; |
||||
} |
||||
} |
||||
#endif |
||||
} |
||||
else |
||||
{ |
||||
/* Can't allocate iovecs; just send the first request. */ |
||||
sendreq = server->qhead; |
||||
|
||||
count = send(server->tcp_socket, sendreq->data, sendreq->len, 0); |
||||
|
||||
if (count < 0) |
||||
{ |
||||
handle_error(channel, i, now); |
||||
continue; |
||||
} |
||||
|
||||
/* Advance the send queue by as many bytes as we sent. */ |
||||
if (count == sendreq->len) |
||||
{ |
||||
server->qhead = sendreq->next; |
||||
if (server->qhead == NULL) |
||||
server->qtail = NULL; |
||||
free(sendreq); |
||||
} |
||||
else |
||||
{ |
||||
sendreq->data += count; |
||||
sendreq->len -= count; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* If any TCP socket selects true for reading, read some data,
|
||||
* allocate a buffer if we finish reading the length word, and process |
||||
* a packet if we finish reading one. |
||||
*/ |
||||
static void read_tcp_data(ares_channel channel, fd_set *read_fds, time_t now) |
||||
{ |
||||
struct server_state *server; |
||||
int i, count; |
||||
|
||||
for (i = 0; i < channel->nservers; i++) |
||||
{ |
||||
/* Make sure the server has a socket and is selected in read_fds. */ |
||||
server = &channel->servers[i]; |
||||
if (server->tcp_socket == -1 || !FD_ISSET(server->tcp_socket, read_fds)) |
||||
continue; |
||||
|
||||
if (server->tcp_lenbuf_pos != 2) |
||||
{ |
||||
/* We haven't yet read a length word, so read that (or
|
||||
* what's left to read of it). |
||||
*/ |
||||
count = recv(server->tcp_socket, |
||||
server->tcp_lenbuf + server->tcp_buffer_pos, |
||||
2 - server->tcp_buffer_pos, 0); |
||||
if (count <= 0) |
||||
{ |
||||
handle_error(channel, i, now); |
||||
continue; |
||||
} |
||||
|
||||
server->tcp_lenbuf_pos += count; |
||||
if (server->tcp_lenbuf_pos == 2) |
||||
{ |
||||
/* We finished reading the length word. Decode the
|
||||
* length and allocate a buffer for the data. |
||||
*/ |
||||
server->tcp_length = server->tcp_lenbuf[0] << 8 |
||||
| server->tcp_lenbuf[1]; |
||||
server->tcp_buffer = malloc(server->tcp_length); |
||||
if (!server->tcp_buffer) |
||||
handle_error(channel, i, now); |
||||
server->tcp_buffer_pos = 0; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
/* Read data into the allocated buffer. */ |
||||
count = recv(server->tcp_socket, |
||||
server->tcp_buffer + server->tcp_buffer_pos, |
||||
server->tcp_length - server->tcp_buffer_pos, 0); |
||||
if (count <= 0) |
||||
{ |
||||
handle_error(channel, i, now); |
||||
continue; |
||||
} |
||||
|
||||
server->tcp_buffer_pos += count; |
||||
if (server->tcp_buffer_pos == server->tcp_length) |
||||
{ |
||||
/* We finished reading this answer; process it and
|
||||
* prepare to read another length word. |
||||
*/ |
||||
process_answer(channel, server->tcp_buffer, server->tcp_length, |
||||
i, 1, now); |
||||
free(server->tcp_buffer); |
||||
server->tcp_buffer = NULL; |
||||
server->tcp_lenbuf_pos = 0; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* If any UDP sockets select true for reading, process them. */ |
||||
static void read_udp_packets(ares_channel channel, fd_set *read_fds, |
||||
time_t now) |
||||
{ |
||||
struct server_state *server; |
||||
int i, count; |
||||
unsigned char buf[PACKETSZ + 1]; |
||||
|
||||
for (i = 0; i < channel->nservers; i++) |
||||
{ |
||||
/* Make sure the server has a socket and is selected in read_fds. */ |
||||
server = &channel->servers[i]; |
||||
|
||||
if (server->udp_socket == -1 || !FD_ISSET(server->udp_socket, read_fds)) |
||||
continue; |
||||
|
||||
count = recv(server->udp_socket, buf, sizeof(buf), 0); |
||||
if (count <= 0) |
||||
handle_error(channel, i, now); |
||||
|
||||
process_answer(channel, buf, count, i, 0, now); |
||||
} |
||||
} |
||||
|
||||
/* If any queries have timed out, note the timeout and move them on. */ |
||||
static void process_timeouts(ares_channel channel, time_t now) |
||||
{ |
||||
struct query *query, *next; |
||||
|
||||
for (query = channel->queries; query; query = next) |
||||
{ |
||||
next = query->next; |
||||
if (query->timeout != 0 && now >= query->timeout) |
||||
{ |
||||
query->error_status = ARES_ETIMEOUT; |
||||
next_server(channel, query, now); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* Handle an answer from a server. */ |
||||
static void process_answer(ares_channel channel, unsigned char *abuf, |
||||
int alen, int whichserver, int tcp, int now) |
||||
{ |
||||
int id, tc, rcode; |
||||
struct query *query; |
||||
|
||||
/* If there's no room in the answer for a header, we can't do much
|
||||
* with it. */ |
||||
if (alen < HFIXEDSZ) |
||||
return; |
||||
|
||||
/* Grab the query ID, truncate bit, and response code from the packet. */ |
||||
id = DNS_HEADER_QID(abuf); |
||||
tc = DNS_HEADER_TC(abuf); |
||||
rcode = DNS_HEADER_RCODE(abuf); |
||||
|
||||
/* Find the query corresponding to this packet. */ |
||||
for (query = channel->queries; query; query = query->next) |
||||
{ |
||||
if (query->qid == id) |
||||
break; |
||||
} |
||||
if (!query) |
||||
return; |
||||
|
||||
/* If we got a truncated UDP packet and are not ignoring truncation,
|
||||
* don't accept the packet, and switch the query to TCP if we hadn't |
||||
* done so already. |
||||
*/ |
||||
if ((tc || alen > PACKETSZ) && !tcp && !(channel->flags & ARES_FLAG_IGNTC)) |
||||
{ |
||||
if (!query->using_tcp) |
||||
{ |
||||
query->using_tcp = 1; |
||||
ares__send_query(channel, query, now); |
||||
} |
||||
return; |
||||
} |
||||
|
||||
/* Limit alen to PACKETSZ if we aren't using TCP (only relevant if we
|
||||
* are ignoring truncation. |
||||
*/ |
||||
if (alen > PACKETSZ && !tcp) |
||||
alen = PACKETSZ; |
||||
|
||||
/* If we aren't passing through all error packets, discard packets
|
||||
* with SERVFAIL, NOTIMP, or REFUSED response codes. |
||||
*/ |
||||
if (!(channel->flags & ARES_FLAG_NOCHECKRESP)) |
||||
{ |
||||
if (rcode == SERVFAIL || rcode == NOTIMP || rcode == REFUSED) |
||||
{ |
||||
query->skip_server[whichserver] = 1; |
||||
if (query->server == whichserver) |
||||
next_server(channel, query, now); |
||||
return; |
||||
} |
||||
if (!same_questions(query->qbuf, query->qlen, abuf, alen)) |
||||
{ |
||||
if (query->server == whichserver) |
||||
next_server(channel, query, now); |
||||
return; |
||||
} |
||||
} |
||||
|
||||
end_query(channel, query, ARES_SUCCESS, abuf, alen); |
||||
} |
||||
|
||||
static void handle_error(ares_channel channel, int whichserver, time_t now) |
||||
{ |
||||
struct query *query; |
||||
|
||||
/* Reset communications with this server. */ |
||||
ares__close_sockets(&channel->servers[whichserver]); |
||||
|
||||
/* Tell all queries talking to this server to move on and not try
|
||||
* this server again. |
||||
*/ |
||||
for (query = channel->queries; query; query = query->next) |
||||
{ |
||||
if (query->server == whichserver) |
||||
{ |
||||
query->skip_server[whichserver] = 1; |
||||
next_server(channel, query, now); |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void next_server(ares_channel channel, struct query *query, time_t now) |
||||
{ |
||||
/* Advance to the next server or try. */ |
||||
query->server++; |
||||
for (; query->try < channel->tries; query->try++) |
||||
{ |
||||
for (; query->server < channel->nservers; query->server++) |
||||
{ |
||||
if (!query->skip_server[query->server]) |
||||
{ |
||||
ares__send_query(channel, query, now); |
||||
return; |
||||
} |
||||
} |
||||
query->server = 0; |
||||
|
||||
/* Only one try if we're using TCP. */ |
||||
if (query->using_tcp) |
||||
break; |
||||
} |
||||
end_query(channel, query, query->error_status, NULL, 0); |
||||
} |
||||
|
||||
void ares__send_query(ares_channel channel, struct query *query, time_t now) |
||||
{ |
||||
struct send_request *sendreq; |
||||
struct server_state *server; |
||||
|
||||
server = &channel->servers[query->server]; |
||||
if (query->using_tcp) |
||||
{ |
||||
/* Make sure the TCP socket for this server is set up and queue
|
||||
* a send request. |
||||
*/ |
||||
if (server->tcp_socket == -1) |
||||
{ |
||||
if (open_tcp_socket(channel, server) == -1) |
||||
{ |
||||
query->skip_server[query->server] = 1; |
||||
next_server(channel, query, now); |
||||
return; |
||||
} |
||||
} |
||||
sendreq = malloc(sizeof(struct send_request)); |
||||
if (!sendreq) |
||||
end_query(channel, query, ARES_ENOMEM, NULL, 0); |
||||
sendreq->data = query->tcpbuf; |
||||
sendreq->len = query->tcplen; |
||||
sendreq->next = NULL; |
||||
if (server->qtail) |
||||
server->qtail->next = sendreq; |
||||
else |
||||
server->qhead = sendreq; |
||||
server->qtail = sendreq; |
||||
query->timeout = 0; |
||||
} |
||||
else |
||||
{ |
||||
if (server->udp_socket == -1) |
||||
{ |
||||
if (open_udp_socket(channel, server) == -1) |
||||
{ |
||||
query->skip_server[query->server] = 1; |
||||
next_server(channel, query, now); |
||||
return; |
||||
} |
||||
} |
||||
if (send(server->udp_socket, query->qbuf, query->qlen, 0) == -1) |
||||
{ |
||||
query->skip_server[query->server] = 1; |
||||
next_server(channel, query, now); |
||||
return; |
||||
} |
||||
query->timeout = now |
||||
+ ((query->try == 0) ? channel->timeout |
||||
: channel->timeout << query->try / channel->nservers); |
||||
} |
||||
} |
||||
|
||||
static int open_tcp_socket(ares_channel channel, struct server_state *server) |
||||
{ |
||||
int s, flags; |
||||
struct sockaddr_in sin; |
||||
|
||||
/* Acquire a socket. */ |
||||
s = socket(AF_INET, SOCK_STREAM, 0); |
||||
if (s == -1) |
||||
return -1; |
||||
|
||||
/* Set the socket non-blocking. */ |
||||
|
||||
#ifdef WIN32 |
||||
flags = 1; |
||||
ioctlsocket(s, FIONBIO, &flags); |
||||
#else |
||||
if (fcntl(s, F_GETFL, &flags) == -1) |
||||
{ |
||||
close(s); |
||||
return -1; |
||||
} |
||||
flags &= O_NONBLOCK; |
||||
if (fcntl(s, F_SETFL, flags) == -1) |
||||
{ |
||||
close(s); |
||||
return -1; |
||||
} |
||||
#endif |
||||
|
||||
/* Connect to the server. */ |
||||
memset(&sin, 0, sizeof(sin)); |
||||
sin.sin_family = AF_INET; |
||||
sin.sin_addr = server->addr; |
||||
sin.sin_port = channel->tcp_port; |
||||
if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == -1 |
||||
&& errno != EINPROGRESS) |
||||
{ |
||||
closesocket(s); |
||||
return -1; |
||||
} |
||||
|
||||
server->tcp_socket = s; |
||||
return 0; |
||||
} |
||||
|
||||
static int open_udp_socket(ares_channel channel, struct server_state *server) |
||||
{ |
||||
int s; |
||||
struct sockaddr_in sin; |
||||
|
||||
/* Acquire a socket. */ |
||||
s = socket(AF_INET, SOCK_DGRAM, 0); |
||||
if (s == -1) |
||||
return -1; |
||||
|
||||
/* Connect to the server. */ |
||||
memset(&sin, 0, sizeof(sin)); |
||||
sin.sin_family = AF_INET; |
||||
sin.sin_addr = server->addr; |
||||
sin.sin_port = channel->udp_port; |
||||
if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == -1) |
||||
{ |
||||
closesocket(s); |
||||
return -1; |
||||
} |
||||
|
||||
server->udp_socket = s; |
||||
return 0; |
||||
} |
||||
|
||||
static int same_questions(const unsigned char *qbuf, int qlen, |
||||
const unsigned char *abuf, int alen) |
||||
{ |
||||
struct { |
||||
const unsigned char *p; |
||||
int qdcount; |
||||
char *name; |
||||
int namelen; |
||||
int type; |
||||
int dnsclass; |
||||
} q, a; |
||||
int i, j; |
||||
|
||||
if (qlen < HFIXEDSZ || alen < HFIXEDSZ) |
||||
return 0; |
||||
|
||||
/* Extract qdcount from the request and reply buffers and compare them. */ |
||||
q.qdcount = DNS_HEADER_QDCOUNT(qbuf); |
||||
a.qdcount = DNS_HEADER_QDCOUNT(abuf); |
||||
if (q.qdcount != a.qdcount) |
||||
return 0; |
||||
|
||||
/* For each question in qbuf, find it in abuf. */ |
||||
q.p = qbuf + HFIXEDSZ; |
||||
for (i = 0; i < q.qdcount; i++) |
||||
{ |
||||
/* Decode the question in the query. */ |
||||
if (ares_expand_name(q.p, qbuf, qlen, &q.name, &q.namelen) |
||||
!= ARES_SUCCESS) |
||||
return 0; |
||||
q.p += q.namelen; |
||||
if (q.p + QFIXEDSZ > qbuf + qlen) |
||||
{ |
||||
free(q.name); |
||||
return 0; |
||||
} |
||||
q.type = DNS_QUESTION_TYPE(q.p); |
||||
q.dnsclass = DNS_QUESTION_CLASS(q.p); |
||||
q.p += QFIXEDSZ; |
||||
|
||||
/* Search for this question in the answer. */ |
||||
a.p = abuf + HFIXEDSZ; |
||||
for (j = 0; j < a.qdcount; j++) |
||||
{ |
||||
/* Decode the question in the answer. */ |
||||
if (ares_expand_name(a.p, abuf, alen, &a.name, &a.namelen) |
||||
!= ARES_SUCCESS) |
||||
{ |
||||
free(q.name); |
||||
return 0; |
||||
} |
||||
a.p += a.namelen; |
||||
if (a.p + QFIXEDSZ > abuf + alen) |
||||
{ |
||||
free(q.name); |
||||
free(a.name); |
||||
return 0; |
||||
} |
||||
a.type = DNS_QUESTION_TYPE(a.p); |
||||
a.dnsclass = DNS_QUESTION_CLASS(a.p); |
||||
a.p += QFIXEDSZ; |
||||
|
||||
/* Compare the decoded questions. */ |
||||
if (strcasecmp(q.name, a.name) == 0 && q.type == a.type |
||||
&& q.dnsclass == a.dnsclass) |
||||
{ |
||||
free(a.name); |
||||
break; |
||||
} |
||||
free(a.name); |
||||
} |
||||
|
||||
free(q.name); |
||||
if (j == a.qdcount) |
||||
return 0; |
||||
} |
||||
return 1; |
||||
} |
||||
|
||||
static void end_query(ares_channel channel, struct query *query, int status, |
||||
unsigned char *abuf, int alen) |
||||
{ |
||||
struct query **q; |
||||
int i; |
||||
|
||||
query->callback(query->arg, status, abuf, alen); |
||||
for (q = &channel->queries; *q; q = &(*q)->next) |
||||
{ |
||||
if (*q == query) |
||||
break; |
||||
} |
||||
*q = query->next; |
||||
free(query->tcpbuf); |
||||
free(query->skip_server); |
||||
free(query); |
||||
|
||||
/* Simple cleanup policy: if no queries are remaining, close all
|
||||
* network sockets unless STAYOPEN is set. |
||||
*/ |
||||
if (!channel->queries && !(channel->flags & ARES_FLAG_STAYOPEN)) |
||||
{ |
||||
for (i = 0; i < channel->nservers; i++) |
||||
ares__close_sockets(&channel->servers[i]); |
||||
} |
||||
} |
@ -0,0 +1,142 @@ |
||||
.\" $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_QUERY 3 "24 July 1998" |
||||
.SH NAME |
||||
ares_query \- Initiate a single-question DNS query |
||||
.SH SYNOPSIS |
||||
.nf |
||||
.B #include <ares.h> |
||||
.PP |
||||
.B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP, |
||||
.B unsigned char *\fIabuf\fP, int \fIalen\fP) |
||||
.PP |
||||
.B void ares_query(ares_channel \fIchannel\fP, const char *\fIname\fP, |
||||
.B int \fIdnsclass\fP, int \fItype\fP, ares_callback \fIcallback\fP, |
||||
.B void *\fIarg\fP) |
||||
.fi |
||||
.SH DESCRIPTION |
||||
The |
||||
.B ares_query |
||||
function initiates a single-question DNS query on the name service |
||||
channel identified by |
||||
.IR channel . |
||||
The parameter |
||||
.I name |
||||
gives the query name as a NUL-terminated C string of period-separated |
||||
labels optionally ending with a period; periods and backslashes within |
||||
a label must be escaped with a backslash. The parameters |
||||
.I dnsclass |
||||
and |
||||
.I type |
||||
give the class and type of the query using the values defined in |
||||
.BR <arpa/nameser.h> . |
||||
When the query is complete or has failed, the ares library will invoke |
||||
.IR callback . |
||||
Completion or failure of the query may happen immediately, or may |
||||
happen during a later call to |
||||
.BR ares_process (3) |
||||
or |
||||
.BR ares_destroy (3). |
||||
.PP |
||||
The callback argument |
||||
.I arg |
||||
is copied from the |
||||
.B ares_query |
||||
argument |
||||
.IR arg . |
||||
The callback argument |
||||
.I status |
||||
indicates whether the query succeeded and, if not, how it failed. It |
||||
may have any of the following values: |
||||
.TP 19 |
||||
.B ARES_SUCCESS |
||||
The query completed successfully. |
||||
.TP 19 |
||||
.B ARES_ENODATA |
||||
The query completed but contains no answers. |
||||
.TP 19 |
||||
.B ARES_EFORMERR |
||||
The query completed but the server claims that the query was |
||||
malformatted. |
||||
.TP 19 |
||||
.B ARES_ESERVFAIL |
||||
The query completed but the server claims to have experienced a |
||||
failure. (This code can only occur if the |
||||
.B ARES_FLAG_NOCHECKRESP |
||||
flag was specified at channel initialization time; otherwise, such |
||||
responses are ignored at the |
||||
.BR ares_send (3) |
||||
level.) |
||||
.TP 19 |
||||
.B ARES_ENOTFOUND |
||||
The query completed but the queried-for domain name was not found. |
||||
.TP 19 |
||||
.B ARES_ENOTIMP |
||||
The query completed but the server does not implement the operation |
||||
requested by the query. (This code can only occur if the |
||||
.B ARES_FLAG_NOCHECKRESP |
||||
flag was specified at channel initialization time; otherwise, such |
||||
responses are ignored at the |
||||
.BR ares_send (3) |
||||
level.) |
||||
.TP 19 |
||||
.B ARES_EREFUSED |
||||
The query completed but the server refused the query. (This code can |
||||
only occur if the |
||||
.B ARES_FLAG_NOCHECKRESP |
||||
flag was specified at channel initialization time; otherwise, such |
||||
responses are ignored at the |
||||
.BR ares_send (3) |
||||
level.) |
||||
.TP 19 |
||||
.B ARES_EBADNAME |
||||
The query name |
||||
.I name |
||||
could not be encoded as a domain name, either because it contained a |
||||
zero-length label or because it contained a label of more than 63 |
||||
characters. |
||||
.TP 19 |
||||
.B ARES_ETIMEOUT |
||||
No name servers responded within the timeout period. |
||||
.TP 19 |
||||
.B ARES_ECONNREFUSED |
||||
No name servers could be contacted. |
||||
.TP 19 |
||||
.B ARES_ENOMEM |
||||
Memory was exhausted. |
||||
.TP 19 |
||||
.B ARES_EDESTRUCTION |
||||
The name service channel |
||||
.I channel |
||||
is being destroyed; the query will not be completed. |
||||
.PP |
||||
If the query completed (even if there was something wrong with it, as |
||||
indicated by some of the above error codes), the callback argument |
||||
.I abuf |
||||
points to a result buffer of length |
||||
.IR alen . |
||||
If the query did not complete, |
||||
.I abuf |
||||
will be NULL and |
||||
.I alen |
||||
will be 0. |
||||
.SH SEE ALSO |
||||
.BR ares_process (3) |
||||
.SH AUTHOR |
||||
Greg Hudson, MIT Information Systems |
||||
.br |
||||
Copyright 1998 by the Massachusetts Institute of Technology. |
@ -0,0 +1,112 @@ |
||||
/* 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" |
||||
#include "ares_dns.h" |
||||
#include "ares_private.h" |
||||
|
||||
struct qquery { |
||||
ares_callback callback; |
||||
void *arg; |
||||
}; |
||||
|
||||
static void qcallback(void *arg, int status, unsigned char *abuf, int alen); |
||||
|
||||
void ares_query(ares_channel channel, const char *name, int dnsclass, |
||||
int type, ares_callback callback, void *arg) |
||||
{ |
||||
struct qquery *qquery; |
||||
unsigned char *qbuf; |
||||
int qlen, rd, status; |
||||
|
||||
/* Compose the query. */ |
||||
rd = !(channel->flags & ARES_FLAG_NORECURSE); |
||||
status = ares_mkquery(name, dnsclass, type, channel->next_id, rd, &qbuf, |
||||
&qlen); |
||||
channel->next_id++; |
||||
if (status != ARES_SUCCESS) |
||||
{ |
||||
callback(arg, status, NULL, 0); |
||||
return; |
||||
} |
||||
|
||||
/* Allocate and fill in the query structure. */ |
||||
qquery = malloc(sizeof(struct qquery)); |
||||
if (!qquery) |
||||
{ |
||||
ares_free_string(qbuf); |
||||
callback(arg, ARES_ENOMEM, NULL, 0); |
||||
return; |
||||
} |
||||
qquery->callback = callback; |
||||
qquery->arg = arg; |
||||
|
||||
/* Send it off. qcallback will be called when we get an answer. */ |
||||
ares_send(channel, qbuf, qlen, qcallback, qquery); |
||||
ares_free_string(qbuf); |
||||
} |
||||
|
||||
static void qcallback(void *arg, int status, unsigned char *abuf, int alen) |
||||
{ |
||||
struct qquery *qquery = (struct qquery *) arg; |
||||
unsigned int ancount; |
||||
int rcode; |
||||
|
||||
if (status != ARES_SUCCESS) |
||||
qquery->callback(qquery->arg, status, abuf, alen); |
||||
else |
||||
{ |
||||
/* Pull the response code and answer count from the packet. */ |
||||
rcode = DNS_HEADER_RCODE(abuf); |
||||
ancount = DNS_HEADER_ANCOUNT(abuf); |
||||
|
||||
/* Convert errors. */ |
||||
switch (rcode) |
||||
{ |
||||
case NOERROR: |
||||
status = (ancount > 0) ? ARES_SUCCESS : ARES_ENODATA; |
||||
break; |
||||
case FORMERR: |
||||
status = ARES_EFORMERR; |
||||
break; |
||||
case SERVFAIL: |
||||
status = ARES_ESERVFAIL; |
||||
break; |
||||
case NXDOMAIN: |
||||
status = ARES_ENOTFOUND; |
||||
break; |
||||
case NOTIMP: |
||||
status = ARES_ENOTIMP; |
||||
break; |
||||
case REFUSED: |
||||
status = ARES_EREFUSED; |
||||
break; |
||||
} |
||||
qquery->callback(qquery->arg, status, abuf, alen); |
||||
} |
||||
free(qquery); |
||||
} |
@ -0,0 +1,144 @@ |
||||
.\" $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_SEARCH 3 "24 July 1998" |
||||
.SH NAME |
||||
ares_search \- Initiate a DNS query with domain search |
||||
.SH SYNOPSIS |
||||
.nf |
||||
.B #include <ares.h> |
||||
.PP |
||||
.B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP, |
||||
.B unsigned char *\fIabuf\fP, int \fIalen\fP) |
||||
.PP |
||||
.B void ares_search(ares_channel \fIchannel\fP, const char *\fIname\fP, |
||||
.B int \fIdnsclass\fP, int \fItype\fP, ares_callback \fIcallback\fP, |
||||
.B void *\fIarg\fP) |
||||
.fi |
||||
.SH DESCRIPTION |
||||
The |
||||
.B ares_search |
||||
function initiates a series of single-question DNS queries on the name |
||||
service channel identified by |
||||
.IR channel , |
||||
using the channel's search domains as well as a host alias file given |
||||
by the HOSTALIAS environment variable. The parameter |
||||
.I name |
||||
gives the alias name or the base of the query name as a NUL-terminated |
||||
C string of period-separated labels; if it ends with a period, the |
||||
channel's search domains will not be used. Periods and backslashes |
||||
within a label must be escaped with a backslash. The parameters |
||||
.I dnsclass |
||||
and |
||||
.I type |
||||
give the class and type of the query using the values defined in |
||||
.BR <arpa/nameser.h> . |
||||
When the query sequence is complete or has failed, the ares library |
||||
will invoke |
||||
.IR callback . |
||||
Completion or failure of the query sequence may happen immediately, or |
||||
may happen during a later call to |
||||
.BR ares_process (3) |
||||
or |
||||
.BR ares_destroy (3). |
||||
.PP |
||||
The callback argument |
||||
.I arg |
||||
is copied from the |
||||
.B ares_search |
||||
argument |
||||
.IR arg . |
||||
The callback argument |
||||
.I status |
||||
indicates whether the query sequence ended with a successful query |
||||
and, if not, how the query sequence failed. It may have any of the |
||||
following values: |
||||
.TP 19 |
||||
.B ARES_SUCCESS |
||||
A query completed successfully. |
||||
.TP 19 |
||||
.B ARES_ENODATA |
||||
No query completed successfully; when the query was tried without a |
||||
search domain appended, a response was returned with no answers. |
||||
.TP 19 |
||||
.B ARES_EFORMERR |
||||
A query completed but the server claimed that the query was |
||||
malformatted. |
||||
.TP 19 |
||||
.B ARES_ESERVFAIL |
||||
No query completed successfully; when the query was tried without a |
||||
search domain appended, the server claimed to have experienced a |
||||
failure. (This code can only occur if the |
||||
.B ARES_FLAG_NOCHECKRESP |
||||
flag was specified at channel initialization time; otherwise, such |
||||
responses are ignored at the |
||||
.BR ares_send (3) |
||||
level.) |
||||
.TP 19 |
||||
.B ARES_ENOTFOUND |
||||
No query completed successfully; when the query was tried without a |
||||
search domain appended, the server reported that the queried-for |
||||
domain name was not found. |
||||
.TP 19 |
||||
.B ARES_ENOTIMP |
||||
A query completed but the server does not implement the operation |
||||
requested by the query. (This code can only occur if the |
||||
.B ARES_FLAG_NOCHECKRESP |
||||
flag was specified at channel initialization time; otherwise, such |
||||
responses are ignored at the |
||||
.BR ares_send (3) |
||||
level.) |
||||
.TP 19 |
||||
.B ARES_EREFUSED |
||||
A query completed but the server refused the query. (This code can |
||||
only occur returned if the |
||||
.B ARES_FLAG_NOCHECKRESP |
||||
flag was specified at channel initialization time; otherwise, such |
||||
responses are ignored at the |
||||
.BR ares_send (3) |
||||
level.) |
||||
.TP 19 |
||||
.B ARES_TIMEOUT |
||||
No name servers responded to a query within the timeout period. |
||||
.TP 19 |
||||
.B ARES_ECONNREFUSED |
||||
No name servers could be contacted. |
||||
.TP 19 |
||||
.B ARES_ENOMEM |
||||
Memory was exhausted. |
||||
.TP 19 |
||||
.B ARES_EDESTRUCTION |
||||
The name service channel |
||||
.I channel |
||||
is being destroyed; the query will not be completed. |
||||
.PP |
||||
If a query completed successfully, the callback argument |
||||
.I abuf |
||||
points to a result buffer of length |
||||
.IR alen . |
||||
If the query did not complete successfully, |
||||
.I abuf |
||||
will usually be NULL and |
||||
.I alen |
||||
will usually be 0, but in some cases an unsuccessful query result may |
||||
be placed in |
||||
.IR abuf . |
||||
.SH SEE ALSO |
||||
.BR ares_process (3) |
||||
.SH AUTHOR |
||||
Greg Hudson, MIT Information Systems |
||||
.br |
||||
Copyright 1998 by the Massachusetts Institute of Technology. |
@ -0,0 +1,273 @@ |
||||
/* 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 <ctype.h> |
||||
|
||||
#ifdef WIN32 |
||||
#include "nameser.h" |
||||
#endif |
||||
|
||||
#include "ares.h" |
||||
#include "ares_private.h" |
||||
|
||||
struct search_query { |
||||
/* Arguments passed to ares_search */ |
||||
ares_channel channel; |
||||
char *name; /* copied into an allocated buffer */ |
||||
int dnsclass; |
||||
int type; |
||||
ares_callback callback; |
||||
void *arg; |
||||
|
||||
int status_as_is; /* error status from trying as-is */ |
||||
int next_domain; /* next search domain to try */ |
||||
int trying_as_is; /* current query is for name as-is */ |
||||
}; |
||||
|
||||
static void search_callback(void *arg, int status, unsigned char *abuf, |
||||
int alen); |
||||
static void end_squery(struct search_query *squery, int status, |
||||
unsigned char *abuf, int alen); |
||||
static int cat_domain(const char *name, const char *domain, char **s); |
||||
static int single_domain(ares_channel channel, const char *name, char **s); |
||||
|
||||
void ares_search(ares_channel channel, const char *name, int dnsclass, |
||||
int type, ares_callback callback, void *arg) |
||||
{ |
||||
struct search_query *squery; |
||||
char *s; |
||||
const char *p; |
||||
int status, ndots; |
||||
|
||||
/* If name only yields one domain to search, then we don't have
|
||||
* to keep extra state, so just do an ares_query(). |
||||
*/ |
||||
status = single_domain(channel, name, &s); |
||||
if (status != ARES_SUCCESS) |
||||
{ |
||||
callback(arg, status, NULL, 0); |
||||
return; |
||||
} |
||||
if (s) |
||||
{ |
||||
ares_query(channel, s, dnsclass, type, callback, arg); |
||||
free(s); |
||||
return; |
||||
} |
||||
|
||||
/* Allocate a search_query structure to hold the state necessary for
|
||||
* doing multiple lookups. |
||||
*/ |
||||
squery = malloc(sizeof(struct search_query)); |
||||
if (!squery) |
||||
{ |
||||
callback(arg, ARES_ENOMEM, NULL, 0); |
||||
return; |
||||
} |
||||
squery->channel = channel; |
||||
squery->name = strdup(name); |
||||
if (!squery->name) |
||||
{ |
||||
free(squery); |
||||
callback(arg, ARES_ENOMEM, NULL, 0); |
||||
return; |
||||
} |
||||
squery->dnsclass = dnsclass; |
||||
squery->type = type; |
||||
squery->status_as_is = -1; |
||||
squery->callback = callback; |
||||
squery->arg = arg; |
||||
|
||||
/* Count the number of dots in name. */ |
||||
ndots = 0; |
||||
for (p = name; *p; p++) |
||||
{ |
||||
if (*p == '.') |
||||
ndots++; |
||||
} |
||||
|
||||
/* If ndots is at least the channel ndots threshold (usually 1),
|
||||
* then we try the name as-is first. Otherwise, we try the name |
||||
* as-is last. |
||||
*/ |
||||
if (ndots >= channel->ndots) |
||||
{ |
||||
/* Try the name as-is first. */ |
||||
squery->next_domain = 0; |
||||
squery->trying_as_is = 1; |
||||
ares_query(channel, name, dnsclass, type, search_callback, squery); |
||||
} |
||||
else |
||||
{ |
||||
/* Try the name as-is last; start with the first search domain. */ |
||||
squery->next_domain = 1; |
||||
squery->trying_as_is = 0; |
||||
status = cat_domain(name, channel->domains[0], &s); |
||||
if (status == ARES_SUCCESS) |
||||
{ |
||||
ares_query(channel, s, dnsclass, type, search_callback, squery); |
||||
free(s); |
||||
} |
||||
else |
||||
callback(arg, status, NULL, 0); |
||||
} |
||||
} |
||||
|
||||
static void search_callback(void *arg, int status, unsigned char *abuf, |
||||
int alen) |
||||
{ |
||||
struct search_query *squery = (struct search_query *) arg; |
||||
ares_channel channel = squery->channel; |
||||
char *s; |
||||
|
||||
/* Stop searching unless we got a non-fatal error. */ |
||||
if (status != ARES_ENODATA && status != ARES_ESERVFAIL |
||||
&& status != ARES_ENOTFOUND) |
||||
end_squery(squery, status, abuf, alen); |
||||
else |
||||
{ |
||||
/* Save the status if we were trying as-is. */ |
||||
if (squery->trying_as_is) |
||||
squery->status_as_is = status; |
||||
if (squery->next_domain < channel->ndomains) |
||||
{ |
||||
/* Try the next domain. */ |
||||
status = cat_domain(squery->name, |
||||
channel->domains[squery->next_domain], &s); |
||||
if (status != ARES_SUCCESS) |
||||
end_squery(squery, status, NULL, 0); |
||||
else |
||||
{ |
||||
squery->trying_as_is = 0; |
||||
squery->next_domain++; |
||||
ares_query(channel, s, squery->dnsclass, squery->type, |
||||
search_callback, squery); |
||||
free(s); |
||||
} |
||||
} |
||||
else if (squery->status_as_is == -1) |
||||
{ |
||||
/* Try the name as-is at the end. */ |
||||
squery->trying_as_is = 1; |
||||
ares_query(channel, squery->name, squery->dnsclass, squery->type, |
||||
search_callback, squery); |
||||
} |
||||
else |
||||
end_squery(squery, squery->status_as_is, NULL, 0); |
||||
} |
||||
} |
||||
|
||||
static void end_squery(struct search_query *squery, int status, |
||||
unsigned char *abuf, int alen) |
||||
{ |
||||
squery->callback(squery->arg, status, abuf, alen); |
||||
free(squery->name); |
||||
free(squery); |
||||
} |
||||
|
||||
/* Concatenate two domains. */ |
||||
static int cat_domain(const char *name, const char *domain, char **s) |
||||
{ |
||||
int nlen = strlen(name), dlen = strlen(domain); |
||||
|
||||
*s = malloc(nlen + 1 + dlen + 1); |
||||
if (!*s) |
||||
return ARES_ENOMEM; |
||||
memcpy(*s, name, nlen); |
||||
(*s)[nlen] = '.'; |
||||
memcpy(*s + nlen + 1, domain, dlen); |
||||
(*s)[nlen + 1 + dlen] = 0; |
||||
return ARES_SUCCESS; |
||||
} |
||||
|
||||
/* Determine if this name only yields one query. If it does, set *s to
|
||||
* the string we should query, in an allocated buffer. If not, set *s |
||||
* to NULL. |
||||
*/ |
||||
static int single_domain(ares_channel channel, const char *name, char **s) |
||||
{ |
||||
int len = strlen(name); |
||||
const char *hostaliases; |
||||
FILE *fp; |
||||
char *line = NULL; |
||||
int linesize, status; |
||||
const char *p, *q; |
||||
|
||||
/* If the name contains a trailing dot, then the single query is the name
|
||||
* sans the trailing dot. |
||||
*/ |
||||
if (name[len - 1] == '.') |
||||
{ |
||||
*s = strdup(name); |
||||
return (*s) ? ARES_SUCCESS : ARES_ENOMEM; |
||||
} |
||||
|
||||
if (!(channel->flags & ARES_FLAG_NOALIASES) && !strchr(name, '.')) |
||||
{ |
||||
/* The name might be a host alias. */ |
||||
hostaliases = getenv("HOSTALIASES"); |
||||
if (hostaliases) |
||||
{ |
||||
fp = fopen(hostaliases, "r"); |
||||
if (fp) |
||||
{ |
||||
while ((status = ares__read_line(fp, &line, &linesize)) |
||||
== ARES_SUCCESS) |
||||
{ |
||||
if (strncasecmp(line, name, len) != 0 || |
||||
!isspace((unsigned char)line[len])) |
||||
continue; |
||||
p = line + len; |
||||
while (isspace((unsigned char)*p)) |
||||
p++; |
||||
if (*p) |
||||
{ |
||||
q = p + 1; |
||||
while (*q && !isspace((unsigned char)*q)) |
||||
q++; |
||||
*s = malloc(q - p + 1); |
||||
if (*s) |
||||
{ |
||||
memcpy(*s, p, q - p); |
||||
(*s)[q - p] = 0; |
||||
} |
||||
free(line); |
||||
fclose(fp); |
||||
return (*s) ? ARES_SUCCESS : ARES_ENOMEM; |
||||
} |
||||
} |
||||
free(line); |
||||
fclose(fp); |
||||
if (status != ARES_SUCCESS) |
||||
return status; |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (channel->flags & ARES_FLAG_NOSEARCH || channel->ndomains == 0) |
||||
{ |
||||
/* No domain search to do; just try the name as-is. */ |
||||
*s = strdup(name); |
||||
return (*s) ? ARES_SUCCESS : ARES_ENOMEM; |
||||
} |
||||
|
||||
*s = NULL; |
||||
return ARES_SUCCESS; |
||||
} |
@ -0,0 +1,117 @@ |
||||
.\" $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_SEND 3 "25 July 1998" |
||||
.SH NAME |
||||
ares_send \- Initiate a DNS query |
||||
.SH SYNOPSIS |
||||
.nf |
||||
.B #include <ares.h> |
||||
.PP |
||||
.B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP, |
||||
.B unsigned char *\fIabuf\fP, int \fIalen\fP) |
||||
.PP |
||||
.B |
||||
void ares_send(ares_channel \fIchannel\fP, const unsigned char *\fIqbuf\fP, |
||||
.B int \fIqlen\fP, ares_callback \fIcallback\fP, void *\fIarg\fP) |
||||
.fi |
||||
.SH DESCRIPTION |
||||
The |
||||
.B ares_send |
||||
function initiates a DNS query on the name service channel identified |
||||
by |
||||
.IR channel . |
||||
The parameters |
||||
.I qbuf |
||||
and |
||||
.I qlen |
||||
give the DNS query, which should already have been formatted according |
||||
to the DNS protocol. When the query is complete or has failed, the |
||||
ares library will invoke |
||||
.IR callback . |
||||
Completion or failure of the query may happen immediately, or may |
||||
happen during a later call to |
||||
.BR ares_process (3) |
||||
or |
||||
.BR ares_destroy (3). |
||||
.PP |
||||
The callback argument |
||||
.I arg |
||||
is copied from the |
||||
.B ares_send |
||||
argument |
||||
.IR arg . |
||||
The callback argument |
||||
.I status |
||||
indicates whether the query succeeded and, if not, how it failed. It |
||||
may have any of the following values: |
||||
.TP 19 |
||||
.B ARES_SUCCESS |
||||
The query completed. |
||||
.TP 19 |
||||
.B ARES_EBADQUERY |
||||
The query buffer was poorly formed (was not long enough for a DNS |
||||
header or was too long for TCP transmission). |
||||
.TP 19 |
||||
.B ARES_ETIMEOUT |
||||
No name servers responded within the timeout period. |
||||
.TP 19 |
||||
.B ARES_ECONNREFUSED |
||||
No name servers could be contacted. |
||||
.TP 19 |
||||
.B ARES_ENOMEM |
||||
Memory was exhausted. |
||||
.TP 19 |
||||
.B ARES_EDESTRUCTION |
||||
The name service channel |
||||
.I channel |
||||
is being destroyed; the query will not be completed. |
||||
.PP |
||||
If the query completed, the callback argument |
||||
.I abuf |
||||
points to a result buffer of length |
||||
.IR alen . |
||||
If the query did not complete, |
||||
.I abuf |
||||
will be NULL and |
||||
.I alen |
||||
will be 0. |
||||
.PP |
||||
Unless the flag |
||||
.B ARES_FLAG_NOCHECKRESP |
||||
was set at channel initialization time, |
||||
.B ares_send |
||||
will normally ignore responses whose questions do not match the |
||||
questions in |
||||
.IR qbuf , |
||||
as well as responses with reply codes of |
||||
.BR SERVFAIL , |
||||
.BR NOTIMP , |
||||
and |
||||
.BR REFUSED . |
||||
Unlike other query functions in the ares library, however, |
||||
.B ares_send |
||||
does not inspect the header of the reply packet to determine the error |
||||
status, so a callback status of |
||||
.B ARES_SUCCESS |
||||
does not reflect as much about the response as for other query |
||||
functions. |
||||
.SH SEE ALSO |
||||
.BR ares_process (3) |
||||
.SH AUTHOR |
||||
Greg Hudson, MIT Information Systems |
||||
.br |
||||
Copyright 1998 by the Massachusetts Institute of Technology. |
@ -0,0 +1,104 @@ |
||||
/* 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 <string.h> |
||||
#include <time.h> |
||||
#include "ares.h" |
||||
#include "ares_dns.h" |
||||
#include "ares_private.h" |
||||
|
||||
void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen, |
||||
ares_callback callback, void *arg) |
||||
{ |
||||
struct query *query; |
||||
int i; |
||||
time_t now; |
||||
|
||||
/* Verify that the query is at least long enough to hold the header. */ |
||||
if (qlen < HFIXEDSZ || qlen >= (1 << 16)) |
||||
{ |
||||
callback(arg, ARES_EBADQUERY, NULL, 0); |
||||
return; |
||||
} |
||||
|
||||
/* Allocate space for query and allocated fields. */ |
||||
query = malloc(sizeof(struct query)); |
||||
if (!query) |
||||
{ |
||||
callback(arg, ARES_ENOMEM, NULL, 0); |
||||
return; |
||||
} |
||||
query->tcpbuf = malloc(qlen + 2); |
||||
if (!query->tcpbuf) |
||||
{ |
||||
free(query); |
||||
callback(arg, ARES_ENOMEM, NULL, 0); |
||||
return; |
||||
} |
||||
query->skip_server = malloc(channel->nservers * sizeof(int)); |
||||
if (!query->skip_server) |
||||
{ |
||||
free(query->tcpbuf); |
||||
free(query); |
||||
callback(arg, ARES_ENOMEM, NULL, 0); |
||||
return; |
||||
} |
||||
|
||||
/* Compute the query ID. Start with no timeout. */ |
||||
query->qid = DNS_HEADER_QID(qbuf); |
||||
query->timeout = 0; |
||||
|
||||
/* Form the TCP query buffer by prepending qlen (as two
|
||||
* network-order bytes) to qbuf. |
||||
*/ |
||||
query->tcpbuf[0] = (qlen >> 8) & 0xff; |
||||
query->tcpbuf[1] = qlen & 0xff; |
||||
memcpy(query->tcpbuf + 2, qbuf, qlen); |
||||
query->tcplen = qlen + 2; |
||||
|
||||
/* Fill in query arguments. */ |
||||
query->qbuf = query->tcpbuf + 2; |
||||
query->qlen = qlen; |
||||
query->callback = callback; |
||||
query->arg = arg; |
||||
|
||||
/* Initialize query status. */ |
||||
query->try = 0; |
||||
query->server = 0; |
||||
for (i = 0; i < channel->nservers; i++) |
||||
query->skip_server[i] = 0; |
||||
query->using_tcp = (channel->flags & ARES_FLAG_USEVC) || qlen > PACKETSZ; |
||||
query->error_status = ARES_ECONNREFUSED; |
||||
|
||||
/* Chain the query into this channel's query list. */ |
||||
query->next = channel->queries; |
||||
channel->queries = query; |
||||
|
||||
/* Perform the first query action. */ |
||||
time(&now); |
||||
ares__send_query(channel, query, now); |
||||
} |
@ -0,0 +1,44 @@ |
||||
.\" $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_STRERROR 3 "25 July 1998" |
||||
.SH NAME |
||||
ares_strerror \- Get the description of an ares library error code |
||||
.SH SYNOPSIS |
||||
.nf |
||||
.B #include <ares.h> |
||||
.PP |
||||
.B const char *ares_strerror(int \fIcode\fP, char **\fImemptr\fP) |
||||
.fi |
||||
.SH DESCRIPTION |
||||
The |
||||
.B ares_strerror |
||||
function gets the description of the ares library error code |
||||
.IR code , |
||||
returning the result as a NUL-terminated C string. A pointer to |
||||
allocated data necessary to compose the error description may be |
||||
stored in the variable pointed to by |
||||
.IR memptr . |
||||
It is the caller's responsibility to invoke |
||||
.BR ares_free_errmem (3) |
||||
with the value of that variable when the error description is no |
||||
longer needed. |
||||
.SH SEE ALSO |
||||
.BR ares_free_errmem (3) |
||||
.SH AUTHOR |
||||
Greg Hudson, MIT Information Systems |
||||
.br |
||||
Copyright 1998 by the Massachusetts Institute of Technology. |
@ -0,0 +1,47 @@ |
||||
/* 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 <assert.h> |
||||
#include "ares.h" |
||||
|
||||
const char *ares_strerror(int code, char **memptr) |
||||
{ |
||||
/* A future implementation may want to handle internationalization.
|
||||
* For now, just return a string literal from a table. |
||||
*/ |
||||
const char *errtext[] = { |
||||
"Successful completion", |
||||
"DNS server returned answer with no data", |
||||
"DNS server claims query was misformatted", |
||||
"DNS server returned general failure", |
||||
"Domain name not found", |
||||
"DNS server does not implement requested operation", |
||||
"DNS server refused query", |
||||
"Misformatted DNS query", |
||||
"Misformatted domain name", |
||||
"Unsupported address family", |
||||
"Misformatted DNS reply", |
||||
"Could not contact DNS servers", |
||||
"Timeout while contacting DNS servers", |
||||
"End of file", |
||||
"Error reading file", |
||||
"Out of memory" |
||||
}; |
||||
|
||||
assert(code >= 0 && code < (sizeof(errtext) / sizeof(*errtext))); |
||||
return errtext[code]; |
||||
} |
@ -0,0 +1,64 @@ |
||||
.\" $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_TIMEOUT 3 "25 July 1998" |
||||
.SH NAME |
||||
ares_fds \- Get file descriptors to select on for name service |
||||
.SH SYNOPSIS |
||||
.nf |
||||
.B #include <ares.h> |
||||
.PP |
||||
.B struct timeval *ares_timeout(ares_channel \fIchannel\fP, |
||||
.B struct timeval *\fImaxtv\fP, struct timeval *\fItvbuf\fP) |
||||
.fi |
||||
.SH DESCRIPTION |
||||
The |
||||
.B ares_timeout |
||||
function determines the maximum time for which the caller should wait |
||||
before invoking |
||||
.BR ares_process (3) |
||||
to process timeouts. The parameter |
||||
.I maxtv |
||||
specifies a existing maximum timeout, or |
||||
.B NULL |
||||
if the caller does not wish to apply a maximum timeout. The parameter |
||||
.I tvbuf |
||||
must point to a writable buffer of type |
||||
.BR "struct timeval" . |
||||
It is valid for |
||||
.I maxtv |
||||
and |
||||
.I tvbuf |
||||
to have the same value. |
||||
.PP |
||||
If no queries have timeouts pending sooner than the given maximum |
||||
timeout, |
||||
.B ares_timeout |
||||
returns the value of |
||||
.IR maxtv; |
||||
otherwise |
||||
.B ares_timeout |
||||
stores the appropriate timeout value into the buffer pointed to by |
||||
.I tvbuf |
||||
and returns the value of |
||||
.IR tvbuf . |
||||
.SH SEE ALSO |
||||
.BR ares_fds (3), |
||||
.BR ares_process (3) |
||||
.SH AUTHOR |
||||
Greg Hudson, MIT Information Systems |
||||
.br |
||||
Copyright 1998 by the Massachusetts Institute of Technology. |
@ -0,0 +1,67 @@ |
||||
/* 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 <time.h> |
||||
#include "ares.h" |
||||
#include "ares_private.h" |
||||
|
||||
struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv, |
||||
struct timeval *tvbuf) |
||||
{ |
||||
struct query *query; |
||||
time_t now; |
||||
int offset, min_offset; |
||||
|
||||
/* No queries, no timeout (and no fetch of the current time). */ |
||||
if (!channel->queries) |
||||
return maxtv; |
||||
|
||||
/* Find the minimum timeout for the current set of queries. */ |
||||
time(&now); |
||||
min_offset = -1; |
||||
for (query = channel->queries; query; query = query->next) |
||||
{ |
||||
if (query->timeout == 0) |
||||
continue; |
||||
offset = query->timeout - now; |
||||
if (offset < 0) |
||||
offset = 0; |
||||
if (min_offset == -1 || offset < min_offset) |
||||
min_offset = offset; |
||||
} |
||||
|
||||
/* If we found a minimum timeout and it's sooner than the one
|
||||
* specified in maxtv (if any), return it. Otherwise go with |
||||
* maxtv. |
||||
*/ |
||||
if (min_offset != -1 && (!maxtv || min_offset <= maxtv->tv_sec)) |
||||
{ |
||||
tvbuf->tv_sec = min_offset; |
||||
tvbuf->tv_usec = 0; |
||||
return tvbuf; |
||||
} |
||||
else |
||||
return maxtv; |
||||
} |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,18 @@ |
||||
dnl Process this file with autoconf to produce a configure script. |
||||
AC_INIT(ares_init.c) |
||||
|
||||
AC_PROG_CC |
||||
AC_PROG_INSTALL |
||||
AC_PROG_RANLIB |
||||
|
||||
AC_CANONICAL_HOST |
||||
case $host_os in |
||||
solaris*) |
||||
AC_DEFINE(ETC_INET) |
||||
;; |
||||
esac |
||||
|
||||
AC_SEARCH_LIBS(gethostbyname, nsl) |
||||
AC_SEARCH_LIBS(socket, socket) |
||||
|
||||
AC_OUTPUT(Makefile) |
@ -0,0 +1,205 @@ |
||||
/* Windows-only header file provided by liren@vivisimo.com to make his Windows
|
||||
port build */ |
||||
|
||||
#include <windows.h> |
||||
#include <sys/types.h> |
||||
|
||||
#define MAXHOSTNAMELEN 256 |
||||
|
||||
#define EINPROGRESS WSAEINPROGRESS |
||||
|
||||
/* Structure for scatter/gather I/O. */ |
||||
struct iovec |
||||
{ |
||||
void *iov_base; /* Pointer to data. */ |
||||
size_t iov_len; /* Length of data. */ |
||||
}; |
||||
|
||||
#define getpid() _getpid() |
||||
|
||||
int strcasecmp(const char *a, const char *b); |
||||
int gettimeofday(struct timeval *tv, struct timezone *tz); |
||||
|
||||
#define NS_CMPRSFLGS 0xc0 |
||||
|
||||
|
||||
/* Flag bits indicating name compression. */ |
||||
#define INDIR_MASK NS_CMPRSFLGS |
||||
|
||||
typedef enum __ns_class { |
||||
ns_c_invalid = 0, /* Cookie. */ |
||||
ns_c_in = 1, /* Internet. */ |
||||
ns_c_2 = 2, /* unallocated/unsupported. */ |
||||
ns_c_chaos = 3, /* MIT Chaos-net. */ |
||||
ns_c_hs = 4, /* MIT Hesiod. */ |
||||
/* Query class values which do not appear in resource records */ |
||||
ns_c_none = 254, /* for prereq. sections in update requests */ |
||||
ns_c_any = 255, /* Wildcard match. */ |
||||
ns_c_max = 65536 |
||||
} ns_class; |
||||
|
||||
#define C_IN ns_c_in |
||||
|
||||
typedef enum __ns_type { |
||||
ns_t_invalid = 0, /* Cookie. */ |
||||
ns_t_a = 1, /* Host address. */ |
||||
ns_t_ns = 2, /* Authoritative server. */ |
||||
ns_t_md = 3, /* Mail destination. */ |
||||
ns_t_mf = 4, /* Mail forwarder. */ |
||||
ns_t_cname = 5, /* Canonical name. */ |
||||
ns_t_soa = 6, /* Start of authority zone. */ |
||||
ns_t_mb = 7, /* Mailbox domain name. */ |
||||
ns_t_mg = 8, /* Mail group member. */ |
||||
ns_t_mr = 9, /* Mail rename name. */ |
||||
ns_t_null = 10, /* Null resource record. */ |
||||
ns_t_wks = 11, /* Well known service. */ |
||||
ns_t_ptr = 12, /* Domain name pointer. */ |
||||
ns_t_hinfo = 13, /* Host information. */ |
||||
ns_t_minfo = 14, /* Mailbox information. */ |
||||
ns_t_mx = 15, /* Mail routing information. */ |
||||
ns_t_txt = 16, /* Text strings. */ |
||||
ns_t_rp = 17, /* Responsible person. */ |
||||
ns_t_afsdb = 18, /* AFS cell database. */ |
||||
ns_t_x25 = 19, /* X_25 calling address. */ |
||||
ns_t_isdn = 20, /* ISDN calling address. */ |
||||
ns_t_rt = 21, /* Router. */ |
||||
ns_t_nsap = 22, /* NSAP address. */ |
||||
ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */ |
||||
ns_t_sig = 24, /* Security signature. */ |
||||
ns_t_key = 25, /* Security key. */ |
||||
ns_t_px = 26, /* X.400 mail mapping. */ |
||||
ns_t_gpos = 27, /* Geographical position (withdrawn). */ |
||||
ns_t_aaaa = 28, /* Ip6 Address. */ |
||||
ns_t_loc = 29, /* Location Information. */ |
||||
ns_t_nxt = 30, /* Next domain (security). */ |
||||
ns_t_eid = 31, /* Endpoint identifier. */ |
||||
ns_t_nimloc = 32, /* Nimrod Locator. */ |
||||
ns_t_srv = 33, /* Server Selection. */ |
||||
ns_t_atma = 34, /* ATM Address */ |
||||
ns_t_naptr = 35, /* Naming Authority PoinTeR */ |
||||
ns_t_kx = 36, /* Key Exchange */ |
||||
ns_t_cert = 37, /* Certification record */ |
||||
ns_t_a6 = 38, /* IPv6 address (deprecates AAAA) */ |
||||
ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */ |
||||
ns_t_sink = 40, /* Kitchen sink (experimentatl) */ |
||||
ns_t_opt = 41, /* EDNS0 option (meta-RR) */ |
||||
ns_t_tsig = 250, /* Transaction signature. */ |
||||
ns_t_ixfr = 251, /* Incremental zone transfer. */ |
||||
ns_t_axfr = 252, /* Transfer zone of authority. */ |
||||
ns_t_mailb = 253, /* Transfer mailbox records. */ |
||||
ns_t_maila = 254, /* Transfer mail agent records. */ |
||||
ns_t_any = 255, /* Wildcard match. */ |
||||
ns_t_zxfr = 256, /* BIND-specific, nonstandard. */ |
||||
ns_t_max = 65536 |
||||
} ns_type; |
||||
|
||||
#define T_PTR ns_t_ptr |
||||
#define T_A ns_t_a |
||||
|
||||
|
||||
#define NS_DEFAULTPORT 53 /* For both TCP and UDP. */ |
||||
#define NAMESERVER_PORT NS_DEFAULTPORT |
||||
|
||||
#define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */ |
||||
#define HFIXEDSZ NS_HFIXEDSZ |
||||
|
||||
#define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */ |
||||
#define QFIXEDSZ NS_QFIXEDSZ |
||||
|
||||
typedef enum __ns_opcode { |
||||
ns_o_query = 0, /* Standard query. */ |
||||
ns_o_iquery = 1, /* Inverse query (deprecated/unsupported). */ |
||||
ns_o_status = 2, /* Name server status query (unsupported). */ |
||||
/* Opcode 3 is undefined/reserved. */ |
||||
ns_o_notify = 4, /* Zone change notification. */ |
||||
ns_o_update = 5, /* Zone update message. */ |
||||
ns_o_max = 6 |
||||
} ns_opcode; |
||||
|
||||
#define QUERY ns_o_query |
||||
|
||||
#define NS_MAXLABEL 63 |
||||
#define MAXLABEL NS_MAXLABEL |
||||
|
||||
#define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */ |
||||
#define RRFIXEDSZ NS_RRFIXEDSZ |
||||
|
||||
#define T_CNAME ns_t_cname |
||||
|
||||
|
||||
#define NS_PACKETSZ 512 /* maximum packet size */ |
||||
#define PACKETSZ NS_PACKETSZ |
||||
|
||||
typedef enum __ns_rcode { |
||||
ns_r_noerror = 0, /* No error occurred. */ |
||||
ns_r_formerr = 1, /* Format error. */ |
||||
ns_r_servfail = 2, /* Server failure. */ |
||||
ns_r_nxdomain = 3, /* Name error. */ |
||||
ns_r_notimpl = 4, /* Unimplemented. */ |
||||
ns_r_refused = 5, /* Operation refused. */ |
||||
/* these are for BIND_UPDATE */ |
||||
ns_r_yxdomain = 6, /* Name exists */ |
||||
ns_r_yxrrset = 7, /* RRset exists */ |
||||
ns_r_nxrrset = 8, /* RRset does not exist */ |
||||
ns_r_notauth = 9, /* Not authoritative for zone */ |
||||
ns_r_notzone = 10, /* Zone of record different from zone section */ |
||||
ns_r_max = 11, |
||||
/* The following are TSIG extended errors */ |
||||
ns_r_badsig = 16, |
||||
ns_r_badkey = 17, |
||||
ns_r_badtime = 18 |
||||
} ns_rcode; |
||||
|
||||
#define SERVFAIL ns_r_servfail |
||||
#define NOTIMP ns_r_notimpl |
||||
#define REFUSED ns_r_refused |
||||
#define NOERROR ns_r_noerror |
||||
#define FORMERR ns_r_formerr |
||||
#define NXDOMAIN ns_r_nxdomain |
||||
|
||||
#define C_CHAOS ns_c_chaos |
||||
#define C_HS ns_c_hs |
||||
#define C_NONE ns_c_none |
||||
#define C_ANY ns_c_any |
||||
|
||||
#define T_A ns_t_a |
||||
#define T_NS ns_t_ns |
||||
#define T_MD ns_t_md |
||||
#define T_MF ns_t_mf |
||||
#define T_CNAME ns_t_cname |
||||
#define T_SOA ns_t_soa |
||||
#define T_MB ns_t_mb |
||||
#define T_MG ns_t_mg |
||||
#define T_MR ns_t_mr |
||||
#define T_NULL ns_t_null |
||||
#define T_WKS ns_t_wks |
||||
#define T_PTR ns_t_ptr |
||||
#define T_HINFO ns_t_hinfo |
||||
#define T_MINFO ns_t_minfo |
||||
#define T_MX ns_t_mx |
||||
#define T_TXT ns_t_txt |
||||
#define T_RP ns_t_rp |
||||
#define T_AFSDB ns_t_afsdb |
||||
#define T_X25 ns_t_x25 |
||||
#define T_ISDN ns_t_isdn |
||||
#define T_RT ns_t_rt |
||||
#define T_NSAP ns_t_nsap |
||||
#define T_NSAP_PTR ns_t_nsap_ptr |
||||
#define T_SIG ns_t_sig |
||||
#define T_KEY ns_t_key |
||||
#define T_PX ns_t_px |
||||
#define T_GPOS ns_t_gpos |
||||
#define T_AAAA ns_t_aaaa |
||||
#define T_LOC ns_t_loc |
||||
#define T_NXT ns_t_nxt |
||||
#define T_EID ns_t_eid |
||||
#define T_NIMLOC ns_t_nimloc |
||||
#define T_SRV ns_t_srv |
||||
#define T_ATMA ns_t_atma |
||||
#define T_NAPTR ns_t_naptr |
||||
#define T_TSIG ns_t_tsig |
||||
#define T_IXFR ns_t_ixfr |
||||
#define T_AXFR ns_t_axfr |
||||
#define T_MAILB ns_t_mailb |
||||
#define T_MAILA ns_t_maila |
||||
#define T_ANY ns_t_any |
@ -0,0 +1,2 @@ |
||||
# Microsoft Developer Studio Generated Dependency File, included by adig.mak |
||||
|
@ -0,0 +1,106 @@ |
||||
# Microsoft Developer Studio Project File - Name="adig" - Package Owner=<4> |
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00 |
||||
# ** DO NOT EDIT ** |
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103 |
||||
|
||||
CFG=adig - Win32 Debug |
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE, |
||||
!MESSAGE use the Export Makefile command and run |
||||
!MESSAGE |
||||
!MESSAGE NMAKE /f "adig.mak". |
||||
!MESSAGE |
||||
!MESSAGE You can specify a configuration when running NMAKE |
||||
!MESSAGE by defining the macro CFG on the command line. For example: |
||||
!MESSAGE |
||||
!MESSAGE NMAKE /f "adig.mak" CFG="adig - Win32 Debug" |
||||
!MESSAGE |
||||
!MESSAGE Possible choices for configuration are: |
||||
!MESSAGE |
||||
!MESSAGE "adig - Win32 Release" (based on "Win32 (x86) Console Application") |
||||
!MESSAGE "adig - Win32 Debug" (based on "Win32 (x86) Console Application") |
||||
!MESSAGE |
||||
|
||||
# Begin Project |
||||
# PROP AllowPerConfigDependencies 0 |
||||
# PROP Scc_ProjName "" |
||||
# PROP Scc_LocalPath "" |
||||
CPP=cl.exe |
||||
RSC=rc.exe |
||||
|
||||
!IF "$(CFG)" == "adig - Win32 Release" |
||||
|
||||
# PROP BASE Use_MFC 0 |
||||
# PROP BASE Use_Debug_Libraries 0 |
||||
# PROP BASE Output_Dir "Release" |
||||
# PROP BASE Intermediate_Dir "Release" |
||||
# PROP BASE Target_Dir "" |
||||
# PROP Use_MFC 0 |
||||
# PROP Use_Debug_Libraries 0 |
||||
# PROP Output_Dir "Release" |
||||
# PROP Intermediate_Dir "Release" |
||||
# PROP Ignore_Export_Lib 0 |
||||
# PROP Target_Dir "" |
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c |
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c |
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG" |
||||
# ADD RSC /l 0x409 /d "NDEBUG" |
||||
BSC32=bscmake.exe |
||||
# ADD BASE BSC32 /nologo |
||||
# ADD BSC32 /nologo |
||||
LINK32=link.exe |
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 |
||||
# ADD LINK32 wsock32.lib areslib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\areslib\Release" |
||||
|
||||
!ELSEIF "$(CFG)" == "adig - Win32 Debug" |
||||
|
||||
# PROP BASE Use_MFC 0 |
||||
# PROP BASE Use_Debug_Libraries 1 |
||||
# PROP BASE Output_Dir "Debug" |
||||
# PROP BASE Intermediate_Dir "Debug" |
||||
# PROP BASE Target_Dir "" |
||||
# PROP Use_MFC 0 |
||||
# PROP Use_Debug_Libraries 1 |
||||
# PROP Output_Dir "Debug" |
||||
# PROP Intermediate_Dir "Debug" |
||||
# PROP Ignore_Export_Lib 0 |
||||
# PROP Target_Dir "" |
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c |
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c |
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG" |
||||
# ADD RSC /l 0x409 /d "_DEBUG" |
||||
BSC32=bscmake.exe |
||||
# ADD BASE BSC32 /nologo |
||||
# ADD BSC32 /nologo |
||||
LINK32=link.exe |
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept |
||||
# ADD LINK32 wsock32.lib areslib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\areslib\Debug" |
||||
|
||||
!ENDIF |
||||
|
||||
# Begin Target |
||||
|
||||
# Name "adig - Win32 Release" |
||||
# Name "adig - Win32 Debug" |
||||
# Begin Group "Source Files" |
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\adig.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\getopt.c |
||||
# End Source File |
||||
# End Group |
||||
# Begin Group "Header Files" |
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl" |
||||
# End Group |
||||
# Begin Group "Resource Files" |
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" |
||||
# End Group |
||||
# End Target |
||||
# End Project |
@ -0,0 +1,213 @@ |
||||
# Microsoft Developer Studio Generated NMAKE File, Based on adig.dsp
|
||||
!IF "$(CFG)" == "" |
||||
CFG=adig - Win32 Debug
|
||||
!MESSAGE No configuration specified. Defaulting to adig - Win32 Debug. |
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" != "adig - Win32 Release" && "$(CFG)" != "adig - Win32 Debug" |
||||
!MESSAGE Invalid configuration "$(CFG)" specified. |
||||
!MESSAGE You can specify a configuration when running NMAKE |
||||
!MESSAGE by defining the macro CFG on the command line. For example: |
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "adig.mak" CFG="adig - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are: |
||||
!MESSAGE
|
||||
!MESSAGE "adig - Win32 Release" (based on "Win32 (x86) Console Application") |
||||
!MESSAGE "adig - Win32 Debug" (based on "Win32 (x86) Console Application") |
||||
!MESSAGE
|
||||
!ERROR An invalid configuration is specified. |
||||
!ENDIF
|
||||
|
||||
!IF "$(OS)" == "Windows_NT" |
||||
NULL=
|
||||
!ELSE
|
||||
NULL=nul
|
||||
!ENDIF
|
||||
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "adig - Win32 Release" |
||||
|
||||
OUTDIR=.\Release
|
||||
INTDIR=.\Release
|
||||
# Begin Custom Macros
|
||||
OutDir=.\Release
|
||||
# End Custom Macros
|
||||
|
||||
!IF "$(RECURSE)" == "0"
|
||||
|
||||
ALL : "$(OUTDIR)\adig.exe" |
||||
|
||||
!ELSE
|
||||
|
||||
ALL : "areslib - Win32 Release" "$(OUTDIR)\adig.exe" |
||||
|
||||
!ENDIF
|
||||
|
||||
!IF "$(RECURSE)" == "1"
|
||||
CLEAN :"areslib - Win32 ReleaseCLEAN" |
||||
!ELSE
|
||||
CLEAN : |
||||
!ENDIF
|
||||
-@erase "$(INTDIR)\adig.obj"
|
||||
-@erase "$(INTDIR)\getopt.obj"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(OUTDIR)\adig.exe"
|
||||
|
||||
"$(OUTDIR)" : |
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\adig.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\adig.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=wsock32.lib areslib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\adig.pdb" /machine:I386 /out:"$(OUTDIR)\adig.exe" /libpath:"..\areslib\Release"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\adig.obj" \
|
||||
"$(INTDIR)\getopt.obj" \
|
||||
"..\areslib\Release\areslib.lib"
|
||||
|
||||
"$(OUTDIR)\adig.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) |
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<< |
||||
|
||||
!ELSEIF "$(CFG)" == "adig - Win32 Debug" |
||||
|
||||
OUTDIR=.\Debug
|
||||
INTDIR=.\Debug
|
||||
# Begin Custom Macros
|
||||
OutDir=.\Debug
|
||||
# End Custom Macros
|
||||
|
||||
!IF "$(RECURSE)" == "0"
|
||||
|
||||
ALL : "$(OUTDIR)\adig.exe" |
||||
|
||||
!ELSE
|
||||
|
||||
ALL : "areslib - Win32 Debug" "$(OUTDIR)\adig.exe" |
||||
|
||||
!ENDIF
|
||||
|
||||
!IF "$(RECURSE)" == "1"
|
||||
CLEAN :"areslib - Win32 DebugCLEAN" |
||||
!ELSE
|
||||
CLEAN : |
||||
!ENDIF
|
||||
-@erase "$(INTDIR)\adig.obj"
|
||||
-@erase "$(INTDIR)\getopt.obj"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(INTDIR)\vc60.pdb"
|
||||
-@erase "$(OUTDIR)\adig.exe"
|
||||
-@erase "$(OUTDIR)\adig.ilk"
|
||||
-@erase "$(OUTDIR)\adig.pdb"
|
||||
|
||||
"$(OUTDIR)" : |
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP_PROJ=/nologo /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\adig.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\adig.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=wsock32.lib areslib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\adig.pdb" /debug /machine:I386 /out:"$(OUTDIR)\adig.exe" /pdbtype:sept /libpath:"..\areslib\Debug"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\adig.obj" \
|
||||
"$(INTDIR)\getopt.obj" \
|
||||
"..\areslib\Debug\areslib.lib"
|
||||
|
||||
"$(OUTDIR)\adig.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) |
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<< |
||||
|
||||
!ENDIF
|
||||
|
||||
.c{$(INTDIR)}.obj:: |
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<< |
||||
|
||||
.cpp{$(INTDIR)}.obj:: |
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<< |
||||
|
||||
.cxx{$(INTDIR)}.obj:: |
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<< |
||||
|
||||
.c{$(INTDIR)}.sbr:: |
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<< |
||||
|
||||
.cpp{$(INTDIR)}.sbr:: |
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<< |
||||
|
||||
.cxx{$(INTDIR)}.sbr:: |
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<< |
||||
|
||||
|
||||
!IF "$(NO_EXTERNAL_DEPS)" != "1" |
||||
!IF EXISTS("adig.dep") |
||||
!INCLUDE "adig.dep" |
||||
!ELSE
|
||||
!MESSAGE Warning: cannot find "adig.dep" |
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
|
||||
!IF "$(CFG)" == "adig - Win32 Release" || "$(CFG)" == "adig - Win32 Debug" |
||||
SOURCE=..\..\adig.c
|
||||
|
||||
"$(INTDIR)\adig.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\getopt.c
|
||||
|
||||
"$(INTDIR)\getopt.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
!IF "$(CFG)" == "adig - Win32 Release" |
||||
|
||||
"areslib - Win32 Release" :
|
||||
cd "\ARES-1.1.1\vc\areslib"
|
||||
$(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Release"
|
||||
cd "..\adig"
|
||||
|
||||
"areslib - Win32 ReleaseCLEAN" :
|
||||
cd "\ARES-1.1.1\vc\areslib"
|
||||
$(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Release" RECURSE=1 CLEAN
|
||||
cd "..\adig"
|
||||
|
||||
!ELSEIF "$(CFG)" == "adig - Win32 Debug" |
||||
|
||||
"areslib - Win32 Debug" :
|
||||
cd "\ARES-1.1.1\vc\areslib"
|
||||
$(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Debug"
|
||||
cd "..\adig"
|
||||
|
||||
"areslib - Win32 DebugCLEAN" :
|
||||
cd "\ARES-1.1.1\vc\areslib"
|
||||
$(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Debug" RECURSE=1 CLEAN
|
||||
cd "..\adig"
|
||||
|
||||
!ENDIF
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
@ -0,0 +1,77 @@ |
||||
<html> |
||||
<body> |
||||
<pre> |
||||
<h1>Build Log</h1> |
||||
<h3> |
||||
--------------------Configuration: areslib - Win32 Release-------------------- |
||||
</h3> |
||||
<h3>Command Lines</h3> |
||||
Creating temporary file "C:\DOCUME~1\liren\LOCALS~1\Temp\RSP615A.tmp" with contents |
||||
[ |
||||
/nologo /MD /W3 /GX /O2 /I "..\.." /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /Fp"Release/areslib.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c |
||||
"Z:\ARES-1.1.1\ares_gethostbyname.c" |
||||
"Z:\ARES-1.1.1\ares_init.c" |
||||
] |
||||
Creating command line "cl.exe @C:\DOCUME~1\liren\LOCALS~1\Temp\RSP615A.tmp" |
||||
Creating temporary file "C:\DOCUME~1\liren\LOCALS~1\Temp\RSP615B.tmp" with contents |
||||
[ |
||||
/nologo /out:"Release\areslib.lib" |
||||
".\Release\ares__close_sockets.obj" |
||||
".\Release\ares__get_hostent.obj" |
||||
".\Release\ares__read_line.obj" |
||||
".\Release\ares_destroy.obj" |
||||
".\Release\ares_expand_name.obj" |
||||
".\Release\ares_fds.obj" |
||||
".\Release\ares_free_errmem.obj" |
||||
".\Release\ares_free_hostent.obj" |
||||
".\Release\ares_free_string.obj" |
||||
".\Release\ares_gethostbyaddr.obj" |
||||
".\Release\ares_gethostbyname.obj" |
||||
".\Release\ares_init.obj" |
||||
".\Release\ares_mkquery.obj" |
||||
".\Release\ares_parse_a_reply.obj" |
||||
".\Release\ares_parse_ptr_reply.obj" |
||||
".\Release\ares_process.obj" |
||||
".\Release\ares_query.obj" |
||||
".\Release\ares_search.obj" |
||||
".\Release\ares_send.obj" |
||||
".\Release\ares_strerror.obj" |
||||
".\Release\ares_timeout.obj" |
||||
".\Release\windows_port.obj" |
||||
] |
||||
Creating command line "link.exe -lib @C:\DOCUME~1\liren\LOCALS~1\Temp\RSP615B.tmp" |
||||
<h3>Output Window</h3> |
||||
Compiling... |
||||
ares_gethostbyname.c |
||||
Z:\ARES-1.1.1\nameser.h(153) : warning C4005: 'NOERROR' : macro redefinition |
||||
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\winerror.h(8022) : see previous definition of 'NOERROR' |
||||
ares_init.c |
||||
Z:\ARES-1.1.1\nameser.h(153) : warning C4005: 'NOERROR' : macro redefinition |
||||
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\winerror.h(8022) : see previous definition of 'NOERROR' |
||||
Z:\ARES-1.1.1\ares_init.c(141) : warning C4013: '_getpid' undefined; assuming extern returning int |
||||
Z:\ARES-1.1.1\ares_init.c(236) : warning C4101: 'p' : unreferenced local variable |
||||
Z:\ARES-1.1.1\ares_init.c(237) : warning C4101: 'linesize' : unreferenced local variable |
||||
Z:\ARES-1.1.1\ares_init.c(235) : warning C4101: 'fp' : unreferenced local variable |
||||
Creating library... |
||||
<h3> |
||||
--------------------Configuration: adig - Win32 Release-------------------- |
||||
</h3> |
||||
<h3>Command Lines</h3> |
||||
Creating temporary file "C:\DOCUME~1\liren\LOCALS~1\Temp\RSP615C.tmp" with contents |
||||
[ |
||||
wsock32.lib areslib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /pdb:"Release/adig.pdb" /machine:I386 /out:"Release/adig.exe" /libpath:"..\areslib\Release" |
||||
".\Release\adig.obj" |
||||
".\Release\getopt.obj" |
||||
"\ARES-1.1.1\vc\areslib\Release\areslib.lib" |
||||
] |
||||
Creating command line "link.exe @C:\DOCUME~1\liren\LOCALS~1\Temp\RSP615C.tmp" |
||||
<h3>Output Window</h3> |
||||
Linking... |
||||
|
||||
|
||||
|
||||
<h3>Results</h3> |
||||
adig.exe - 0 error(s), 6 warning(s) |
||||
</pre> |
||||
</body> |
||||
</html> |
@ -0,0 +1,2 @@ |
||||
# Microsoft Developer Studio Generated Dependency File, included by ahost.mak |
||||
|
@ -0,0 +1,100 @@ |
||||
# Microsoft Developer Studio Project File - Name="ahost" - Package Owner=<4> |
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00 |
||||
# ** DO NOT EDIT ** |
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103 |
||||
|
||||
CFG=ahost - Win32 Debug |
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE, |
||||
!MESSAGE use the Export Makefile command and run |
||||
!MESSAGE |
||||
!MESSAGE NMAKE /f "ahost.mak". |
||||
!MESSAGE |
||||
!MESSAGE You can specify a configuration when running NMAKE |
||||
!MESSAGE by defining the macro CFG on the command line. For example: |
||||
!MESSAGE |
||||
!MESSAGE NMAKE /f "ahost.mak" CFG="ahost - Win32 Debug" |
||||
!MESSAGE |
||||
!MESSAGE Possible choices for configuration are: |
||||
!MESSAGE |
||||
!MESSAGE "ahost - Win32 Release" (based on "Win32 (x86) Console Application") |
||||
!MESSAGE "ahost - Win32 Debug" (based on "Win32 (x86) Console Application") |
||||
!MESSAGE |
||||
|
||||
# Begin Project |
||||
# PROP AllowPerConfigDependencies 0 |
||||
# PROP Scc_ProjName "" |
||||
# PROP Scc_LocalPath "" |
||||
CPP=cl.exe |
||||
RSC=rc.exe |
||||
|
||||
!IF "$(CFG)" == "ahost - Win32 Release" |
||||
|
||||
# PROP BASE Use_MFC 0 |
||||
# PROP BASE Use_Debug_Libraries 0 |
||||
# PROP BASE Output_Dir "Release" |
||||
# PROP BASE Intermediate_Dir "Release" |
||||
# PROP BASE Target_Dir "" |
||||
# PROP Use_MFC 0 |
||||
# PROP Use_Debug_Libraries 0 |
||||
# PROP Output_Dir "Release" |
||||
# PROP Intermediate_Dir "Release" |
||||
# PROP Target_Dir "" |
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c |
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c |
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG" |
||||
# ADD RSC /l 0x409 /d "NDEBUG" |
||||
BSC32=bscmake.exe |
||||
# ADD BASE BSC32 /nologo |
||||
# ADD BSC32 /nologo |
||||
LINK32=link.exe |
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 |
||||
# ADD LINK32 wsock32.lib areslib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\areslib\Release" |
||||
|
||||
!ELSEIF "$(CFG)" == "ahost - Win32 Debug" |
||||
|
||||
# PROP BASE Use_MFC 0 |
||||
# PROP BASE Use_Debug_Libraries 1 |
||||
# PROP BASE Output_Dir "Debug" |
||||
# PROP BASE Intermediate_Dir "Debug" |
||||
# PROP BASE Target_Dir "" |
||||
# PROP Use_MFC 0 |
||||
# PROP Use_Debug_Libraries 1 |
||||
# PROP Output_Dir "Debug" |
||||
# PROP Intermediate_Dir "Debug" |
||||
# PROP Target_Dir "" |
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c |
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c |
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG" |
||||
# ADD RSC /l 0x409 /d "_DEBUG" |
||||
BSC32=bscmake.exe |
||||
# ADD BASE BSC32 /nologo |
||||
# ADD BSC32 /nologo |
||||
LINK32=link.exe |
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept |
||||
# ADD LINK32 wsock32.lib areslib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\areslib\Debug" |
||||
|
||||
!ENDIF |
||||
|
||||
# Begin Target |
||||
|
||||
# Name "ahost - Win32 Release" |
||||
# Name "ahost - Win32 Debug" |
||||
# Begin Group "Source Files" |
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ahost.c |
||||
# End Source File |
||||
# End Group |
||||
# Begin Group "Header Files" |
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl" |
||||
# End Group |
||||
# Begin Group "Resource Files" |
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" |
||||
# End Group |
||||
# End Target |
||||
# End Project |
@ -0,0 +1,223 @@ |
||||
# Microsoft Developer Studio Generated NMAKE File, Based on ahost.dsp
|
||||
!IF "$(CFG)" == "" |
||||
CFG=ahost - Win32 Debug
|
||||
!MESSAGE No configuration specified. Defaulting to ahost - Win32 Debug. |
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" != "ahost - Win32 Release" && "$(CFG)" != "ahost - Win32 Debug" |
||||
!MESSAGE Invalid configuration "$(CFG)" specified. |
||||
!MESSAGE You can specify a configuration when running NMAKE |
||||
!MESSAGE by defining the macro CFG on the command line. For example: |
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "ahost.mak" CFG="ahost - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are: |
||||
!MESSAGE
|
||||
!MESSAGE "ahost - Win32 Release" (based on "Win32 (x86) Console Application") |
||||
!MESSAGE "ahost - Win32 Debug" (based on "Win32 (x86) Console Application") |
||||
!MESSAGE
|
||||
!ERROR An invalid configuration is specified. |
||||
!ENDIF
|
||||
|
||||
!IF "$(OS)" == "Windows_NT" |
||||
NULL=
|
||||
!ELSE
|
||||
NULL=nul
|
||||
!ENDIF
|
||||
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "ahost - Win32 Release" |
||||
|
||||
OUTDIR=.\Release
|
||||
INTDIR=.\Release
|
||||
# Begin Custom Macros
|
||||
OutDir=.\Release
|
||||
# End Custom Macros
|
||||
|
||||
!IF "$(RECURSE)" == "0"
|
||||
|
||||
ALL : "$(OUTDIR)\ahost.exe" |
||||
|
||||
!ELSE
|
||||
|
||||
ALL : "areslib - Win32 Release" "$(OUTDIR)\ahost.exe" |
||||
|
||||
!ENDIF
|
||||
|
||||
!IF "$(RECURSE)" == "1"
|
||||
CLEAN :"areslib - Win32 ReleaseCLEAN" |
||||
!ELSE
|
||||
CLEAN : |
||||
!ENDIF
|
||||
-@erase "$(INTDIR)\ahost.obj"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(OUTDIR)\ahost.exe"
|
||||
|
||||
"$(OUTDIR)" : |
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\ahost.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\ahost.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=wsock32.lib areslib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\ahost.pdb" /machine:I386 /out:"$(OUTDIR)\ahost.exe" /libpath:"..\areslib\Release"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\ahost.obj" \
|
||||
"..\areslib\Release\areslib.lib"
|
||||
|
||||
"$(OUTDIR)\ahost.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) |
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<< |
||||
|
||||
!ELSEIF "$(CFG)" == "ahost - Win32 Debug" |
||||
|
||||
OUTDIR=.\Debug
|
||||
INTDIR=.\Debug
|
||||
# Begin Custom Macros
|
||||
OutDir=.\Debug
|
||||
# End Custom Macros
|
||||
|
||||
!IF "$(RECURSE)" == "0"
|
||||
|
||||
ALL : "$(OUTDIR)\ahost.exe" "$(OUTDIR)\ahost.bsc" |
||||
|
||||
!ELSE
|
||||
|
||||
ALL : "areslib - Win32 Debug" "$(OUTDIR)\ahost.exe" "$(OUTDIR)\ahost.bsc" |
||||
|
||||
!ENDIF
|
||||
|
||||
!IF "$(RECURSE)" == "1"
|
||||
CLEAN :"areslib - Win32 DebugCLEAN" |
||||
!ELSE
|
||||
CLEAN : |
||||
!ENDIF
|
||||
-@erase "$(INTDIR)\ahost.obj"
|
||||
-@erase "$(INTDIR)\ahost.sbr"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(INTDIR)\vc60.pdb"
|
||||
-@erase "$(OUTDIR)\ahost.bsc"
|
||||
-@erase "$(OUTDIR)\ahost.exe"
|
||||
-@erase "$(OUTDIR)\ahost.ilk"
|
||||
-@erase "$(OUTDIR)\ahost.pdb"
|
||||
|
||||
"$(OUTDIR)" : |
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP_PROJ=/nologo /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\ahost.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\ahost.bsc"
|
||||
BSC32_SBRS= \
|
||||
"$(INTDIR)\ahost.sbr"
|
||||
|
||||
"$(OUTDIR)\ahost.bsc" : "$(OUTDIR)" $(BSC32_SBRS) |
||||
$(BSC32) @<<
|
||||
$(BSC32_FLAGS) $(BSC32_SBRS)
|
||||
<< |
||||
|
||||
LINK32=link.exe
|
||||
LINK32_FLAGS=wsock32.lib areslib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\ahost.pdb" /debug /machine:I386 /out:"$(OUTDIR)\ahost.exe" /pdbtype:sept /libpath:"..\areslib\Debug"
|
||||
LINK32_OBJS= \
|
||||
"$(INTDIR)\ahost.obj" \
|
||||
"..\areslib\Debug\areslib.lib"
|
||||
|
||||
"$(OUTDIR)\ahost.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) |
||||
$(LINK32) @<<
|
||||
$(LINK32_FLAGS) $(LINK32_OBJS)
|
||||
<< |
||||
|
||||
!ENDIF
|
||||
|
||||
.c{$(INTDIR)}.obj:: |
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<< |
||||
|
||||
.cpp{$(INTDIR)}.obj:: |
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<< |
||||
|
||||
.cxx{$(INTDIR)}.obj:: |
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<< |
||||
|
||||
.c{$(INTDIR)}.sbr:: |
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<< |
||||
|
||||
.cpp{$(INTDIR)}.sbr:: |
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<< |
||||
|
||||
.cxx{$(INTDIR)}.sbr:: |
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<< |
||||
|
||||
|
||||
!IF "$(NO_EXTERNAL_DEPS)" != "1" |
||||
!IF EXISTS("ahost.dep") |
||||
!INCLUDE "ahost.dep" |
||||
!ELSE
|
||||
!MESSAGE Warning: cannot find "ahost.dep" |
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
|
||||
!IF "$(CFG)" == "ahost - Win32 Release" || "$(CFG)" == "ahost - Win32 Debug" |
||||
SOURCE=..\..\ahost.c
|
||||
|
||||
!IF "$(CFG)" == "ahost - Win32 Release" |
||||
|
||||
|
||||
"$(INTDIR)\ahost.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
!ELSEIF "$(CFG)" == "ahost - Win32 Debug" |
||||
|
||||
|
||||
"$(INTDIR)\ahost.obj" "$(INTDIR)\ahost.sbr" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" == "ahost - Win32 Release" |
||||
|
||||
"areslib - Win32 Release" :
|
||||
cd "\ARES-1.1.1\vc\areslib"
|
||||
$(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Release"
|
||||
cd "..\ahost"
|
||||
|
||||
"areslib - Win32 ReleaseCLEAN" :
|
||||
cd "\ARES-1.1.1\vc\areslib"
|
||||
$(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Release" RECURSE=1 CLEAN
|
||||
cd "..\ahost"
|
||||
|
||||
!ELSEIF "$(CFG)" == "ahost - Win32 Debug" |
||||
|
||||
"areslib - Win32 Debug" :
|
||||
cd "\ARES-1.1.1\vc\areslib"
|
||||
$(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Debug"
|
||||
cd "..\ahost"
|
||||
|
||||
"areslib - Win32 DebugCLEAN" :
|
||||
cd "\ARES-1.1.1\vc\areslib"
|
||||
$(MAKE) /$(MAKEFLAGS) /F ".\areslib.mak" CFG="areslib - Win32 Debug" RECURSE=1 CLEAN
|
||||
cd "..\ahost"
|
||||
|
||||
!ENDIF
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
@ -0,0 +1,16 @@ |
||||
<html> |
||||
<body> |
||||
<pre> |
||||
<h1>Build Log</h1> |
||||
<h3> |
||||
--------------------Configuration: ahost - Win32 Release-------------------- |
||||
</h3> |
||||
<h3>Command Lines</h3> |
||||
|
||||
|
||||
|
||||
<h3>Results</h3> |
||||
ahost.exe - 0 error(s), 0 warning(s) |
||||
</pre> |
||||
</body> |
||||
</html> |
@ -0,0 +1,2 @@ |
||||
# Microsoft Developer Studio Generated Dependency File, included by areslib.mak |
||||
|
@ -0,0 +1,196 @@ |
||||
# Microsoft Developer Studio Project File - Name="areslib" - Package Owner=<4> |
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00 |
||||
# ** DO NOT EDIT ** |
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104 |
||||
|
||||
CFG=areslib - Win32 Debug |
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE, |
||||
!MESSAGE use the Export Makefile command and run |
||||
!MESSAGE |
||||
!MESSAGE NMAKE /f "areslib.mak". |
||||
!MESSAGE |
||||
!MESSAGE You can specify a configuration when running NMAKE |
||||
!MESSAGE by defining the macro CFG on the command line. For example: |
||||
!MESSAGE |
||||
!MESSAGE NMAKE /f "areslib.mak" CFG="areslib - Win32 Debug" |
||||
!MESSAGE |
||||
!MESSAGE Possible choices for configuration are: |
||||
!MESSAGE |
||||
!MESSAGE "areslib - Win32 Release" (based on "Win32 (x86) Static Library") |
||||
!MESSAGE "areslib - Win32 Debug" (based on "Win32 (x86) Static Library") |
||||
!MESSAGE |
||||
|
||||
# Begin Project |
||||
# PROP AllowPerConfigDependencies 0 |
||||
# PROP Scc_ProjName "" |
||||
# PROP Scc_LocalPath "" |
||||
CPP=cl.exe |
||||
RSC=rc.exe |
||||
|
||||
!IF "$(CFG)" == "areslib - Win32 Release" |
||||
|
||||
# PROP BASE Use_MFC 0 |
||||
# PROP BASE Use_Debug_Libraries 0 |
||||
# PROP BASE Output_Dir "Release" |
||||
# PROP BASE Intermediate_Dir "Release" |
||||
# PROP BASE Target_Dir "" |
||||
# PROP Use_MFC 0 |
||||
# PROP Use_Debug_Libraries 0 |
||||
# PROP Output_Dir "Release" |
||||
# PROP Intermediate_Dir "Release" |
||||
# PROP Target_Dir "" |
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c |
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c |
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG" |
||||
# ADD RSC /l 0x409 /d "NDEBUG" |
||||
BSC32=bscmake.exe |
||||
# ADD BASE BSC32 /nologo |
||||
# ADD BSC32 /nologo |
||||
LIB32=link.exe -lib |
||||
# ADD BASE LIB32 /nologo |
||||
# ADD LIB32 /nologo |
||||
|
||||
!ELSEIF "$(CFG)" == "areslib - Win32 Debug" |
||||
|
||||
# PROP BASE Use_MFC 0 |
||||
# PROP BASE Use_Debug_Libraries 1 |
||||
# PROP BASE Output_Dir "Debug" |
||||
# PROP BASE Intermediate_Dir "Debug" |
||||
# PROP BASE Target_Dir "" |
||||
# PROP Use_MFC 0 |
||||
# PROP Use_Debug_Libraries 1 |
||||
# PROP Output_Dir "Debug" |
||||
# PROP Intermediate_Dir "Debug" |
||||
# PROP Target_Dir "" |
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c |
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\.." /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c |
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG" |
||||
# ADD RSC /l 0x409 /d "_DEBUG" |
||||
BSC32=bscmake.exe |
||||
# ADD BASE BSC32 /nologo |
||||
# ADD BSC32 /nologo |
||||
LIB32=link.exe -lib |
||||
# ADD BASE LIB32 /nologo |
||||
# ADD LIB32 /nologo |
||||
|
||||
!ENDIF |
||||
|
||||
# Begin Target |
||||
|
||||
# Name "areslib - Win32 Release" |
||||
# Name "areslib - Win32 Debug" |
||||
# Begin Group "Source Files" |
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares__close_sockets.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares__get_hostent.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares__read_line.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_destroy.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_expand_name.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_fds.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_free_errmem.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_free_hostent.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_free_string.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_gethostbyaddr.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_gethostbyname.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_init.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_mkquery.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_parse_a_reply.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_parse_ptr_reply.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_process.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_query.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_search.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_send.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_strerror.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_timeout.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\windows_port.c |
||||
# End Source File |
||||
# End Group |
||||
# Begin Group "Header Files" |
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl" |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares.h |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_dns.h |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\ares_private.h |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=..\..\nameser.h |
||||
# End Source File |
||||
# End Group |
||||
# End Target |
||||
# End Project |
@ -0,0 +1,361 @@ |
||||
# Microsoft Developer Studio Generated NMAKE File, Based on areslib.dsp
|
||||
!IF "$(CFG)" == "" |
||||
CFG=areslib - Win32 Debug
|
||||
!MESSAGE No configuration specified. Defaulting to areslib - Win32 Debug. |
||||
!ENDIF
|
||||
|
||||
!IF "$(CFG)" != "areslib - Win32 Release" && "$(CFG)" != "areslib - Win32 Debug" |
||||
!MESSAGE Invalid configuration "$(CFG)" specified. |
||||
!MESSAGE You can specify a configuration when running NMAKE |
||||
!MESSAGE by defining the macro CFG on the command line. For example: |
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "areslib.mak" CFG="areslib - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are: |
||||
!MESSAGE
|
||||
!MESSAGE "areslib - Win32 Release" (based on "Win32 (x86) Static Library") |
||||
!MESSAGE "areslib - Win32 Debug" (based on "Win32 (x86) Static Library") |
||||
!MESSAGE
|
||||
!ERROR An invalid configuration is specified. |
||||
!ENDIF
|
||||
|
||||
!IF "$(OS)" == "Windows_NT" |
||||
NULL=
|
||||
!ELSE
|
||||
NULL=nul
|
||||
!ENDIF
|
||||
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "areslib - Win32 Release" |
||||
|
||||
OUTDIR=.\Release
|
||||
INTDIR=.\Release
|
||||
# Begin Custom Macros
|
||||
OutDir=.\Release
|
||||
# End Custom Macros
|
||||
|
||||
ALL : "$(OUTDIR)\areslib.lib" |
||||
|
||||
|
||||
CLEAN : |
||||
-@erase "$(INTDIR)\ares__close_sockets.obj"
|
||||
-@erase "$(INTDIR)\ares__get_hostent.obj"
|
||||
-@erase "$(INTDIR)\ares__read_line.obj"
|
||||
-@erase "$(INTDIR)\ares_destroy.obj"
|
||||
-@erase "$(INTDIR)\ares_expand_name.obj"
|
||||
-@erase "$(INTDIR)\ares_fds.obj"
|
||||
-@erase "$(INTDIR)\ares_free_errmem.obj"
|
||||
-@erase "$(INTDIR)\ares_free_hostent.obj"
|
||||
-@erase "$(INTDIR)\ares_free_string.obj"
|
||||
-@erase "$(INTDIR)\ares_gethostbyaddr.obj"
|
||||
-@erase "$(INTDIR)\ares_gethostbyname.obj"
|
||||
-@erase "$(INTDIR)\ares_init.obj"
|
||||
-@erase "$(INTDIR)\ares_mkquery.obj"
|
||||
-@erase "$(INTDIR)\ares_parse_a_reply.obj"
|
||||
-@erase "$(INTDIR)\ares_parse_ptr_reply.obj"
|
||||
-@erase "$(INTDIR)\ares_process.obj"
|
||||
-@erase "$(INTDIR)\ares_query.obj"
|
||||
-@erase "$(INTDIR)\ares_search.obj"
|
||||
-@erase "$(INTDIR)\ares_send.obj"
|
||||
-@erase "$(INTDIR)\ares_strerror.obj"
|
||||
-@erase "$(INTDIR)\ares_timeout.obj"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(INTDIR)\windows_port.obj"
|
||||
-@erase "$(OUTDIR)\areslib.lib"
|
||||
|
||||
"$(OUTDIR)" : |
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP_PROJ=/nologo /MD /W3 /GX /O2 /I "..\.." /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /Fp"$(INTDIR)\areslib.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\areslib.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LIB32=link.exe -lib
|
||||
LIB32_FLAGS=/nologo /out:"$(OUTDIR)\areslib.lib"
|
||||
LIB32_OBJS= \
|
||||
"$(INTDIR)\ares__close_sockets.obj" \
|
||||
"$(INTDIR)\ares__get_hostent.obj" \
|
||||
"$(INTDIR)\ares__read_line.obj" \
|
||||
"$(INTDIR)\ares_destroy.obj" \
|
||||
"$(INTDIR)\ares_expand_name.obj" \
|
||||
"$(INTDIR)\ares_fds.obj" \
|
||||
"$(INTDIR)\ares_free_errmem.obj" \
|
||||
"$(INTDIR)\ares_free_hostent.obj" \
|
||||
"$(INTDIR)\ares_free_string.obj" \
|
||||
"$(INTDIR)\ares_gethostbyaddr.obj" \
|
||||
"$(INTDIR)\ares_gethostbyname.obj" \
|
||||
"$(INTDIR)\ares_init.obj" \
|
||||
"$(INTDIR)\ares_mkquery.obj" \
|
||||
"$(INTDIR)\ares_parse_a_reply.obj" \
|
||||
"$(INTDIR)\ares_parse_ptr_reply.obj" \
|
||||
"$(INTDIR)\ares_process.obj" \
|
||||
"$(INTDIR)\ares_query.obj" \
|
||||
"$(INTDIR)\ares_search.obj" \
|
||||
"$(INTDIR)\ares_send.obj" \
|
||||
"$(INTDIR)\ares_strerror.obj" \
|
||||
"$(INTDIR)\ares_timeout.obj" \
|
||||
"$(INTDIR)\windows_port.obj"
|
||||
|
||||
"$(OUTDIR)\areslib.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) |
||||
$(LIB32) @<<
|
||||
$(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS)
|
||||
<< |
||||
|
||||
!ELSEIF "$(CFG)" == "areslib - Win32 Debug" |
||||
|
||||
OUTDIR=.\Debug
|
||||
INTDIR=.\Debug
|
||||
# Begin Custom Macros
|
||||
OutDir=.\Debug
|
||||
# End Custom Macros
|
||||
|
||||
ALL : "$(OUTDIR)\areslib.lib" |
||||
|
||||
|
||||
CLEAN : |
||||
-@erase "$(INTDIR)\ares__close_sockets.obj"
|
||||
-@erase "$(INTDIR)\ares__get_hostent.obj"
|
||||
-@erase "$(INTDIR)\ares__read_line.obj"
|
||||
-@erase "$(INTDIR)\ares_destroy.obj"
|
||||
-@erase "$(INTDIR)\ares_expand_name.obj"
|
||||
-@erase "$(INTDIR)\ares_fds.obj"
|
||||
-@erase "$(INTDIR)\ares_free_errmem.obj"
|
||||
-@erase "$(INTDIR)\ares_free_hostent.obj"
|
||||
-@erase "$(INTDIR)\ares_free_string.obj"
|
||||
-@erase "$(INTDIR)\ares_gethostbyaddr.obj"
|
||||
-@erase "$(INTDIR)\ares_gethostbyname.obj"
|
||||
-@erase "$(INTDIR)\ares_init.obj"
|
||||
-@erase "$(INTDIR)\ares_mkquery.obj"
|
||||
-@erase "$(INTDIR)\ares_parse_a_reply.obj"
|
||||
-@erase "$(INTDIR)\ares_parse_ptr_reply.obj"
|
||||
-@erase "$(INTDIR)\ares_process.obj"
|
||||
-@erase "$(INTDIR)\ares_query.obj"
|
||||
-@erase "$(INTDIR)\ares_search.obj"
|
||||
-@erase "$(INTDIR)\ares_send.obj"
|
||||
-@erase "$(INTDIR)\ares_strerror.obj"
|
||||
-@erase "$(INTDIR)\ares_timeout.obj"
|
||||
-@erase "$(INTDIR)\vc60.idb"
|
||||
-@erase "$(INTDIR)\vc60.pdb"
|
||||
-@erase "$(INTDIR)\windows_port.obj"
|
||||
-@erase "$(OUTDIR)\areslib.lib"
|
||||
|
||||
"$(OUTDIR)" : |
||||
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
|
||||
|
||||
CPP_PROJ=/nologo /MLd /W3 /Gm /GX /ZI /Od /I "..\.." /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /Fp"$(INTDIR)\areslib.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
|
||||
BSC32=bscmake.exe
|
||||
BSC32_FLAGS=/nologo /o"$(OUTDIR)\areslib.bsc"
|
||||
BSC32_SBRS= \
|
||||
|
||||
LIB32=link.exe -lib
|
||||
LIB32_FLAGS=/nologo /out:"$(OUTDIR)\areslib.lib"
|
||||
LIB32_OBJS= \
|
||||
"$(INTDIR)\ares__close_sockets.obj" \
|
||||
"$(INTDIR)\ares__get_hostent.obj" \
|
||||
"$(INTDIR)\ares__read_line.obj" \
|
||||
"$(INTDIR)\ares_destroy.obj" \
|
||||
"$(INTDIR)\ares_expand_name.obj" \
|
||||
"$(INTDIR)\ares_fds.obj" \
|
||||
"$(INTDIR)\ares_free_errmem.obj" \
|
||||
"$(INTDIR)\ares_free_hostent.obj" \
|
||||
"$(INTDIR)\ares_free_string.obj" \
|
||||
"$(INTDIR)\ares_gethostbyaddr.obj" \
|
||||
"$(INTDIR)\ares_gethostbyname.obj" \
|
||||
"$(INTDIR)\ares_init.obj" \
|
||||
"$(INTDIR)\ares_mkquery.obj" \
|
||||
"$(INTDIR)\ares_parse_a_reply.obj" \
|
||||
"$(INTDIR)\ares_parse_ptr_reply.obj" \
|
||||
"$(INTDIR)\ares_process.obj" \
|
||||
"$(INTDIR)\ares_query.obj" \
|
||||
"$(INTDIR)\ares_search.obj" \
|
||||
"$(INTDIR)\ares_send.obj" \
|
||||
"$(INTDIR)\ares_strerror.obj" \
|
||||
"$(INTDIR)\ares_timeout.obj" \
|
||||
"$(INTDIR)\windows_port.obj"
|
||||
|
||||
"$(OUTDIR)\areslib.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) |
||||
$(LIB32) @<<
|
||||
$(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS)
|
||||
<< |
||||
|
||||
!ENDIF
|
||||
|
||||
.c{$(INTDIR)}.obj:: |
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<< |
||||
|
||||
.cpp{$(INTDIR)}.obj:: |
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<< |
||||
|
||||
.cxx{$(INTDIR)}.obj:: |
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<< |
||||
|
||||
.c{$(INTDIR)}.sbr:: |
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<< |
||||
|
||||
.cpp{$(INTDIR)}.sbr:: |
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<< |
||||
|
||||
.cxx{$(INTDIR)}.sbr:: |
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<< |
||||
|
||||
|
||||
!IF "$(NO_EXTERNAL_DEPS)" != "1" |
||||
!IF EXISTS("areslib.dep") |
||||
!INCLUDE "areslib.dep" |
||||
!ELSE
|
||||
!MESSAGE Warning: cannot find "areslib.dep" |
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
|
||||
!IF "$(CFG)" == "areslib - Win32 Release" || "$(CFG)" == "areslib - Win32 Debug" |
||||
SOURCE=..\..\ares__close_sockets.c
|
||||
|
||||
"$(INTDIR)\ares__close_sockets.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares__get_hostent.c
|
||||
|
||||
"$(INTDIR)\ares__get_hostent.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares__read_line.c
|
||||
|
||||
"$(INTDIR)\ares__read_line.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares_destroy.c
|
||||
|
||||
"$(INTDIR)\ares_destroy.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares_expand_name.c
|
||||
|
||||
"$(INTDIR)\ares_expand_name.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares_fds.c
|
||||
|
||||
"$(INTDIR)\ares_fds.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares_free_errmem.c
|
||||
|
||||
"$(INTDIR)\ares_free_errmem.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares_free_hostent.c
|
||||
|
||||
"$(INTDIR)\ares_free_hostent.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares_free_string.c
|
||||
|
||||
"$(INTDIR)\ares_free_string.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares_gethostbyaddr.c
|
||||
|
||||
"$(INTDIR)\ares_gethostbyaddr.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares_gethostbyname.c
|
||||
|
||||
"$(INTDIR)\ares_gethostbyname.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares_init.c
|
||||
|
||||
"$(INTDIR)\ares_init.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares_mkquery.c
|
||||
|
||||
"$(INTDIR)\ares_mkquery.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares_parse_a_reply.c
|
||||
|
||||
"$(INTDIR)\ares_parse_a_reply.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares_parse_ptr_reply.c
|
||||
|
||||
"$(INTDIR)\ares_parse_ptr_reply.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares_process.c
|
||||
|
||||
"$(INTDIR)\ares_process.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares_query.c
|
||||
|
||||
"$(INTDIR)\ares_query.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares_search.c
|
||||
|
||||
"$(INTDIR)\ares_search.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares_send.c
|
||||
|
||||
"$(INTDIR)\ares_send.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares_strerror.c
|
||||
|
||||
"$(INTDIR)\ares_strerror.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\ares_timeout.c
|
||||
|
||||
"$(INTDIR)\ares_timeout.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
SOURCE=..\..\windows_port.c
|
||||
|
||||
"$(INTDIR)\windows_port.obj" : $(SOURCE) "$(INTDIR)" |
||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||
|
||||
|
||||
|
||||
!ENDIF
|
||||
|
@ -0,0 +1,125 @@ |
||||
<html> |
||||
<body> |
||||
<pre> |
||||
<h1>Build Log</h1> |
||||
<h3> |
||||
--------------------Configuration: areslib - Win32 Release-------------------- |
||||
</h3> |
||||
<h3>Command Lines</h3> |
||||
Creating temporary file "C:\DOCUME~1\liren\LOCALS~1\Temp\RSP603D.tmp" with contents |
||||
[ |
||||
/nologo /MD /W3 /GX /O2 /I "..\.." /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /Fp"Release/areslib.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c |
||||
"Z:\ares-1.1.1\ares__close_sockets.c" |
||||
"Z:\ares-1.1.1\ares__get_hostent.c" |
||||
"Z:\ares-1.1.1\ares__read_line.c" |
||||
"Z:\ares-1.1.1\ares_destroy.c" |
||||
"Z:\ares-1.1.1\ares_expand_name.c" |
||||
"Z:\ares-1.1.1\ares_fds.c" |
||||
"Z:\ares-1.1.1\ares_free_errmem.c" |
||||
"Z:\ares-1.1.1\ares_free_hostent.c" |
||||
"Z:\ares-1.1.1\ares_free_string.c" |
||||
"Z:\ares-1.1.1\ares_gethostbyaddr.c" |
||||
"Z:\ares-1.1.1\ares_gethostbyname.c" |
||||
"Z:\ares-1.1.1\ares_init.c" |
||||
"Z:\ares-1.1.1\ares_mkquery.c" |
||||
"Z:\ares-1.1.1\ares_parse_a_reply.c" |
||||
"Z:\ares-1.1.1\ares_parse_ptr_reply.c" |
||||
"Z:\ares-1.1.1\ares_process.c" |
||||
"Z:\ares-1.1.1\ares_query.c" |
||||
"Z:\ares-1.1.1\ares_search.c" |
||||
"Z:\ares-1.1.1\ares_send.c" |
||||
"Z:\ares-1.1.1\ares_strerror.c" |
||||
"Z:\ares-1.1.1\ares_timeout.c" |
||||
"Z:\ares-1.1.1\windows_port.c" |
||||
] |
||||
Creating command line "cl.exe @C:\DOCUME~1\liren\LOCALS~1\Temp\RSP603D.tmp" |
||||
Creating temporary file "C:\DOCUME~1\liren\LOCALS~1\Temp\RSP603E.tmp" with contents |
||||
[ |
||||
/nologo /out:"Release\areslib.lib" |
||||
".\Release\ares__close_sockets.obj" |
||||
".\Release\ares__get_hostent.obj" |
||||
".\Release\ares__read_line.obj" |
||||
".\Release\ares_destroy.obj" |
||||
".\Release\ares_expand_name.obj" |
||||
".\Release\ares_fds.obj" |
||||
".\Release\ares_free_errmem.obj" |
||||
".\Release\ares_free_hostent.obj" |
||||
".\Release\ares_free_string.obj" |
||||
".\Release\ares_gethostbyaddr.obj" |
||||
".\Release\ares_gethostbyname.obj" |
||||
".\Release\ares_init.obj" |
||||
".\Release\ares_mkquery.obj" |
||||
".\Release\ares_parse_a_reply.obj" |
||||
".\Release\ares_parse_ptr_reply.obj" |
||||
".\Release\ares_process.obj" |
||||
".\Release\ares_query.obj" |
||||
".\Release\ares_search.obj" |
||||
".\Release\ares_send.obj" |
||||
".\Release\ares_strerror.obj" |
||||
".\Release\ares_timeout.obj" |
||||
".\Release\windows_port.obj" |
||||
] |
||||
Creating command line "link.exe -lib @C:\DOCUME~1\liren\LOCALS~1\Temp\RSP603E.tmp" |
||||
<h3>Output Window</h3> |
||||
Compiling... |
||||
ares__close_sockets.c |
||||
Z:\ares-1.1.1\ares__close_sockets.c(46) : warning C4013: 'close' undefined; assuming extern returning int |
||||
ares__get_hostent.c |
||||
ares__read_line.c |
||||
ares_destroy.c |
||||
ares_expand_name.c |
||||
Z:\ares-1.1.1\nameser.h(153) : warning C4005: 'NOERROR' : macro redefinition |
||||
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\winerror.h(8022) : see previous definition of 'NOERROR' |
||||
ares_fds.c |
||||
ares_free_errmem.c |
||||
ares_free_hostent.c |
||||
ares_free_string.c |
||||
ares_gethostbyaddr.c |
||||
Z:\ares-1.1.1\nameser.h(153) : warning C4005: 'NOERROR' : macro redefinition |
||||
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\winerror.h(8022) : see previous definition of 'NOERROR' |
||||
ares_gethostbyname.c |
||||
Z:\ares-1.1.1\nameser.h(153) : warning C4005: 'NOERROR' : macro redefinition |
||||
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\winerror.h(8022) : see previous definition of 'NOERROR' |
||||
ares_init.c |
||||
Z:\ares-1.1.1\nameser.h(153) : warning C4005: 'NOERROR' : macro redefinition |
||||
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\winerror.h(8022) : see previous definition of 'NOERROR' |
||||
Z:\ares-1.1.1\ares_init.c(141) : warning C4013: '_getpid' undefined; assuming extern returning int |
||||
Z:\ares-1.1.1\ares_init.c(236) : warning C4101: 'p' : unreferenced local variable |
||||
Z:\ares-1.1.1\ares_init.c(237) : warning C4101: 'linesize' : unreferenced local variable |
||||
Z:\ares-1.1.1\ares_init.c(235) : warning C4101: 'fp' : unreferenced local variable |
||||
ares_mkquery.c |
||||
Z:\ares-1.1.1\nameser.h(153) : warning C4005: 'NOERROR' : macro redefinition |
||||
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\winerror.h(8022) : see previous definition of 'NOERROR' |
||||
ares_parse_a_reply.c |
||||
Z:\ares-1.1.1\nameser.h(153) : warning C4005: 'NOERROR' : macro redefinition |
||||
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\winerror.h(8022) : see previous definition of 'NOERROR' |
||||
Z:\ares-1.1.1\ares_parse_a_reply.c(90) : warning C4018: '<' : signed/unsigned mismatch |
||||
ares_parse_ptr_reply.c |
||||
Z:\ares-1.1.1\nameser.h(153) : warning C4005: 'NOERROR' : macro redefinition |
||||
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\winerror.h(8022) : see previous definition of 'NOERROR' |
||||
Z:\ares-1.1.1\ares_parse_ptr_reply.c(71) : warning C4018: '<' : signed/unsigned mismatch |
||||
ares_process.c |
||||
Z:\ares-1.1.1\nameser.h(153) : warning C4005: 'NOERROR' : macro redefinition |
||||
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\winerror.h(8022) : see previous definition of 'NOERROR' |
||||
ares_query.c |
||||
Z:\ares-1.1.1\nameser.h(153) : warning C4005: 'NOERROR' : macro redefinition |
||||
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\winerror.h(8022) : see previous definition of 'NOERROR' |
||||
ares_search.c |
||||
Z:\ares-1.1.1\ares_search.c(229) : warning C4013: 'strncasecmp' undefined; assuming extern returning int |
||||
ares_send.c |
||||
Z:\ares-1.1.1\nameser.h(153) : warning C4005: 'NOERROR' : macro redefinition |
||||
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\winerror.h(8022) : see previous definition of 'NOERROR' |
||||
ares_strerror.c |
||||
ares_timeout.c |
||||
windows_port.c |
||||
Z:\ares-1.1.1\nameser.h(153) : warning C4005: 'NOERROR' : macro redefinition |
||||
C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\winerror.h(8022) : see previous definition of 'NOERROR' |
||||
Creating library... |
||||
|
||||
|
||||
|
||||
<h3>Results</h3> |
||||
areslib.lib - 0 error(s), 19 warning(s) |
||||
</pre> |
||||
</body> |
||||
</html> |
@ -0,0 +1,59 @@ |
||||
Microsoft Developer Studio Workspace File, Format Version 6.00 |
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! |
||||
|
||||
############################################################################### |
||||
|
||||
Project: "adig"=".\adig\adig.dsp" - Package Owner=<4> |
||||
|
||||
Package=<5> |
||||
{{{ |
||||
}}} |
||||
|
||||
Package=<4> |
||||
{{{ |
||||
Begin Project Dependency |
||||
Project_Dep_Name areslib |
||||
End Project Dependency |
||||
}}} |
||||
|
||||
############################################################################### |
||||
|
||||
Project: "ahost"=".\ahost\ahost.dsp" - Package Owner=<4> |
||||
|
||||
Package=<5> |
||||
{{{ |
||||
}}} |
||||
|
||||
Package=<4> |
||||
{{{ |
||||
Begin Project Dependency |
||||
Project_Dep_Name areslib |
||||
End Project Dependency |
||||
}}} |
||||
|
||||
############################################################################### |
||||
|
||||
Project: "areslib"=".\areslib\areslib.dsp" - Package Owner=<4> |
||||
|
||||
Package=<5> |
||||
{{{ |
||||
}}} |
||||
|
||||
Package=<4> |
||||
{{{ |
||||
}}} |
||||
|
||||
############################################################################### |
||||
|
||||
Global: |
||||
|
||||
Package=<5> |
||||
{{{ |
||||
}}} |
||||
|
||||
Package=<3> |
||||
{{{ |
||||
}}} |
||||
|
||||
############################################################################### |
||||
|
@ -0,0 +1,61 @@ |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <ctype.h> |
||||
#include <string.h> |
||||
|
||||
#include "nameser.h" |
||||
|
||||
int |
||||
strncasecmp(const char *a, const char *b, size_t n) |
||||
{ |
||||
size_t i; |
||||
|
||||
for (i = 0; i < n; i++) { |
||||
int c1 = isupper(a[i]) ? tolower(a[i]) : a[i]; |
||||
int c2 = isupper(b[i]) ? tolower(b[i]) : b[i]; |
||||
if (c1 != c2) return c1-c2; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
int |
||||
strcasecmp(const char *a, const char *b) |
||||
{ |
||||
return strncasecmp(a, b, strlen(a)+1); |
||||
} |
||||
|
||||
int
|
||||
gettimeofday(struct timeval *tv, struct timezone *tz)
|
||||
{ |
||||
FILETIME ft; |
||||
LARGE_INTEGER li; |
||||
__int64 t; |
||||
static int tzflag; |
||||
|
||||
if (tv) |
||||
{ |
||||
GetSystemTimeAsFileTime(&ft); |
||||
li.LowPart = ft.dwLowDateTime; |
||||
li.HighPart = ft.dwHighDateTime; |
||||
t = li.QuadPart; /* In 100-nanosecond intervals */ |
||||
//t -= EPOCHFILETIME; /* Offset to the Epoch time */
|
||||
t /= 10; /* In microseconds */ |
||||
tv->tv_sec = (long)(t / 1000000); |
||||
tv->tv_usec = (long)(t % 1000000); |
||||
} |
||||
|
||||
#if 0 |
||||
if (tz) |
||||
{ |
||||
if (!tzflag) |
||||
{ |
||||
_tzset(); |
||||
tzflag++; |
||||
} |
||||
tz->tz_minuteswest = _timezone / 60; |
||||
tz->tz_dsttime = _daylight; |
||||
} |
||||
#endif |
||||
|
||||
return 0; |
||||
} |
Loading…
Reference in new issue