ares 1.1.1 with collected applied patches

This commit is contained in:
Daniel Stenberg 2003-10-07 21:54:04 +00:00
parent 6494889e3b
commit 0436fbe226
70 changed files with 11352 additions and 0 deletions

9
ares/CHANGES Normal file
View File

@ -0,0 +1,9 @@
- James Bursa made it run on RISC OS
- Dominick Meglio made it run fine on NT4
- Duncan Wilcox made it fine on Mac OS X
- Daniel Stenberg adjusted the windows port
- liren at vivisimo.com made the initial windows port

87
ares/Makefile.in Normal file
View File

@ -0,0 +1,87 @@
# $Id$
SHELL=/bin/sh
INSTALL=@INSTALL@
RANLIB=@RANLIB@
VPATH=@srcdir@
srcdir=@srcdir@
top_srcdir=@top_srcdir@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
mandir=@mandir@
CC=@CC@
CPPFLAGS=@CPPFLAGS@
CFLAGS=@CFLAGS@ ${WARN_CFLAGS} ${ERROR_CFLAGS}
DEFS=@DEFS@
LDFLAGS=@LDFLAGS@
LIBS=@LIBS@
ALL_CFLAGS=${CPPFLAGS} ${CFLAGS} ${DEFS}
OBJS= ares__close_sockets.o ares__get_hostent.o ares__read_line.o \
ares_destroy.o ares_expand_name.o ares_fds.o ares_free_errmem.o \
ares_free_hostent.o ares_free_string.o ares_gethostbyaddr.o \
ares_gethostbyname.o ares_init.o ares_mkquery.o ares_parse_a_reply.o \
ares_parse_ptr_reply.o ares_process.o ares_query.o ares_search.o \
ares_send.o ares_strerror.o ares_timeout.o
all: libares.a adig ahost
libares.a: ${OBJS}
ar cru $@ ${OBJS}
${RANLIB} $@
adig: adig.o libares.a
${CC} ${LDFLAGS} -o $@ adig.o libares.a ${LIBS}
ahost: ahost.o libares.a
${CC} ${LDFLAGS} -o $@ ahost.o libares.a ${LIBS}
${OBJS}: ares.h ares_dns.h ares_private.h
.c.o:
${CC} -c ${ALL_CFLAGS} $<
check:
install:
${top_srcdir}/mkinstalldirs ${DESTDIR}${libdir}
${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}
${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man3
${INSTALL} -m 644 libares.a ${DESTDIR}${libdir}
${RANLIB} ${DESTDIR}${libdir}/libares.a
chmod u-w ${DESTDIR}${libdir}/libares.a
${INSTALL} -m 444 ${srcdir}/ares.h ${DESTDIR}${includedir}
${INSTALL} -m 444 ${srcdir}/ares_destroy.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_expand_name.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_fds.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_free_errmem.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_free_hostent.3 \
${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_free_string.3 \
${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_gethostbyaddr.3 \
${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_gethostbyname.3 \
${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_init.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_init_options.3 \
${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_mkquery.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_parse_a_reply.3 \
${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_parse_ptr_reply.3 \
${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_process.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_query.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_search.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_send.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_strerror.3 ${DESTDIR}${mandir}/man3
${INSTALL} -m 444 ${srcdir}/ares_timeout.3 ${DESTDIR}${mandir}/man3
clean:
rm -f ${OBJS} libares.a adig.o adig ahost.o ahost
distclean: clean
rm -f config.cache config.log config.status Makefile

18
ares/NEWS Normal file
View File

@ -0,0 +1,18 @@
Major changes in release 1.1.1:
* ares should now compile as C++ code (no longer uses reserved word
"class").
* Added SRV support to adig test program.
* Fixed a few error handling bugs in query processing.
Major changes in release 1.1.0:
* Added ares_free_string() function so that memory can be freed in the
same layer as it is allocated, a desirable feature in some
environments.
* A few of the ares_dns.h macros are fixed to use the proper bitwise
operator.
* Fixed a couple of fenceposts fixed in ares_expand_name()'s
bounds-checking.
* In process_timeouts(), extract query->next before calling
next_server() and possibly freeing the query structure.
* Casted arguments to ctype macros casted to unsigned char, since not
all char values are valid inputs to those macros according to ANSI.

41
ares/README Normal file
View File

@ -0,0 +1,41 @@
This is ares, an asynchronous resolver library. It is intended for
applications which need to perform DNS queries without blocking, or
need to perform multiple DNS queries in parallel. The primary
examples of such applications are servers which communicate with
multiple clients and programs with graphical user interfaces.
This library implementation is not especially portable to crufty old
systems like SunOS 4. It assumes a compiler which can handle ANSI C
syntax, a system malloc which properly handles realloc(NULL, foo) and
free(NULL), and a reasonably up-to-date <arpa/nameser.h>.
I have attempted to preserve the externally visible behavior of the
BIND resolver in nearly all respects. The API of the library is, of
course, very different from the synchronous BIND API; instead of
invoking a function like res_send() and getting a return value back
indicating the number of bytes in the response, you invoke a function
like ares_send() and give it a callback function to invoke when the
response arrives. You then have to select() on the file descriptors
indicated by ares_fds(), with a timeout given by ares_timeout(). You
call ares_process() when select() returns.
Some features are missing from the current version of ares, relative
to the BIND resolver:
* There is no IPV6 support.
* There is no hostname verification.
* There is no logging of unexpected events.
* There is no debugging-oriented logging.
* There is no YP support.
libares requires an ANSI compiler to compile and use. To build the
library, just run "./configure" and "make". To install it, run "make
install". Run "./configure --help" to see a list of options you can
provide to configure to change how the library builds. libares has no
data files, so you can move the include file and library around freely
without leaving behind any dependencies on old paths. Building the
library will also build the "adig" program, a little toy for trying
out the library. It doesn't get installed.
libares is distributed at athena-dist.mit.edu:pub/ATHENA/ares. Please
send bug reports and comments to ghudson@mit.edu.

358
ares/aclocal.m4 vendored Normal file
View File

@ -0,0 +1,358 @@
dnl $Id$
dnl Copyright 1996 by the Massachusetts Institute of Technology.
dnl
dnl Permission to use, copy, modify, and distribute this
dnl software and its documentation for any purpose and without
dnl fee is hereby granted, provided that the above copyright
dnl notice appear in all copies and that both that copyright
dnl notice and this permission notice appear in supporting
dnl documentation, and that the name of M.I.T. not be used in
dnl advertising or publicity pertaining to distribution of the
dnl software without specific, written prior permission.
dnl M.I.T. makes no representations about the suitability of
dnl this software for any purpose. It is provided "as is"
dnl without express or implied warranty.
dnl This file provides local macros for packages which use specific
dnl external libraries. The public macros are:
dnl
dnl ATHENA_UTIL_COM_ERR
dnl Generates error if com_err not found.
dnl ATHENA_UTIL_SS
dnl Generates error if ss not found.
dnl ATHENA_REGEXP
dnl Sets REGEX_LIBS if rx library used; ensures POSIX
dnl regexp support.
dnl ATHENA_MOTIF
dnl Sets MOTIF_LIBS and defines HAVE_MOTIF if Motif used.
dnl ATHENA_MOTIF_REQUIRED
dnl Generates error if Motif not found.
dnl ATHENA_AFS
dnl Sets AFS_LIBS and defines HAVE_AFS if AFS used. Pass
dnl in an argument giving the desired AFS libraries;
dnl AFS_LIBS will be set to that value if AFS is found.
dnl AFS_DIR will be set to the prefix given.
dnl ATHENA_AFS_REQUIRED
dnl Generates error if AFS libraries not found. AFS_DIR
dnl will be set to the prefix given.
dnl ATHENA_KRB4
dnl Sets KRB4_LIBS and defines HAVE_KRB4 if krb4 used.
dnl ATHENA_KRB4_REQUIRED
dnl Generates error if krb4 not found. Sets KRB4_LIBS
dnl otherwise. (Special behavior because krb4 libraries
dnl may be different if using krb4 compatibility libraries
dnl from krb5.)
dnl ATHENA_KRB5
dnl Sets KRB5_LIBS and defines HAVE_KRB5 if krb5 used.
dnl ATHENA_KRB5_REQUIRED
dnl Generates error if krb5 not found.
dnl ATHENA_HESIOD
dnl Sets HESIOD_LIBS and defines HAVE_HESIOD if Hesiod
dnl used.
dnl ATHENA_HESIOD_REQUIRED
dnl Generates error if Hesiod not found.
dnl ATHENA_ARES
dnl Sets ARES_LIBS and defines HAVE_ARES if libares
dnl used.
dnl ATHENA_ARES_REQUIRED
dnl Generates error if libares not found.
dnl ATHENA_ZEPHYR
dnl Sets ZEPHYR_LIBS and defines HAVE_ZEPHYR if zephyr
dnl used.
dnl ATHENA_ZEPHYR_REQUIRED
dnl Generates error if zephyr not found.
dnl
dnl All of the macros may extend CPPFLAGS and LDFLAGS to let the
dnl compiler find the requested libraries. Put ATHENA_UTIL_COM_ERR
dnl and ATHENA_UTIL_SS before ATHENA_AFS or ATHENA_AFS_REQUIRED; there
dnl is a com_err library in the AFS libraries which requires -lutil.
dnl ----- com_err -----
AC_DEFUN(ATHENA_UTIL_COM_ERR,
[AC_ARG_WITH(com_err,
[ --with-com_err=PREFIX Specify location of com_err],
[com_err="$withval"], [com_err=yes])
if test "$com_err" != no; then
if test "$com_err" != yes; then
CPPFLAGS="$CPPFLAGS -I$com_err/include"
LDFLAGS="$LDFLAGS -L$com_err/lib"
fi
AC_CHECK_LIB(com_err, com_err, :,
[AC_MSG_ERROR(com_err library not found)])
else
AC_MSG_ERROR(This package requires com_err.)
fi])
dnl ----- ss -----
AC_DEFUN(ATHENA_UTIL_SS,
[AC_ARG_WITH(ss,
[ --with-ss=PREFIX Specify location of ss (requires com_err)],
[ss="$withval"], [ss=yes])
if test "$ss" != no; then
if test "$ss" != yes; then
CPPFLAGS="$CPPFLAGS -I$ss/include"
LDFLAGS="$LDFLAGS -L$ss/lib"
fi
AC_CHECK_LIB(ss, ss_perror, :,
[AC_MSG_ERROR(ss library not found)], -lcom_err)
else
AC_MSG_ERROR(This package requires ss.)
fi])
dnl ----- Regular expressions -----
AC_DEFUN(ATHENA_REGEXP,
[AC_ARG_WITH(regex,
[ --with-regex=PREFIX Use installed regex library],
[regex="$withval"], [regex=no])
if test "$regex" != no; then
if test "$regex" != yes; then
CPPFLAGS="$CPPFLAGS -I$regex/include"
LDFLAGS="$LDFLAGS -L$regex/lib"
fi
AC_CHECK_LIB(regex, regcomp, REGEX_LIBS=-lregex,
[AC_MSG_ERROR(regex library not found)])
else
AC_CHECK_FUNC(regcomp, :,
[AC_MSG_ERROR(can't find POSIX regexp support)])
fi
AC_SUBST(REGEX_LIBS)])
dnl ----- Motif -----
AC_DEFUN(ATHENA_MOTIF_CHECK,
[if test "$motif" != yes; then
CPPFLAGS="$CPPFLAGS -I$motif/include"
LDFLAGS="$LDFLAGS -L$motif/lib"
fi
AC_CHECK_LIB(Xm, XmStringFree, :, [AC_MSG_ERROR(Motif library not found)])])
AC_DEFUN(ATHENA_MOTIF,
[AC_ARG_WITH(motif,
[ --with-motif=PREFIX Use Motif],
[motif="$withval"], [motif=no])
if test "$motif" != no; then
ATHENA_MOTIF_CHECK
MOTIF_LIBS=-lXm
AC_DEFINE(HAVE_MOTIF)
fi
AC_SUBST(MOTIF_LIBS)])
AC_DEFUN(ATHENA_MOTIF_REQUIRED,
[AC_ARG_WITH(motif,
[ --with-motif=PREFIX Specify location of Motif],
[motif="$withval"], [motif=yes])
if test "$motif" != no; then
ATHENA_MOTIF_CHECK
else
AC_MSG_ERROR(This package requires Motif.)
fi])
dnl ----- AFS -----
AC_DEFUN(ATHENA_AFS_CHECK,
[AC_CHECK_FUNC(insque, :, AC_CHECK_LIB(compat, insque))
AC_CHECK_FUNC(gethostbyname, :, AC_CHECK_LIB(nsl, gethostbyname))
AC_CHECK_FUNC(socket, :, AC_CHECK_LIB(socket, socket))
if test "$afs" != yes; then
CPPFLAGS="$CPPFLAGS -I$afs/include"
LDFLAGS="$LDFLAGS -L$afs/lib -L$afs/lib/afs"
fi
AC_CHECK_LIB(sys, pioctl, :, [AC_MSG_ERROR(AFS libraries not found)],
-lrx -llwp -lsys)
AFS_DIR=$afs
AC_SUBST(AFS_DIR)])
dnl Specify desired AFS libraries as a parameter.
AC_DEFUN(ATHENA_AFS,
[AC_ARG_WITH(afs,
[ --with-afs=PREFIX Use AFS libraries],
[afs="$withval"], [afs=no])
if test "$afs" != no; then
ATHENA_AFS_CHECK
AFS_LIBS=$1
AC_DEFINE(HAVE_AFS)
fi
AC_SUBST(AFS_LIBS)])
AC_DEFUN(ATHENA_AFS_REQUIRED,
[AC_ARG_WITH(afs,
[ --with-afs=PREFIX Specify location of AFS libraries],
[afs="$withval"], [afs=/usr/afsws])
if test "$afs" != no; then
ATHENA_AFS_CHECK
else
AC_MSG_ERROR(This package requires AFS libraries.)
fi])
dnl ----- Kerberos 4 -----
AC_DEFUN(ATHENA_KRB4_CHECK,
[AC_CHECK_FUNC(gethostbyname, :, AC_CHECK_LIB(nsl, gethostbyname))
AC_CHECK_FUNC(socket, :, AC_CHECK_LIB(socket, socket))
AC_CHECK_LIB(gen, compile)
if test "$krb4" != yes; then
CPPFLAGS="$CPPFLAGS -I$krb4/include"
if test -d "$krb4/include/kerberosIV"; then
CPPFLAGS="$CPPFLAGS -I$krb4/include/kerberosIV"
fi
LDFLAGS="$LDFLAGS -L$krb4/lib"
fi
AC_CHECK_LIB(krb4, krb_rd_req,
[KRB4_LIBS="-lkrb4 -ldes425 -lkrb5 -lk5crypto -lcom_err"],
[AC_CHECK_LIB(krb, krb_rd_req,
[KRB4_LIBS="-lkrb -ldes"],
[AC_MSG_ERROR(Kerberos 4 libraries not found)],
-ldes)],
-ldes425 -lkrb5 -lk5crypto -lcom_err)])
AC_DEFUN(ATHENA_KRB4,
[AC_ARG_WITH(krb4,
[ --with-krb4=PREFIX Use Kerberos 4],
[krb4="$withval"], [krb4=no])
if test "$krb4" != no; then
ATHENA_KRB4_CHECK
AC_DEFINE(HAVE_KRB4)
fi
AC_SUBST(KRB4_LIBS)])
AC_DEFUN(ATHENA_KRB4_REQUIRED,
[AC_ARG_WITH(krb4,
[ --with-krb4=PREFIX Specify location of Kerberos 4],
[krb4="$withval"], [krb4=yes])
if test "$krb4" != no; then
ATHENA_KRB4_CHECK
AC_SUBST(KRB4_LIBS)
else
AC_MSG_ERROR(This package requires Kerberos 4.)
fi])
dnl ----- Kerberos 5 -----
AC_DEFUN(ATHENA_KRB5_CHECK,
[AC_SEARCH_LIBS(gethostbyname, nsl)
AC_SEARCH_LIBS(socket, socket)
AC_CHECK_LIB(gen, compile)
if test "$krb5" != yes; then
CPPFLAGS="$CPPFLAGS -I$krb5/include"
LDFLAGS="$LDFLAGS -L$krb5/lib"
fi
AC_CHECK_LIB(krb5, krb5_init_context, :,
[AC_MSG_ERROR(Kerberos 5 libraries not found)],
-lk5crypto -lcom_err)])
AC_DEFUN(ATHENA_KRB5,
[AC_ARG_WITH(krb5,
[ --with-krb5=PREFIX Use Kerberos 5],
[krb5="$withval"], [krb5=no])
if test "$krb5" != no; then
ATHENA_KRB5_CHECK
KRB5_LIBS="-lkrb5 -lk5crypto -lcom_err"
AC_DEFINE(HAVE_KRB5)
fi
AC_SUBST(KRB5_LIBS)])
AC_DEFUN(ATHENA_KRB5_REQUIRED,
[AC_ARG_WITH(krb5,
[ --with-krb5=PREFIX Specify location of Kerberos 5],
[krb5="$withval"], [krb5=yes])
if test "$krb5" != no; then
ATHENA_KRB5_CHECK
else
AC_MSG_ERROR(This package requires Kerberos 5.)
fi])
dnl ----- Hesiod -----
AC_DEFUN(ATHENA_HESIOD_CHECK,
[AC_CHECK_FUNC(res_send, :, AC_CHECK_LIB(resolv, res_send))
if test "$hesiod" != yes; then
CPPFLAGS="$CPPFLAGS -I$hesiod/include"
LDFLAGS="$LDFLAGS -L$hesiod/lib"
fi
AC_CHECK_LIB(hesiod, hes_resolve, :,
[AC_MSG_ERROR(Hesiod library not found)])])
AC_DEFUN(ATHENA_HESIOD,
[AC_ARG_WITH(hesiod,
[ --with-hesiod=PREFIX Use Hesiod],
[hesiod="$withval"], [hesiod=no])
if test "$hesiod" != no; then
ATHENA_HESIOD_CHECK
HESIOD_LIBS="-lhesiod"
AC_DEFINE(HAVE_HESIOD)
fi
AC_SUBST(HESIOD_LIBS)])
AC_DEFUN(ATHENA_HESIOD_REQUIRED,
[AC_ARG_WITH(hesiod,
[ --with-hesiod=PREFIX Specify location of Hesiod],
[hesiod="$withval"], [hesiod=yes])
if test "$hesiod" != no; then
ATHENA_HESIOD_CHECK
else
AC_MSG_ERROR(This package requires Hesiod.)
fi])
dnl ----- libares -----
AC_DEFUN(ATHENA_ARES_CHECK,
[AC_CHECK_FUNC(res_send, :, AC_CHECK_LIB(resolv, res_send))
if test "$ares" != yes; then
CPPFLAGS="$CPPFLAGS -I$ares/include"
LDFLAGS="$LDFLAGS -L$ares/lib"
fi
AC_CHECK_LIB(ares, ares_init, :, [AC_MSG_ERROR(libares not found)])])
AC_DEFUN(ATHENA_ARES,
[AC_ARG_WITH(ares,
[ --with-ares=PREFIX Use libares],
[ares="$withval"], [ares=no])
if test "$ares" != no; then
ATHENA_ARES_CHECK
ARES_LIBS="-lares"
AC_DEFINE(HAVE_ARES)
fi
AC_SUBST(ARES_LIBS)])
AC_DEFUN(ATHENA_ARES_REQUIRED,
[AC_ARG_WITH(ares,
[ --with-ares=PREFIX Specify location of libares],
[ares="$withval"], [ares=yes])
if test "$ares" != no; then
ATHENA_ARES_CHECK
else
AC_MSG_ERROR(This package requires libares.)
fi])
dnl ----- zephyr -----
AC_DEFUN(ATHENA_ZEPHYR_CHECK,
[if test "$zephyr" != yes; then
CPPFLAGS="$CPPFLAGS -I$zephyr/include"
LDFLAGS="$LDFLAGS -L$zephyr/lib"
fi
AC_CHECK_LIB(zephyr, ZFreeNotice, :, [AC_MSG_ERROR(zephyr not found)])])
AC_DEFUN(ATHENA_ZEPHYR,
[AC_ARG_WITH(zephyr,
[ --with-zephyr=PREFIX Use zephyr],
[zephyr="$withval"], [zephyr=no])
if test "$zephyr" != no; then
ATHENA_ZEPHYR_CHECK
ZEPHYR_LIBS="-lzephyr"
AC_DEFINE(HAVE_ZEPHYR)
fi
AC_SUBST(ZEPHYR_LIBS)])
AC_DEFUN(ATHENA_ZEPHYR_REQUIRED,
[AC_ARG_WITH(zephyr,
[ --with-zephyr=PREFIX Specify location of zephyr],
[zephyr="$withval"], [zephyr=yes])
if test "$zephyr" != no; then
ATHENA_ZEPHYR_CHECK
else
AC_MSG_ERROR(This package requires zephyr.)
fi])

623
ares/adig.c Normal file
View File

@ -0,0 +1,623 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
static const char rcsid[] = "$Id$";
#include <sys/types.h>
#ifdef WIN32
#include "nameser.h"
#else
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <unistd.h>
#include <netdb.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "ares.h"
#include "ares_dns.h"
#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif
/* Mac OS X portability check */
#ifndef T_SRV
#define T_SRV 33 /* server selection */
#endif
extern int optind;
extern char *optarg;
struct nv {
const char *name;
int value;
};
static const struct nv flags[] = {
{ "usevc", ARES_FLAG_USEVC },
{ "primary", ARES_FLAG_PRIMARY },
{ "igntc", ARES_FLAG_IGNTC },
{ "norecurse", ARES_FLAG_NORECURSE },
{ "stayopen", ARES_FLAG_STAYOPEN },
{ "noaliases", ARES_FLAG_NOALIASES }
};
static const int nflags = sizeof(flags) / sizeof(flags[0]);
static const struct nv classes[] = {
{ "IN", C_IN },
{ "CHAOS", C_CHAOS },
{ "HS", C_HS },
{ "ANY", C_ANY }
};
static const int nclasses = sizeof(classes) / sizeof(classes[0]);
static const struct nv types[] = {
{ "A", T_A },
{ "NS", T_NS },
{ "MD", T_MD },
{ "MF", T_MF },
{ "CNAME", T_CNAME },
{ "SOA", T_SOA },
{ "MB", T_MB },
{ "MG", T_MG },
{ "MR", T_MR },
{ "NULL", T_NULL },
{ "WKS", T_WKS },
{ "PTR", T_PTR },
{ "HINFO", T_HINFO },
{ "MINFO", T_MINFO },
{ "MX", T_MX },
{ "TXT", T_TXT },
{ "RP", T_RP },
{ "AFSDB", T_AFSDB },
{ "X25", T_X25 },
{ "ISDN", T_ISDN },
{ "RT", T_RT },
{ "NSAP", T_NSAP },
{ "NSAP_PTR", T_NSAP_PTR },
{ "SIG", T_SIG },
{ "KEY", T_KEY },
{ "PX", T_PX },
{ "GPOS", T_GPOS },
{ "AAAA", T_AAAA },
{ "LOC", T_LOC },
{ "SRV", T_SRV },
{ "AXFR", T_AXFR },
{ "MAILB", T_MAILB },
{ "MAILA", T_MAILA },
{ "ANY", T_ANY }
};
static const int ntypes = sizeof(types) / sizeof(types[0]);
static const char *opcodes[] = {
"QUERY", "IQUERY", "STATUS", "(reserved)", "NOTIFY",
"(unknown)", "(unknown)", "(unknown)", "(unknown)",
"UPDATEA", "UPDATED", "UPDATEDA", "UPDATEM", "UPDATEMA",
"ZONEINIT", "ZONEREF"
};
static const char *rcodes[] = {
"NOERROR", "FORMERR", "SERVFAIL", "NXDOMAIN", "NOTIMP", "REFUSED",
"(unknown)", "(unknown)", "(unknown)", "(unknown)", "(unknown)",
"(unknown)", "(unknown)", "(unknown)", "(unknown)", "NOCHANGE"
};
static void callback(void *arg, int status, unsigned char *abuf, int alen);
static const unsigned char *display_question(const unsigned char *aptr,
const unsigned char *abuf,
int alen);
static const unsigned char *display_rr(const unsigned char *aptr,
const unsigned char *abuf, int alen);
static const char *type_name(int type);
static const char *class_name(int dnsclass);
static void usage(void);
int main(int argc, char **argv)
{
ares_channel channel;
int c, i, optmask = ARES_OPT_FLAGS, dnsclass = C_IN, type = T_A;
int status, nfds, count;
struct ares_options options;
struct hostent *hostent;
fd_set read_fds, write_fds;
struct timeval *tvp, tv;
char *errmem;
#ifdef WIN32
WORD wVersionRequested = MAKEWORD(1,1);
WSADATA wsaData;
WSAStartup(wVersionRequested, &wsaData);
#endif
options.flags = ARES_FLAG_NOCHECKRESP;
options.servers = NULL;
options.nservers = 0;
while ((c = getopt(argc, argv, "f:s:c:t:T:U:")) != -1)
{
switch (c)
{
case 'f':
/* Add a flag. */
for (i = 0; i < nflags; i++)
{
if (strcmp(flags[i].name, optarg) == 0)
break;
}
if (i == nflags)
usage();
options.flags |= flags[i].value;
break;
case 's':
/* Add a server, and specify servers in the option mask. */
hostent = gethostbyname(optarg);
if (!hostent || hostent->h_addrtype != AF_INET)
{
fprintf(stderr, "adig: server %s not found.\n", optarg);
return 1;
}
options.servers = realloc(options.servers, (options.nservers + 1)
* sizeof(struct in_addr));
if (!options.servers)
{
fprintf(stderr, "Out of memory!\n");
return 1;
}
memcpy(&options.servers[options.nservers], hostent->h_addr,
sizeof(struct in_addr));
options.nservers++;
optmask |= ARES_OPT_SERVERS;
break;
case 'c':
/* Set the query class. */
for (i = 0; i < nclasses; i++)
{
if (strcasecmp(classes[i].name, optarg) == 0)
break;
}
if (i == nclasses)
usage();
dnsclass = classes[i].value;
break;
case 't':
/* Set the query type. */
for (i = 0; i < ntypes; i++)
{
if (strcasecmp(types[i].name, optarg) == 0)
break;
}
if (i == ntypes)
usage();
type = types[i].value;
break;
case 'T':
/* Set the TCP port number. */
if (!isdigit((unsigned char)*optarg))
usage();
options.tcp_port = strtol(optarg, NULL, 0);
optmask |= ARES_OPT_TCP_PORT;
break;
case 'U':
/* Set the UDP port number. */
if (!isdigit((unsigned char)*optarg))
usage();
options.udp_port = strtol(optarg, NULL, 0);
optmask |= ARES_OPT_UDP_PORT;
break;
}
}
argc -= optind;
argv += optind;
if (argc == 0)
usage();
status = ares_init_options(&channel, &options, optmask);
if (status != ARES_SUCCESS)
{
fprintf(stderr, "ares_init_options: %s\n",
ares_strerror(status, &errmem));
ares_free_errmem(errmem);
return 1;
}
/* Initiate the queries, one per command-line argument. If there is
* only one query to do, supply NULL as the callback argument;
* otherwise, supply the query name as an argument so we can
* distinguish responses for the user when printing them out.
*/
if (argc == 1)
ares_query(channel, *argv, dnsclass, type, callback, (char *) NULL);
else
{
for (; *argv; argv++)
ares_query(channel, *argv, dnsclass, type, callback, *argv);
}
/* Wait for all queries to complete. */
while (1)
{
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
nfds = ares_fds(channel, &read_fds, &write_fds);
if (nfds == 0)
break;
tvp = ares_timeout(channel, NULL, &tv);
count = select(nfds, &read_fds, &write_fds, NULL, tvp);
if (count < 0 && errno != EINVAL)
{
perror("select");
return 1;
}
ares_process(channel, &read_fds, &write_fds);
}
ares_destroy(channel);
return 0;
}
static void callback(void *arg, int status, unsigned char *abuf, int alen)
{
char *name = (char *) arg, *errmem;
int id, qr, opcode, aa, tc, rd, ra, rcode, i;
unsigned int qdcount, ancount, nscount, arcount;
const unsigned char *aptr;
/* Display the query name if given. */
if (name)
printf("Answer for query %s:\n", name);
/* Display an error message if there was an error, but only stop if
* we actually didn't get an answer buffer.
*/
if (status != ARES_SUCCESS)
{
printf("%s\n", ares_strerror(status, &errmem));
ares_free_errmem(errmem);
if (!abuf)
return;
}
/* Won't happen, but check anyway, for safety. */
if (alen < HFIXEDSZ)
return;
/* Parse the answer header. */
id = DNS_HEADER_QID(abuf);
qr = DNS_HEADER_QR(abuf);
opcode = DNS_HEADER_OPCODE(abuf);
aa = DNS_HEADER_AA(abuf);
tc = DNS_HEADER_TC(abuf);
rd = DNS_HEADER_RD(abuf);
ra = DNS_HEADER_RA(abuf);
rcode = DNS_HEADER_RCODE(abuf);
qdcount = DNS_HEADER_QDCOUNT(abuf);
ancount = DNS_HEADER_ANCOUNT(abuf);
nscount = DNS_HEADER_NSCOUNT(abuf);
arcount = DNS_HEADER_ARCOUNT(abuf);
/* Display the answer header. */
printf("id: %d\n", id);
printf("flags: %s%s%s%s%s\n",
qr ? "qr " : "",
aa ? "aa " : "",
tc ? "tc " : "",
rd ? "rd " : "",
ra ? "ra " : "");
printf("opcode: %s\n", opcodes[opcode]);
printf("rcode: %s\n", rcodes[rcode]);
/* Display the questions. */
printf("Questions:\n");
aptr = abuf + HFIXEDSZ;
for (i = 0; i < qdcount; i++)
{
aptr = display_question(aptr, abuf, alen);
if (aptr == NULL)
return;
}
/* Display the answers. */
printf("Answers:\n");
for (i = 0; i < ancount; i++)
{
aptr = display_rr(aptr, abuf, alen);
if (aptr == NULL)
return;
}
/* Display the NS records. */
printf("NS records:\n");
for (i = 0; i < nscount; i++)
{
aptr = display_rr(aptr, abuf, alen);
if (aptr == NULL)
return;
}
/* Display the additional records. */
printf("Additional records:\n");
for (i = 0; i < arcount; i++)
{
aptr = display_rr(aptr, abuf, alen);
if (aptr == NULL)
return;
}
}
static const unsigned char *display_question(const unsigned char *aptr,
const unsigned char *abuf,
int alen)
{
char *name;
int type, dnsclass, status, len;
/* Parse the question name. */
status = ares_expand_name(aptr, abuf, alen, &name, &len);
if (status != ARES_SUCCESS)
return NULL;
aptr += len;
/* Make sure there's enough data after the name for the fixed part
* of the question.
*/
if (aptr + QFIXEDSZ > abuf + alen)
{
free(name);
return NULL;
}
/* Parse the question type and class. */
type = DNS_QUESTION_TYPE(aptr);
dnsclass = DNS_QUESTION_CLASS(aptr);
aptr += QFIXEDSZ;
/* Display the question, in a format sort of similar to how we will
* display RRs.
*/
printf("\t%-15s.\t", name);
if (dnsclass != C_IN)
printf("\t%s", class_name(dnsclass));
printf("\t%s\n", type_name(type));
free(name);
return aptr;
}
static const unsigned char *display_rr(const unsigned char *aptr,
const unsigned char *abuf, int alen)
{
const unsigned char *p;
char *name;
int type, dnsclass, ttl, dlen, status, len;
struct in_addr addr;
/* Parse the RR name. */
status = ares_expand_name(aptr, abuf, alen, &name, &len);
if (status != ARES_SUCCESS)
return NULL;
aptr += len;
/* Make sure there is enough data after the RR name for the fixed
* part of the RR.
*/
if (aptr + RRFIXEDSZ > abuf + alen)
{
free(name);
return NULL;
}
/* Parse the fixed part of the RR, and advance to the RR data
* field. */
type = DNS_RR_TYPE(aptr);
dnsclass = DNS_RR_CLASS(aptr);
ttl = DNS_RR_TTL(aptr);
dlen = DNS_RR_LEN(aptr);
aptr += RRFIXEDSZ;
if (aptr + dlen > abuf + alen)
{
free(name);
return NULL;
}
/* Display the RR name, class, and type. */
printf("\t%-15s.\t%d", name, ttl);
if (dnsclass != C_IN)
printf("\t%s", class_name(dnsclass));
printf("\t%s", type_name(type));
free(name);
/* Display the RR data. Don't touch aptr. */
switch (type)
{
case T_CNAME:
case T_MB:
case T_MD:
case T_MF:
case T_MG:
case T_MR:
case T_NS:
case T_PTR:
/* For these types, the RR data is just a domain name. */
status = ares_expand_name(aptr, abuf, alen, &name, &len);
if (status != ARES_SUCCESS)
return NULL;
printf("\t%s.", name);
free(name);
break;
case T_HINFO:
/* The RR data is two length-counted character strings. */
p = aptr;
len = *p;
if (p + len + 1 > aptr + dlen)
return NULL;
printf("\t%.*s", len, p + 1);
p += len + 1;
len = *p;
if (p + len + 1 > aptr + dlen)
return NULL;
printf("\t%.*s", len, p + 1);
break;
case T_MINFO:
/* The RR data is two domain names. */
p = aptr;
status = ares_expand_name(p, abuf, alen, &name, &len);
if (status != ARES_SUCCESS)
return NULL;
printf("\t%s.", name);
free(name);
p += len;
status = ares_expand_name(p, abuf, alen, &name, &len);
if (status != ARES_SUCCESS)
return NULL;
printf("\t%s.", name);
free(name);
break;
case T_MX:
/* The RR data is two bytes giving a preference ordering, and
* then a domain name.
*/
if (dlen < 2)
return NULL;
printf("\t%d", (aptr[0] << 8) | aptr[1]);
status = ares_expand_name(aptr + 2, abuf, alen, &name, &len);
if (status != ARES_SUCCESS)
return NULL;
printf("\t%s.", name);
free(name);
break;
case T_SOA:
/* The RR data is two domain names and then five four-byte
* numbers giving the serial number and some timeouts.
*/
p = aptr;
status = ares_expand_name(p, abuf, alen, &name, &len);
if (status != ARES_SUCCESS)
return NULL;
printf("\t%s.\n", name);
free(name);
p += len;
status = ares_expand_name(p, abuf, alen, &name, &len);
if (status != ARES_SUCCESS)
return NULL;
printf("\t\t\t\t\t\t%s.\n", name);
free(name);
p += len;
if (p + 20 > aptr + dlen)
return NULL;
printf("\t\t\t\t\t\t( %d %d %d %d %d )",
(p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3],
(p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7],
(p[8] << 24) | (p[9] << 16) | (p[10] << 8) | p[11],
(p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15],
(p[16] << 24) | (p[17] << 16) | (p[18] << 8) | p[19]);
break;
case T_TXT:
/* The RR data is one or more length-counted character
* strings. */
p = aptr;
while (p < aptr + dlen)
{
len = *p;
if (p + len + 1 > aptr + dlen)
return NULL;
printf("\t%.*s", len, p + 1);
p += len + 1;
}
break;
case T_A:
/* The RR data is a four-byte Internet address. */
if (dlen != 4)
return NULL;
memcpy(&addr, aptr, sizeof(struct in_addr));
printf("\t%s", inet_ntoa(addr));
break;
case T_WKS:
/* Not implemented yet */
break;
case T_SRV:
/* The RR data is three two-byte numbers representing the
* priority, weight, and port, followed by a domain name.
*/
printf("\t%d", DNS__16BIT(aptr));
printf(" %d", DNS__16BIT(aptr + 2));
printf(" %d", DNS__16BIT(aptr + 4));
status = ares_expand_name(aptr + 6, abuf, alen, &name, &len);
if (status != ARES_SUCCESS)
return NULL;
printf("\t%s.", name);
free(name);
break;
default:
printf("\t[Unknown RR; cannot parse]");
}
printf("\n");
return aptr + dlen;
}
static const char *type_name(int type)
{
int i;
for (i = 0; i < ntypes; i++)
{
if (types[i].value == type)
return types[i].name;
}
return "(unknown)";
}
static const char *class_name(int dnsclass)
{
int i;
for (i = 0; i < nclasses; i++)
{
if (classes[i].value == dnsclass)
return classes[i].name;
}
return "(unknown)";
}
static void usage(void)
{
fprintf(stderr, "usage: adig [-f flag] [-s server] [-c class] "
"[-t type] [-p port] name ...\n");
exit(1);
}

122
ares/ahost.c Normal file
View File

@ -0,0 +1,122 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
static const char rcsid[] = "$Id$";
#include <sys/types.h>
#ifdef WIN32
#else
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ares.h"
#include "ares_dns.h"
#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif
static void callback(void *arg, int status, struct hostent *host);
static void usage(void);
int main(int argc, char **argv)
{
ares_channel channel;
int status, nfds;
fd_set read_fds, write_fds;
struct timeval *tvp, tv;
char *errmem;
struct in_addr addr;
#ifdef WIN32
WORD wVersionRequested = MAKEWORD(1,1);
WSADATA wsaData;
WSAStartup(wVersionRequested, &wsaData);
#endif
if (argc == 0)
usage();
status = ares_init(&channel);
if (status != ARES_SUCCESS)
{
fprintf(stderr, "ares_init: %s\n", ares_strerror(status, &errmem));
ares_free_errmem(errmem);
return 1;
}
/* Initiate the queries, one per command-line argument. */
for (argv++; *argv; argv++)
{
addr.s_addr = inet_addr(*argv);
if (addr.s_addr == INADDR_NONE)
ares_gethostbyname(channel, *argv, AF_INET, callback, *argv);
else
{
ares_gethostbyaddr(channel, &addr, sizeof(addr), AF_INET, callback,
*argv);
}
}
/* Wait for all queries to complete. */
while (1)
{
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
nfds = ares_fds(channel, &read_fds, &write_fds);
if (nfds == 0)
break;
tvp = ares_timeout(channel, NULL, &tv);
select(nfds, &read_fds, &write_fds, NULL, tvp);
ares_process(channel, &read_fds, &write_fds);
}
ares_destroy(channel);
return 0;
}
static void callback(void *arg, int status, struct hostent *host)
{
struct in_addr addr;
char *mem, **p;
if (status != ARES_SUCCESS)
{
fprintf(stderr, "%s: %s\n", (char *) arg, ares_strerror(status, &mem));
ares_free_errmem(mem);
return;
}
for (p = host->h_addr_list; *p; p++)
{
memcpy(&addr, *p, sizeof(struct in_addr));
printf("%-32s\t%s\n", host->h_name, inet_ntoa(addr));
}
}
static void usage(void)
{
fprintf(stderr, "usage: ahost {host|addr} ...\n");
exit(1);
}

130
ares/ares.h Normal file
View File

@ -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 */

View File

@ -0,0 +1,57 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
static const char rcsid[] = "$Id$";
#include <stdlib.h>
#ifdef WIN32
#else
#include <unistd.h>
#endif
#include "ares.h"
#include "ares_private.h"
void ares__close_sockets(struct server_state *server)
{
struct send_request *sendreq;
/* Free all pending output buffers. */
while (server->qhead)
{
/* Advance server->qhead; pull out query as we go. */
sendreq = server->qhead;
server->qhead = sendreq->next;
free(sendreq);
}
server->qtail = NULL;
/* Reset any existing input buffer. */
if (server->tcp_buffer)
free(server->tcp_buffer);
server->tcp_buffer = NULL;
server->tcp_lenbuf_pos = 0;
/* Close the TCP and UDP sockets. */
if (server->tcp_socket != -1)
{
closesocket(server->tcp_socket);
server->tcp_socket = -1;
}
if (server->udp_socket != -1)
{
closesocket(server->udp_socket);
server->udp_socket = -1;
}
}

171
ares/ares__get_hostent.c Normal file
View File

@ -0,0 +1,171 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
static const char rcsid[] = "$Id$";
#include <sys/types.h>
#ifdef WIN32
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "ares.h"
#include "ares_private.h"
int ares__get_hostent(FILE *fp, struct hostent **host)
{
char *line = NULL, *p, *q, *canonical, **alias;
int status, linesize, end_at_hostname, naliases;
struct in_addr addr;
struct hostent *hostent = NULL;
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
{
/* Skip comment lines; terminate line at comment character. */
if (*line == '#' || !*line)
continue;
p = strchr(line, '#');
if (p)
*p = 0;
/* Get the address part. */
p = line;
while (*p && !isspace((unsigned char)*p))
p++;
if (!*p)
continue;
*p = 0;
addr.s_addr = inet_addr(line);
if (addr.s_addr == INADDR_NONE)
continue;
/* Get the canonical hostname. */
p++;
while (isspace((unsigned char)*p))
p++;
if (!*p)
continue;
q = p;
while (*q && !isspace((unsigned char)*q))
q++;
end_at_hostname = (*q == 0);
*q = 0;
canonical = p;
naliases = 0;
if (!end_at_hostname)
{
/* Count the aliases. */
p = q + 1;
while (isspace((unsigned char)*p))
p++;
while (*p)
{
while (*p && !isspace((unsigned char)*p))
p++;
while (isspace((unsigned char)*p))
p++;
naliases++;
}
}
/* Allocate memory for the host structure. */
hostent = malloc(sizeof(struct hostent));
if (!hostent)
break;
hostent->h_aliases = NULL;
hostent->h_addr_list = NULL;
hostent->h_name = strdup(canonical);
if (!hostent->h_name)
break;
hostent->h_addr_list = malloc(2 * sizeof(char *));
if (!hostent->h_addr_list)
break;
hostent->h_addr_list[0] = malloc(sizeof(struct in_addr));
if (!hostent->h_addr_list[0])
break;
hostent->h_aliases = malloc((naliases + 1) * sizeof(char *));
if (!hostent->h_aliases)
break;
/* Copy in aliases. */
naliases = 0;
if (!end_at_hostname)
{
p = canonical + strlen(canonical) + 1;
while (isspace((unsigned char)*p))
p++;
while (*p)
{
q = p;
while (*q && !isspace((unsigned char)*q))
q++;
hostent->h_aliases[naliases] = malloc(q - p + 1);
if (hostent->h_aliases[naliases] == NULL)
break;
memcpy(hostent->h_aliases[naliases], p, q - p);
hostent->h_aliases[naliases][q - p] = 0;
p = q;
while (isspace((unsigned char)*p))
p++;
naliases++;
}
if (*p)
break;
}
hostent->h_aliases[naliases] = NULL;
hostent->h_addrtype = AF_INET;
hostent->h_length = sizeof(struct in_addr);
memcpy(hostent->h_addr_list[0], &addr, sizeof(struct in_addr));
hostent->h_addr_list[1] = NULL;
*host = hostent;
free(line);
return ARES_SUCCESS;
}
free(line);
if (status == ARES_SUCCESS)
{
/* Memory allocation failure; clean up. */
if (hostent)
{
free((char *) hostent->h_name);
if (hostent->h_aliases)
{
for (alias = hostent->h_aliases; *alias; alias++)
free(*alias);
}
free(hostent->h_aliases);
if (hostent->h_addr_list)
free(hostent->h_addr_list[0]);
free(hostent->h_addr_list);
}
free(hostent);
return ARES_ENOMEM;
}
return status;
}

64
ares/ares__read_line.c Normal file
View File

@ -0,0 +1,64 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
static const char rcsid[] = "$Id$";
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ares.h"
#include "ares_private.h"
/* This is an internal function. Its contract is to read a line from
* a file into a dynamically allocated buffer, zeroing the trailing
* newline if there is one. The calling routine may call
* ares__read_line multiple times with the same buf and bufsize
* pointers; *buf will be reallocated and *bufsize adjusted as
* appropriate. The initial value of *buf should be NULL. After the
* calling routine is done reading lines, it should free *buf.
*/
int ares__read_line(FILE *fp, char **buf, int *bufsize)
{
char *newbuf;
int offset = 0, len;
if (*buf == NULL)
{
*buf = malloc(128);
if (!*buf)
return ARES_ENOMEM;
*bufsize = 128;
}
while (1)
{
if (!fgets(*buf + offset, *bufsize - offset, fp))
return (offset != 0) ? 0 : (ferror(fp)) ? ARES_EFILE : ARES_EOF;
len = offset + strlen(*buf + offset);
if ((*buf)[len - 1] == '\n')
{
(*buf)[len - 1] = 0;
return ARES_SUCCESS;
}
offset = len;
/* Allocate more space. */
newbuf = realloc(*buf, *bufsize * 2);
if (!newbuf)
return ARES_ENOMEM;
*buf = newbuf;
*bufsize *= 2;
}
}

43
ares/ares_destroy.3 Normal file
View File

@ -0,0 +1,43 @@
.\" $Id$
.\"
.\" Copyright 1998 by the Massachusetts Institute of Technology.
.\"
.\" Permission to use, copy, modify, and distribute this
.\" software and its documentation for any purpose and without
.\" fee is hereby granted, provided that the above copyright
.\" notice appear in all copies and that both that copyright
.\" notice and this permission notice appear in supporting
.\" documentation, and that the name of M.I.T. not be used in
.\" advertising or publicity pertaining to distribution of the
.\" software without specific, written prior permission.
.\" M.I.T. makes no representations about the suitability of
.\" this software for any purpose. It is provided "as is"
.\" without express or implied warranty.
.\"
.TH ARES_DESTROY 3 "23 July 1998"
.SH NAME
ares_destroy \- Destroy a resolver channel
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B int ares_destroy(ares_channel \fIchannel\fP)
.fi
.SH DESCRIPTION
The
.B ares_destroy
function destroys the name service channel identified by
.IR channel ,
freeing all memory and closing all sockets used by the channel.
.B ares_destroy
invokes the callbacks for each pending query on the channel, passing a
status of
.BR ARES_EDESTRUCTION .
These calls give the callbacks a chance to clean up any state which
might have been stored in their arguments.
.SH SEE ALSO
.BR ares_init (3)
.SH AUTHOR
Greg Hudson, MIT Information Systems
.br
Copyright 1998 by the Massachusetts Institute of Technology.

45
ares/ares_destroy.c Normal file
View File

@ -0,0 +1,45 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
static const char rcsid[] = "$Id$";
#include <stdlib.h>
#include "ares.h"
#include "ares_private.h"
void ares_destroy(ares_channel channel)
{
int i;
struct query *query;
for (i = 0; i < channel->nservers; i++)
ares__close_sockets(&channel->servers[i]);
free(channel->servers);
for (i = 0; i < channel->ndomains; i++)
free(channel->domains[i]);
free(channel->domains);
free(channel->sortlist);
free(channel->lookups);
while (channel->queries)
{
query = channel->queries;
channel->queries = query->next;
query->callback(query->arg, ARES_EDESTRUCTION, NULL, 0);
free(query->tcpbuf);
free(query->skip_server);
free(query);
}
free(channel);
}

81
ares/ares_dns.h Normal file
View File

@ -0,0 +1,81 @@
/* $Id$ */
/* Copyright 1998 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
#ifndef ARES__DNS_H
#define ARES__DNS_H
#define DNS__16BIT(p) (((p)[0] << 8) | (p)[1])
#define DNS__32BIT(p) (((p)[0] << 24) | ((p)[1] << 16) | \
((p)[2] << 8) | (p)[3])
#define DNS__SET16BIT(p, v) (((p)[0] = ((v) >> 8) & 0xff), \
((p)[1] = (v) & 0xff))
#define DNS__SET32BIT(p, v) (((p)[0] = ((v) >> 24) & 0xff), \
((p)[1] = ((v) >> 16) & 0xff), \
((p)[2] = ((v) >> 8) & 0xff), \
((p)[3] = (v) & 0xff))
/* Macros for parsing a DNS header */
#define DNS_HEADER_QID(h) DNS__16BIT(h)
#define DNS_HEADER_QR(h) (((h)[2] >> 7) & 0x1)
#define DNS_HEADER_OPCODE(h) (((h)[2] >> 3) & 0xf)
#define DNS_HEADER_AA(h) (((h)[2] >> 2) & 0x1)
#define DNS_HEADER_TC(h) (((h)[2] >> 1) & 0x1)
#define DNS_HEADER_RD(h) ((h)[2] & 0x1)
#define DNS_HEADER_RA(h) (((h)[3] >> 7) & 0x1)
#define DNS_HEADER_Z(h) (((h)[3] >> 4) & 0x7)
#define DNS_HEADER_RCODE(h) ((h)[3] & 0xf)
#define DNS_HEADER_QDCOUNT(h) DNS__16BIT((h) + 4)
#define DNS_HEADER_ANCOUNT(h) DNS__16BIT((h) + 6)
#define DNS_HEADER_NSCOUNT(h) DNS__16BIT((h) + 8)
#define DNS_HEADER_ARCOUNT(h) DNS__16BIT((h) + 10)
/* Macros for constructing a DNS header */
#define DNS_HEADER_SET_QID(h, v) DNS__SET16BIT(h, v)
#define DNS_HEADER_SET_QR(h, v) ((h)[2] |= (((v) & 0x1) << 7))
#define DNS_HEADER_SET_OPCODE(h, v) ((h)[2] |= (((v) & 0xf) << 3))
#define DNS_HEADER_SET_AA(h, v) ((h)[2] |= (((v) & 0x1) << 2))
#define DNS_HEADER_SET_TC(h, v) ((h)[2] |= (((v) & 0x1) << 1))
#define DNS_HEADER_SET_RD(h, v) ((h)[2] |= (((v) & 0x1)))
#define DNS_HEADER_SET_RA(h, v) ((h)[3] |= (((v) & 0x1) << 7))
#define DNS_HEADER_SET_Z(h, v) ((h)[3] |= (((v) & 0x7) << 4))
#define DNS_HEADER_SET_RCODE(h, v) ((h)[3] |= (((v) & 0xf)))
#define DNS_HEADER_SET_QDCOUNT(h, v) DNS__SET16BIT((h) + 4, v)
#define DNS_HEADER_SET_ANCOUNT(h, v) DNS__SET16BIT((h) + 6, v)
#define DNS_HEADER_SET_NSCOUNT(h, v) DNS__SET16BIT((h) + 8, v)
#define DNS_HEADER_SET_ARCOUNT(h, v) DNS__SET16BIT((h) + 10, v)
/* Macros for parsing the fixed part of a DNS question */
#define DNS_QUESTION_TYPE(q) DNS__16BIT(q)
#define DNS_QUESTION_CLASS(q) DNS__16BIT((q) + 2)
/* Macros for constructing the fixed part of a DNS question */
#define DNS_QUESTION_SET_TYPE(q, v) DNS__SET16BIT(q, v)
#define DNS_QUESTION_SET_CLASS(q, v) DNS__SET16BIT((q) + 2, v)
/* Macros for parsing the fixed part of a DNS resource record */
#define DNS_RR_TYPE(r) DNS__16BIT(r)
#define DNS_RR_CLASS(r) DNS__16BIT((r) + 2)
#define DNS_RR_TTL(r) DNS__32BIT((r) + 4)
#define DNS_RR_LEN(r) DNS__16BIT((r) + 8)
/* Macros for constructing the fixed part of a DNS resource record */
#define DNS_RR_SET_TYPE(r) DNS__SET16BIT(r, v)
#define DNS_RR_SET_CLASS(r) DNS__SET16BIT((r) + 2, v)
#define DNS_RR_SET_TTL(r) DNS__SET32BIT((r) + 4, v)
#define DNS_RR_SET_LEN(r) DNS__SET16BIT((r) + 8, v)
#endif /* ARES__DNS_H */

65
ares/ares_expand_name.3 Normal file
View File

@ -0,0 +1,65 @@
.\" $Id$
.\"
.\" Copyright 1998 by the Massachusetts Institute of Technology.
.\"
.\" Permission to use, copy, modify, and distribute this
.\" software and its documentation for any purpose and without
.\" fee is hereby granted, provided that the above copyright
.\" notice appear in all copies and that both that copyright
.\" notice and this permission notice appear in supporting
.\" documentation, and that the name of M.I.T. not be used in
.\" advertising or publicity pertaining to distribution of the
.\" software without specific, written prior permission.
.\" M.I.T. makes no representations about the suitability of
.\" this software for any purpose. It is provided "as is"
.\" without express or implied warranty.
.\"
.TH ARES_EXPAND_NAME 3 "23 July 1998"
.SH NAME
ares_expand_name \- Expand a DNS-encoded domain name
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B int ares_expand_name(const unsigned char *\fIencoded\fP,
.B
const unsigned char *\fIabuf\fP, int \fIalen\fP, char **\fIs\fP,
.B int *\fIenclen\fP)
.fi
.SH DESCRIPTION
The
.B ares_expand_name
function converts a DNS-encoded domain name to a dot-separated C
string. The argument
.I encoded
gives the beginning of the encoded domain name, and the arguments
.I abuf
and
.I alen
give the containing message buffer (necessary for the processing of
indirection pointers within the encoded domain name). The result is
placed in a NUL-terminated allocated buffer, a pointer to which is
stored in the variable pointed to by
.IR s .
The length of the encoded name is stored in the variable pointed to by
.I enclen
so that the caller can advance past the encoded domain name to read
further data in the message.
.SH RETURN VALUES
.B ares_expand_name
can return any of the following values:
.TP 15
.B ARES_SUCCESS
Expansion of the encoded name succeeded.
.TP 15
.B ARES_EBADNAME
The encoded domain name was malformed and could not be expanded.
.TP 15
.B ARES_ENOMEM
Memory was exhausted.
.SH SEE ALSO
.BR ares_mkquery (3)
.SH AUTHOR
Greg Hudson, MIT Information Systems
.br
Copyright 1998 by the Massachusetts Institute of Technology.

159
ares/ares_expand_name.c Normal file
View File

@ -0,0 +1,159 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
static const char rcsid[] = "$Id$";
#include <sys/types.h>
#ifdef WIN32
#include "nameser.h"
#else
#include <netinet/in.h>
#include <arpa/nameser.h>
#endif
#include <stdlib.h>
#include "ares.h"
static int name_length(const unsigned char *encoded, const unsigned char *abuf,
int alen);
/* Expand an RFC1035-encoded domain name given by encoded. The
* containing message is given by abuf and alen. The result given by
* *s, which is set to a NUL-terminated allocated buffer. *enclen is
* set to the length of the encoded name (not the length of the
* expanded name; the goal is to tell the caller how many bytes to
* move forward to get past the encoded name).
*
* In the simple case, an encoded name is a series of labels, each
* composed of a one-byte length (limited to values between 0 and 63
* inclusive) followed by the label contents. The name is terminated
* by a zero-length label.
*
* In the more complicated case, a label may be terminated by an
* indirection pointer, specified by two bytes with the high bits of
* the first byte (corresponding to INDIR_MASK) set to 11. With the
* two high bits of the first byte stripped off, the indirection
* pointer gives an offset from the beginning of the containing
* message with more labels to decode. Indirection can happen an
* arbitrary number of times, so we have to detect loops.
*
* Since the expanded name uses '.' as a label separator, we use
* backslashes to escape periods or backslashes in the expanded name.
*/
int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf,
int alen, char **s, int *enclen)
{
int len, indir = 0;
char *q;
const unsigned char *p;
len = name_length(encoded, abuf, alen);
if (len == -1)
return ARES_EBADNAME;
*s = malloc(len + 1);
if (!*s)
return ARES_ENOMEM;
q = *s;
/* No error-checking necessary; it was all done by name_length(). */
p = encoded;
while (*p)
{
if ((*p & INDIR_MASK) == INDIR_MASK)
{
if (!indir)
{
*enclen = p + 2 - encoded;
indir = 1;
}
p = abuf + ((*p & ~INDIR_MASK) << 8 | *(p + 1));
}
else
{
len = *p;
p++;
while (len--)
{
if (*p == '.' || *p == '\\')
*q++ = '\\';
*q++ = *p;
p++;
}
*q++ = '.';
}
}
if (!indir)
*enclen = p + 1 - encoded;
/* Nuke the trailing period if we wrote one. */
if (q > *s)
*(q - 1) = 0;
return ARES_SUCCESS;
}
/* Return the length of the expansion of an encoded domain name, or
* -1 if the encoding is invalid.
*/
static int name_length(const unsigned char *encoded, const unsigned char *abuf,
int alen)
{
int n = 0, offset, indir = 0;
/* Allow the caller to pass us abuf + alen and have us check for it. */
if (encoded == abuf + alen)
return -1;
while (*encoded)
{
if ((*encoded & INDIR_MASK) == INDIR_MASK)
{
/* Check the offset and go there. */
if (encoded + 1 >= abuf + alen)
return -1;
offset = (*encoded & ~INDIR_MASK) << 8 | *(encoded + 1);
if (offset >= alen)
return -1;
encoded = abuf + offset;
/* If we've seen more indirects than the message length,
* then there's a loop.
*/
if (++indir > alen)
return -1;
}
else
{
offset = *encoded;
if (encoded + offset + 1 >= abuf + alen)
return -1;
encoded++;
while (offset--)
{
n += (*encoded == '.' || *encoded == '\\') ? 2 : 1;
encoded++;
}
n++;
}
}
/* If there were any labels at all, then the number of dots is one
* less than the number of labels, so subtract one.
*/
return (n) ? n - 1 : n;
}

62
ares/ares_fds.3 Normal file
View File

@ -0,0 +1,62 @@
.\" $Id$
.\"
.\" Copyright 1998 by the Massachusetts Institute of Technology.
.\"
.\" Permission to use, copy, modify, and distribute this
.\" software and its documentation for any purpose and without
.\" fee is hereby granted, provided that the above copyright
.\" notice appear in all copies and that both that copyright
.\" notice and this permission notice appear in supporting
.\" documentation, and that the name of M.I.T. not be used in
.\" advertising or publicity pertaining to distribution of the
.\" software without specific, written prior permission.
.\" M.I.T. makes no representations about the suitability of
.\" this software for any purpose. It is provided "as is"
.\" without express or implied warranty.
.\"
.TH ARES_FDS 3 "23 July 1998"
.SH NAME
ares_fds \- Get file descriptors to select on for name service
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B int ares_fds(ares_channel \fIchannel\fP, fd_set *\fIread_fds\fP,
.B fd_set *\fIwrite_fds\fP)
.fi
.SH DESCRIPTION
The
.B ares_fds
function retrieves the set of file descriptors which the calling
application should select on for reading and writing for the
processing of name service queries pending on the name service channel
identified by
.IR channel .
File descriptors will be set in the file descriptor sets pointed to by
.I read_fds
and
.I write_fds
as appropriate. File descriptors already set in
.I read_fds
and
.I write_fds
will remain set; initialization of the file descriptor sets
(using
.BR FD_ZERO )
is the responsibility of the caller.
.SH RETURN VALUES
.B ares_fds
returns one greater than the number of the highest socket set in either
.I read_fds
or
.IR write_fds .
If no queries are active,
.B ares_fds
will return 0.
.SH SEE ALSO
.BR ares_timeout (3),
.BR ares_process (3)
.SH AUTHOR
Greg Hudson, MIT Information Systems
.br
Copyright 1998 by the Massachusetts Institute of Technology.

58
ares/ares_fds.c Normal file
View File

@ -0,0 +1,58 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
static const char rcsid[] = "$Id$";
#include <sys/types.h>
#ifdef WIN32
#else
#include <sys/time.h>
#endif
#include "ares.h"
#include "ares_private.h"
int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds)
{
struct server_state *server;
int i, nfds;
/* No queries, no file descriptors. */
if (!channel->queries)
return 0;
nfds = 0;
for (i = 0; i < channel->nservers; i++)
{
server = &channel->servers[i];
if (server->udp_socket != -1)
{
FD_SET(server->udp_socket, read_fds);
if (server->udp_socket >= nfds)
nfds = server->udp_socket + 1;
}
if (server->tcp_socket != -1)
{
FD_SET(server->tcp_socket, read_fds);
if (server->qhead)
FD_SET(server->tcp_socket, write_fds);
if (server->tcp_socket >= nfds)
nfds = server->tcp_socket + 1;
}
}
return nfds;
}

42
ares/ares_free_errmem.3 Normal file
View File

@ -0,0 +1,42 @@
.\" $Id$
.\"
.\" Copyright 1998 by the Massachusetts Institute of Technology.
.\"
.\" Permission to use, copy, modify, and distribute this
.\" software and its documentation for any purpose and without
.\" fee is hereby granted, provided that the above copyright
.\" notice appear in all copies and that both that copyright
.\" notice and this permission notice appear in supporting
.\" documentation, and that the name of M.I.T. not be used in
.\" advertising or publicity pertaining to distribution of the
.\" software without specific, written prior permission.
.\" M.I.T. makes no representations about the suitability of
.\" this software for any purpose. It is provided "as is"
.\" without express or implied warranty.
.\"
.TH ARES_FREE_ERRMEM 3 "23 July 1998"
.SH NAME
ares_free_errmem \- Free memory allocated by ares_strerror
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B void ares_free_errmem(char *\fIerrmem\fP)
.fi
.SH DESCRIPTION
The
.B ares_free_errmem
function frees any memory which might have been allocated by the
.BR ares_strerror (3)
function. The parameter
.I errmem
should be set to the variable pointed to by the
.I memptr
argument previously passed to
.IR ares_strerror .
.SH SEE ALSO
.BR ares_strerror (3)
.SH AUTHOR
Greg Hudson, MIT Information Systems
.br
Copyright 1998 by the Massachusetts Institute of Technology.

26
ares/ares_free_errmem.c Normal file
View File

@ -0,0 +1,26 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
static const char rcsid[] = "$Id$";
#include "ares.h"
/* Do nothing, for now. A future implementation may want to deal with
* internationalization, in which case ares_strerror() might allocate
* memory which we would then have to free.
*/
void ares_free_errmem(char *mem)
{
}

49
ares/ares_free_hostent.3 Normal file
View File

@ -0,0 +1,49 @@
.\" $Id$
.\"
.\" Copyright 1998 by the Massachusetts Institute of Technology.
.\"
.\" Permission to use, copy, modify, and distribute this
.\" software and its documentation for any purpose and without
.\" fee is hereby granted, provided that the above copyright
.\" notice appear in all copies and that both that copyright
.\" notice and this permission notice appear in supporting
.\" documentation, and that the name of M.I.T. not be used in
.\" advertising or publicity pertaining to distribution of the
.\" software without specific, written prior permission.
.\" M.I.T. makes no representations about the suitability of
.\" this software for any purpose. It is provided "as is"
.\" without express or implied warranty.
.\"
.TH ARES_FREE_HOSTENT 3 "23 July 1998"
.SH NAME
ares_free_hostent \- Free host structure allocated by ares functions
.SH SYNOPSIS
.nf
.B #include <ares.h>
.PP
.B void ares_free_hostent(struct hostent *\fIhost\fP)
.fi
.SH DESCRIPTION
The
.I ares_free_hostent
function frees a
.B struct hostent
allocated by one of the functions
.I ares_parse_a_reply
or
.IR ares_parse_ptr_reply .
.SH SEE ALSO
.BR ares_parse_a_reply (3),
.BR ares_parse_ptr_reply (3)
.SH NOTES
It is not necessary (and is not correct) to free the host structure
passed to the callback functions for
.I ares_gethostbyname
or
.IR ares_gethostbyaddr .
The ares library will automatically free such host structures when the
callback returns.
.SH AUTHOR
Greg Hudson, MIT Information Systems
.br
Copyright 1998 by the Massachusetts Institute of Technology.

39
ares/ares_free_hostent.c Normal file
View File

@ -0,0 +1,39 @@
/* Copyright 1998 by the Massachusetts Institute of Technology.
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
static const char rcsid[] = "$Id$";
#include <stdlib.h>
#ifdef WIN32
#else
#include <netdb.h>
#endif
#include "ares.h"
void ares_free_hostent(struct hostent *host)
{
char **p;
free(host->h_name);
for (p = host->h_aliases; *p; p++)
free(*p);
free(host->h_aliases);
free(host->h_addr_list[0]);
free(host->h_addr_list);
free(host);
}

37
ares/ares_free_string.3 Normal file
View File

@ -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.

24
ares/ares_free_string.c Normal file
View File

@ -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);
}

100
ares/ares_gethostbyaddr.3 Normal file
View File

@ -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.

174
ares/ares_gethostbyaddr.c Normal file
View File

@ -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;
}

103
ares/ares_gethostbyname.3 Normal file
View File

@ -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.

297
ares/ares_gethostbyname.c Normal file
View File

@ -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;
}

170
ares/ares_init.3 Normal file
View File

@ -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.

776
ares/ares_init.c Normal file
View File

@ -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);
}

2
ares/ares_init_options.3 Normal file
View File

@ -0,0 +1,2 @@
.so man3/ares_init.3
.\" $Id$

79
ares/ares_mkquery.3 Normal file
View File

@ -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.

161
ares/ares_mkquery.c Normal file
View File

@ -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;
}

65
ares/ares_parse_a_reply.3 Normal file
View File

@ -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.

173
ares/ares_parse_a_reply.c Normal file
View File

@ -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;
}

View File

@ -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.

159
ares/ares_parse_ptr_reply.c Normal file
View File

@ -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;
}

145
ares/ares_private.h Normal file
View File

@ -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);

79
ares/ares_process.3 Normal file
View File

@ -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.

625
ares/ares_process.c Normal file
View File

@ -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]);
}
}

142
ares/ares_query.3 Normal file
View File

@ -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.

112
ares/ares_query.c Normal file
View File

@ -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);
}

144
ares/ares_search.3 Normal file
View File

@ -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.

273
ares/ares_search.c Normal file
View File

@ -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;
}

117
ares/ares_send.3 Normal file
View File

@ -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.

104
ares/ares_send.c Normal file
View File

@ -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);
}

44
ares/ares_strerror.3 Normal file
View File

@ -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.

47
ares/ares_strerror.c Normal file
View File

@ -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];
}

64
ares/ares_timeout.3 Normal file
View File

@ -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.

67
ares/ares_timeout.c Normal file
View File

@ -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;
}

1388
ares/config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

1489
ares/config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

18
ares/configure.in Normal file
View File

@ -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)

205
ares/nameser.h Normal file
View File

@ -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

2
ares/vc/adig/adig.dep Normal file
View File

@ -0,0 +1,2 @@
# Microsoft Developer Studio Generated Dependency File, included by adig.mak

106
ares/vc/adig/adig.dsp Normal file
View File

@ -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

213
ares/vc/adig/adig.mak Normal file
View File

@ -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

77
ares/vc/adig/adig.plg Normal file
View File

@ -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>

2
ares/vc/ahost/ahost.dep Normal file
View File

@ -0,0 +1,2 @@
# Microsoft Developer Studio Generated Dependency File, included by ahost.mak

100
ares/vc/ahost/ahost.dsp Normal file
View File

@ -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

223
ares/vc/ahost/ahost.mak Normal file
View File

@ -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

16
ares/vc/ahost/ahost.plg Normal file
View File

@ -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>

View File

@ -0,0 +1,2 @@
# Microsoft Developer Studio Generated Dependency File, included by areslib.mak

196
ares/vc/areslib/areslib.dsp Normal file
View File

@ -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

361
ares/vc/areslib/areslib.mak Normal file
View File

@ -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

125
ares/vc/areslib/areslib.plg Normal file
View File

@ -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>

59
ares/vc/vc.dsw Normal file
View File

@ -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>
{{{
}}}
###############################################################################

BIN
ares/vc/vc.ncb Normal file

Binary file not shown.

BIN
ares/vc/vc.opt Normal file

Binary file not shown.

61
ares/windows_port.c Normal file
View File

@ -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;
}