Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2006-12-11 22:59:06 +0300
committerCorinna Vinschen <corinna@vinschen.de>2006-12-11 22:59:06 +0300
commit0c365c631fc11ec4c1c6fbbeeb194a3609b59b93 (patch)
tree231a49044d876f9088bbb2e632b02ac9c48d047d /winsup
parent12cb181da7dffe5baba2c6ff78f7d35191273b07 (diff)
* Makefile.in (DLL_OFILES): Add minires-os-if.o and minires.o.
(SUBLIBS): Add libresolv.a. Add rule for libresolv.a. * autoload.cc: Fix return code handling for IP Helper API in case of being unable to load iphlpapi.dll. (DnsQuery_A): Define. (DnsRecordListFree): Define. * cygwin.din: Export resolver functions. * include/resolv.h: New header. * include/arpa/nameser.h: New header. * include/arpa/nameser_compat.h: New header. * include/cygwin/version.h: Bump API minor number. * libc/minires-os-if.c: New file. * libc/minires.c: New file. * libc/minires.h: New file.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog18
-rw-r--r--winsup/cygwin/Makefile.in23
-rw-r--r--winsup/cygwin/autoload.cc13
-rw-r--r--winsup/cygwin/cygwin.din35
-rwxr-xr-xwinsup/cygwin/include/arpa/nameser.h563
-rwxr-xr-xwinsup/cygwin/include/arpa/nameser_compat.h231
-rw-r--r--winsup/cygwin/include/cygwin/version.h3
-rwxr-xr-xwinsup/cygwin/include/resolv.h464
-rw-r--r--winsup/cygwin/libc/minires-os-if.c572
-rw-r--r--winsup/cygwin/libc/minires.c916
-rw-r--r--winsup/cygwin/libc/minires.h68
-rw-r--r--winsup/cygwin/sigproc.cc1
12 files changed, 2891 insertions, 16 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index babeec345..64ff7f428 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,21 @@
+2006-12-11 Corinna Vinschen <corinna@vinschen.de>
+
+ * Makefile.in (DLL_OFILES): Add minires-os-if.o and minires.o.
+ (SUBLIBS): Add libresolv.a.
+ Add rule for libresolv.a.
+ * autoload.cc: Fix return code handling for IP Helper API in case
+ of being unable to load iphlpapi.dll.
+ (DnsQuery_A): Define.
+ (DnsRecordListFree): Define.
+ * cygwin.din: Export resolver functions.
+ * include/resolv.h: New header.
+ * include/arpa/nameser.h: New header.
+ * include/arpa/nameser_compat.h: New header.
+ * include/cygwin/version.h: Bump API minor number.
+ * libc/minires-os-if.c: New file.
+ * libc/minires.c: New file.
+ * libc/minires.h: New file.
+
2006-12-11 Christopher Faylor <me@cgf.cx>
* sigproc.cc (child_info::child_info): Move old comment about msv_count
diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in
index bf7ea3de0..c8ef03e63 100644
--- a/winsup/cygwin/Makefile.in
+++ b/winsup/cygwin/Makefile.in
@@ -134,15 +134,15 @@ DLL_OFILES:=assert.o autoload.o bsdlib.o ctype.o cxx.o cygheap.o cygthread.o \
fhandler_tty.o fhandler_virtual.o fhandler_windows.o fhandler_zero.o \
flock.o fnmatch.o fork.o fts.o ftw.o getopt.o glob.o grp.o heap.o \
hookapi.o inet_addr.o inet_network.o init.o ioctl.o ipc.o localtime.o \
- lsearch.o malloc_wrapper.o memmem.o miscfuncs.o mktemp.o mmap.o msg.o \
- net.o netdb.o nftw.o ntea.o passwd.o path.o pinfo.o pipe.o poll.o \
- pthread.o regcomp.o regerror.o regexec.o regfree.o registry.o resource.o \
- rexec.o rcmd.o scandir.o sched.o sec_acl.o sec_helper.o security.o \
- select.o sem.o shared.o shm.o sigfe.o signal.o sigproc.o smallprint.o \
- spawn.o strace.o strptime.o strsep.o strsig.o sync.o syscalls.o \
- sysconf.o syslog.o termios.o thread.o timelocal.o timer.o times.o tty.o \
- uinfo.o uname.o v8_regexp.o v8_regerror.o v8_regsub.o wait.o wincap.o \
- window.o winf.o \
+ lsearch.o malloc_wrapper.o memmem.o minires-os-if.o minires.o \
+ miscfuncs.o mktemp.o mmap.o msg.o net.o netdb.o nftw.o ntea.o passwd.o \
+ path.o pinfo.o pipe.o poll.o pthread.o regcomp.o regerror.o regexec.o \
+ regfree.o registry.o resource.o rexec.o rcmd.o scandir.o sched.o \
+ sec_acl.o sec_helper.o security.o select.o sem.o shared.o shm.o sigfe.o \
+ signal.o sigproc.o smallprint.o spawn.o strace.o strptime.o strsep.o \
+ strsig.o sync.o syscalls.o sysconf.o syslog.o termios.o thread.o \
+ timelocal.o timer.o times.o tty.o uinfo.o uname.o v8_regexp.o \
+ v8_regerror.o v8_regsub.o wait.o wincap.o window.o winf.o \
$(EXTRA_DLL_OFILES) $(EXTRA_OFILES) $(MALLOC_OFILES) $(MT_SAFE_OBJECTS)
GMON_OFILES:=gmon.o mcount.o profil.o
@@ -219,7 +219,7 @@ API_VER:=$(srcdir)/include/cygwin/version.h
PWD:=${shell pwd}
LIB_NAME:=$(PWD)/libcygwin.a
LIBSERVER:=@LIBSERVER@
-SUBLIBS:=$(PWD)/libpthread.a $(PWD)/libutil.a $(PWD)/libm.a $(PWD)/libc.a $(PWD)/libdl.a
+SUBLIBS:=$(PWD)/libpthread.a $(PWD)/libutil.a $(PWD)/libm.a $(PWD)/libc.a $(PWD)/libdl.a $(PWD)/libresolv.a
EXTRALIBS:=libautomode.a libbinmode.a libtextmode.a libtextreadmode.a
INSTOBJS:=automode.o binmode.o textmode.o textreadmode.o
TARGET_LIBS:=$(LIB_NAME) $(CYGWIN_START) $(GMON_START) $(LIBGMON_A) $(SUBLIBS) $(INSTOBJS) $(EXTRALIBS)
@@ -443,6 +443,9 @@ $(PWD)/libc.a: speclib $(LIB_NAME) $(PWD)/libm.a libpthread.a libutil.a
$(PWD)/libdl.a: speclib $(LIB_NAME) dlfcn.o
/bin/sh ${word 1, $^} $@ "${NM}" "$(AR)" ${wordlist 2, 99, $^}
+$(PWD)/libresolv.a: speclib $(LIB_NAME) minires.o
+ /bin/sh ${word 1, $^} $@ "${NM}" "$(AR)" ${wordlist 2, 99, $^}
+
lib%.a: %.o
$(AR) cru $@ $?
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index 1e7fb783a..62e2a3b63 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -492,11 +492,11 @@ LoadDLLfunc (WSASetLastError, 4, ws2_32)
// LoadDLLfunc (WSAStartup, 8, ws2_32)
LoadDLLfunc (WSAWaitForMultipleEvents, 20, ws2_32)
-LoadDLLfuncEx (GetIfTable, 12, iphlpapi, 1)
-LoadDLLfuncEx (GetIfEntry, 4, iphlpapi, 1)
-LoadDLLfuncEx (GetIpAddrTable, 12, iphlpapi, 1)
-LoadDLLfuncEx (GetNetworkParams, 8, iphlpapi, 1)
-LoadDLLfuncEx (GetTcpTable, 12, iphlpapi, 1)
+// 50 = ERROR_NOT_SUPPORTED. Returned if OS doesn't supprot iphlpapi funcs
+LoadDLLfuncEx2 (GetIfEntry, 4, iphlpapi, 1, 50)
+LoadDLLfuncEx2 (GetIpAddrTable, 12, iphlpapi, 1, 50)
+LoadDLLfuncEx2 (GetNetworkParams, 8, iphlpapi, 1, 50)
+LoadDLLfuncEx2 (GetTcpTable, 12, iphlpapi, 1, 50)
LoadDLLfunc (CoTaskMemFree, 4, ole32)
@@ -559,4 +559,7 @@ LoadDLLfunc (WNetCloseEnum, 4, mpr)
LoadDLLfuncEx (UuidCreate, 4, rpcrt4, 1)
LoadDLLfuncEx (UuidCreateSequential, 4, rpcrt4, 1)
+
+LoadDLLfuncEx2 (DnsQuery_A, 24, dnsapi, 1, 127) // ERROR_PROC_NOT_FOUND
+LoadDLLfuncEx (DnsRecordListFree, 8, dnsapi, 1)
}
diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din
index e8a40ede2..c47fd46c8 100644
--- a/winsup/cygwin/cygwin.din
+++ b/winsup/cygwin/cygwin.din
@@ -269,6 +269,12 @@ dll_entry@12 NOSIGFE
dll_noncygwin_dllcrt0 NOSIGFE
dlopen SIGFE
dlsym SIGFE
+dn_comp = __dn_comp SIGFE
+__dn_comp SIGFE
+dn_expand = __dn_expand SIGFE
+__dn_expand SIGFE
+dn_skipname = __dn_skipname SIGFE
+__dn_skipname SIGFE
drand48 NOSIGFE
_drand48 = drand48 NOSIGFE
drem NOSIGFE
@@ -1124,6 +1130,35 @@ remquo NOSIGFE
remquof NOSIGFE
rename SIGFE
_rename = rename SIGFE
+res_close = __res_close SIGFE
+__res_close SIGFE
+res_init = __res_init SIGFE
+__res_init SIGFE
+res_mkquery = __res_mkquery SIGFE
+__res_mkquery SIGFE
+res_nclose = __res_nclose SIGFE
+__res_nclose SIGFE
+res_ninit = __res_ninit SIGFE
+__res_ninit SIGFE
+res_nmkquery = __res_nmkquery SIGFE
+__res_nmkquery SIGFE
+res_nquery = __res_nquery SIGFE
+__res_nquery SIGFE
+res_nquerydomain = __res_nquerydomain SIGFE
+__res_nquerydomain SIGFE
+res_nsearch = __res_nsearch SIGFE
+__res_nsearch SIGFE
+res_nsend = __res_nsend SIGFE
+__res_nsend SIGFE
+res_query = __res_query SIGFE
+__res_query SIGFE
+res_querydomain = __res_querydomain SIGFE
+__res_querydomain SIGFE
+res_search = __res_search SIGFE
+__res_search SIGFE
+res_send = __res_send SIGFE
+__res_send SIGFE
+__res_state SIGFE
revoke SIGFE
rewind SIGFE
_rewind = rewind SIGFE
diff --git a/winsup/cygwin/include/arpa/nameser.h b/winsup/cygwin/include/arpa/nameser.h
new file mode 100755
index 000000000..3980933f5
--- /dev/null
+++ b/winsup/cygwin/include/arpa/nameser.h
@@ -0,0 +1,563 @@
+/*
+ * Copyright (c) 1983, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * $Id$
+ */
+
+#ifndef _ARPA_NAMESER_H_
+#define _ARPA_NAMESER_H_
+
+#ifdef __CYGWIN__
+#define BSD 199903 /* Used inside the .h file */
+#endif
+
+#define BIND_4_COMPAT
+
+#include <sys/param.h>
+#if (!defined(BSD)) || (BSD < 199306)
+# include <sys/bitypes.h>
+#else
+# include <sys/types.h>
+#endif
+#include <sys/cdefs.h>
+
+/*
+ * Revision information. This is the release date in YYYYMMDD format.
+ * It can change every day so the right thing to do with it is use it
+ * in preprocessor commands such as "#if (__NAMESER > 19931104)". Do not
+ * compare for equality; rather, use it to determine whether your libbind.a
+ * contains a new enough lib/nameser/ to support the feature you need.
+ */
+
+#define __NAMESER 19991006 /* New interface version stamp. */
+
+/*
+ * Define constants based on RFC 883, RFC 1034, RFC 1035
+ */
+#define NS_PACKETSZ 512 /* maximum packet size */
+#define NS_MAXDNAME 1025 /* maximum domain name */
+#define NS_MAXCDNAME 255 /* maximum compressed domain name */
+#define NS_MAXLABEL 63 /* maximum length of domain label */
+#define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */
+#define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */
+#define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */
+#define NS_INT32SZ 4 /* #/bytes of data in a u_int32_t */
+#define NS_INT16SZ 2 /* #/bytes of data in a u_int16_t */
+#define NS_INT8SZ 1 /* #/bytes of data in a u_int8_t */
+#define NS_INADDRSZ 4 /* IPv4 T_A */
+#define NS_IN6ADDRSZ 16 /* IPv6 T_AAAA */
+#define NS_CMPRSFLGS 0xc0 /* Flag bits indicating name compression. */
+#define NS_DEFAULTPORT 53 /* For both TCP and UDP. */
+
+/*
+ * These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord()
+ * in synch with it.
+ */
+typedef enum __ns_sect {
+ ns_s_qd = 0, /* Query: Question. */
+ ns_s_zn = 0, /* Update: Zone. */
+ ns_s_an = 1, /* Query: Answer. */
+ ns_s_pr = 1, /* Update: Prerequisites. */
+ ns_s_ns = 2, /* Query: Name servers. */
+ ns_s_ud = 2, /* Update: Update. */
+ ns_s_ar = 3, /* Query|Update: Additional records. */
+ ns_s_max = 4
+} ns_sect;
+
+/*
+ * This is a message handle. It is caller allocated and has no dynamic data.
+ * This structure is intended to be opaque to all but ns_parse.c, thus the
+ * leading _'s on the member names. Use the accessor functions, not the _'s.
+ */
+typedef struct __ns_msg {
+ const u_char *_msg, *_eom;
+ u_int16_t _id, _flags, _counts[ns_s_max];
+ const u_char *_sections[ns_s_max];
+ ns_sect _sect;
+ int _rrnum;
+ const u_char *_msg_ptr;
+} ns_msg;
+
+/* Private data structure - do not use from outside library. */
+struct _ns_flagdata { int mask, shift; };
+extern struct _ns_flagdata _ns_flagdata[];
+
+/* Accessor macros - this is part of the public interface. */
+
+#define ns_msg_id(handle) ((handle)._id + 0)
+#define ns_msg_base(handle) ((handle)._msg + 0)
+#define ns_msg_end(handle) ((handle)._eom + 0)
+#define ns_msg_size(handle) ((handle)._eom - (handle)._msg)
+#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
+
+/*
+ * This is a parsed record. It is caller allocated and has no dynamic data.
+ */
+typedef struct __ns_rr {
+ char name[NS_MAXDNAME];
+ u_int16_t type;
+ u_int16_t rr_class;
+ u_int32_t ttl;
+ u_int16_t rdlength;
+ const u_char * rdata;
+} ns_rr;
+
+/* Accessor macros - this is part of the public interface. */
+#define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".")
+#define ns_rr_type(rr) ((ns_type)((rr).type + 0))
+#define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0))
+#define ns_rr_ttl(rr) ((rr).ttl + 0)
+#define ns_rr_rdlen(rr) ((rr).rdlength + 0)
+#define ns_rr_rdata(rr) ((rr).rdata + 0)
+
+/*
+ * These don't have to be in the same order as in the packet flags word,
+ * and they can even overlap in some cases, but they will need to be kept
+ * in synch with ns_parse.c:ns_flagdata[].
+ */
+typedef enum __ns_flag {
+ ns_f_qr, /* Question/Response. */
+ ns_f_opcode, /* Operation code. */
+ ns_f_aa, /* Authoritative Answer. */
+ ns_f_tc, /* Truncation occurred. */
+ ns_f_rd, /* Recursion Desired. */
+ ns_f_ra, /* Recursion Available. */
+ ns_f_z, /* MBZ. */
+ ns_f_ad, /* Authentic Data (DNSSEC). */
+ ns_f_cd, /* Checking Disabled (DNSSEC). */
+ ns_f_rcode, /* Response code. */
+ ns_f_max
+} ns_flag;
+
+/*
+ * Currently defined opcodes.
+ */
+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;
+
+/*
+ * Currently defined response codes.
+ */
+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;
+
+/* BIND_UPDATE */
+typedef enum __ns_update_operation {
+ ns_uop_delete = 0,
+ ns_uop_add = 1,
+ ns_uop_max = 2
+} ns_update_operation;
+
+/*
+ * This structure is used for TSIG authenticated messages
+ */
+struct ns_tsig_key {
+ char name[NS_MAXDNAME], alg[NS_MAXDNAME];
+ unsigned char *data;
+ int len;
+};
+typedef struct ns_tsig_key ns_tsig_key;
+
+/*
+ * This structure is used for TSIG authenticated TCP messages
+ */
+struct ns_tcp_tsig_state {
+ int counter;
+ struct dst_key *key;
+ void *ctx;
+ unsigned char sig[NS_PACKETSZ];
+ int siglen;
+};
+typedef struct ns_tcp_tsig_state ns_tcp_tsig_state;
+
+#define NS_TSIG_FUDGE 300
+#define NS_TSIG_TCP_COUNT 100
+#define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT"
+
+#define NS_TSIG_ERROR_NO_TSIG -10
+#define NS_TSIG_ERROR_NO_SPACE -11
+#define NS_TSIG_ERROR_FORMERR -12
+
+/*
+ * Currently defined type values for resources and queries.
+ */
+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_tkey = 249, /* Transaction key */
+ 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;
+
+/* Exclusively a QTYPE? (not also an RTYPE) */
+#define ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \
+ (t) == ns_t_mailb || (t) == ns_t_maila)
+/* Some kind of meta-RR? (not a QTYPE, but also not an RTYPE) */
+#define ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt)
+/* Exclusively an RTYPE? (not also a QTYPE or a meta-RR) */
+#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t))
+#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr)
+#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \
+ (t) == ns_t_zxfr)
+
+/*
+ * Values for class field
+ */
+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;
+
+/* DNSSEC constants. */
+
+typedef enum __ns_key_types {
+ ns_kt_rsa = 1, /* key type RSA/MD5 */
+ ns_kt_dh = 2, /* Diffie Hellman */
+ ns_kt_dsa = 3, /* Digital Signature Standard (MANDATORY) */
+ ns_kt_private = 254 /* Private key type starts with OID */
+} ns_key_types;
+
+typedef enum __ns_cert_types {
+ cert_t_pkix = 1, /* PKIX (X.509v3) */
+ cert_t_spki = 2, /* SPKI */
+ cert_t_pgp = 3, /* PGP */
+ cert_t_url = 253, /* URL private type */
+ cert_t_oid = 254 /* OID private type */
+} ns_cert_types;
+
+/* Flags field of the KEY RR rdata. */
+#define NS_KEY_TYPEMASK 0xC000 /* Mask for "type" bits */
+#define NS_KEY_TYPE_AUTH_CONF 0x0000 /* Key usable for both */
+#define NS_KEY_TYPE_CONF_ONLY 0x8000 /* Key usable for confidentiality */
+#define NS_KEY_TYPE_AUTH_ONLY 0x4000 /* Key usable for authentication */
+#define NS_KEY_TYPE_NO_KEY 0xC000 /* No key usable for either; no key */
+/* The type bits can also be interpreted independently, as single bits: */
+#define NS_KEY_NO_AUTH 0x8000 /* Key unusable for authentication */
+#define NS_KEY_NO_CONF 0x4000 /* Key unusable for confidentiality */
+#define NS_KEY_RESERVED2 0x2000 /* Security is *mandatory* if bit=0 */
+#define NS_KEY_EXTENDED_FLAGS 0x1000 /* reserved - must be zero */
+#define NS_KEY_RESERVED4 0x0800 /* reserved - must be zero */
+#define NS_KEY_RESERVED5 0x0400 /* reserved - must be zero */
+#define NS_KEY_NAME_TYPE 0x0300 /* these bits determine the type */
+#define NS_KEY_NAME_USER 0x0000 /* key is assoc. with user */
+#define NS_KEY_NAME_ENTITY 0x0200 /* key is assoc. with entity eg host */
+#define NS_KEY_NAME_ZONE 0x0100 /* key is zone key */
+#define NS_KEY_NAME_RESERVED 0x0300 /* reserved meaning */
+#define NS_KEY_RESERVED8 0x0080 /* reserved - must be zero */
+#define NS_KEY_RESERVED9 0x0040 /* reserved - must be zero */
+#define NS_KEY_RESERVED10 0x0020 /* reserved - must be zero */
+#define NS_KEY_RESERVED11 0x0010 /* reserved - must be zero */
+#define NS_KEY_SIGNATORYMASK 0x000F /* key can sign RR's of same name */
+#define NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \
+ NS_KEY_RESERVED4 | \
+ NS_KEY_RESERVED5 | \
+ NS_KEY_RESERVED8 | \
+ NS_KEY_RESERVED9 | \
+ NS_KEY_RESERVED10 | \
+ NS_KEY_RESERVED11 )
+#define NS_KEY_RESERVED_BITMASK2 0xFFFF /* no bits defined here */
+
+/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */
+#define NS_ALG_MD5RSA 1 /* MD5 with RSA */
+#define NS_ALG_DH 2 /* Diffie Hellman KEY */
+#define NS_ALG_DSA 3 /* DSA KEY */
+#define NS_ALG_DSS NS_ALG_DSA
+#define NS_ALG_EXPIRE_ONLY 253 /* No alg, no security */
+#define NS_ALG_PRIVATE_OID 254 /* Key begins with OID giving alg */
+
+/* Protocol values */
+/* value 0 is reserved */
+#define NS_KEY_PROT_TLS 1
+#define NS_KEY_PROT_EMAIL 2
+#define NS_KEY_PROT_DNSSEC 3
+#define NS_KEY_PROT_IPSEC 4
+#define NS_KEY_PROT_ANY 255
+
+/* Signatures */
+#define NS_MD5RSA_MIN_BITS 512 /* Size of a mod or exp in bits */
+#define NS_MD5RSA_MAX_BITS 2552
+ /* Total of binary mod and exp */
+#define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS+7/8)*2+3)
+ /* Max length of text sig block */
+#define NS_MD5RSA_MAX_BASE64 (((NS_MD5RSA_MAX_BYTES+2)/3)*4)
+#define NS_MD5RSA_MIN_SIZE ((NS_MD5RSA_MIN_BITS+7)/8)
+#define NS_MD5RSA_MAX_SIZE ((NS_MD5RSA_MAX_BITS+7)/8)
+
+#define NS_DSA_SIG_SIZE 41
+#define NS_DSA_MIN_SIZE 213
+#define NS_DSA_MAX_BYTES 405
+
+/* Offsets into SIG record rdata to find various values */
+#define NS_SIG_TYPE 0 /* Type flags */
+#define NS_SIG_ALG 2 /* Algorithm */
+#define NS_SIG_LABELS 3 /* How many labels in name */
+#define NS_SIG_OTTL 4 /* Original TTL */
+#define NS_SIG_EXPIR 8 /* Expiration time */
+#define NS_SIG_SIGNED 12 /* Signature time */
+#define NS_SIG_FOOT 16 /* Key footprint */
+#define NS_SIG_SIGNER 18 /* Domain name of who signed it */
+
+/* How RR types are represented as bit-flags in NXT records */
+#define NS_NXT_BITS 8
+#define NS_NXT_BIT_SET( n,p) (p[(n)/NS_NXT_BITS] |= (0x80>>((n)%NS_NXT_BITS)))
+#define NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS)))
+#define NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] & (0x80>>((n)%NS_NXT_BITS)))
+#define NS_NXT_MAX 127
+
+/*
+ * Inline versions of get/put short/long. Pointer is advanced.
+ */
+#define NS_GET16(s, cp) do { \
+ register const u_char *t_cp = (const u_char *)(cp); \
+ (s) = ((u_int16_t)t_cp[0] << 8) \
+ | ((u_int16_t)t_cp[1]) \
+ ; \
+ (cp) += NS_INT16SZ; \
+} while (0)
+
+#define NS_GET32(l, cp) do { \
+ register const u_char *t_cp = (const u_char *)(cp); \
+ (l) = ((u_int32_t)t_cp[0] << 24) \
+ | ((u_int32_t)t_cp[1] << 16) \
+ | ((u_int32_t)t_cp[2] << 8) \
+ | ((u_int32_t)t_cp[3]) \
+ ; \
+ (cp) += NS_INT32SZ; \
+} while (0)
+
+#define NS_PUT16(s, cp) do { \
+ register u_int16_t t_s = (u_int16_t)(s); \
+ register u_char *t_cp = (u_char *)(cp); \
+ *t_cp++ = t_s >> 8; \
+ *t_cp = t_s; \
+ (cp) += NS_INT16SZ; \
+} while (0)
+
+#define NS_PUT32(l, cp) do { \
+ register u_int32_t t_l = (u_int32_t)(l); \
+ register u_char *t_cp = (u_char *)(cp); \
+ *t_cp++ = t_l >> 24; \
+ *t_cp++ = t_l >> 16; \
+ *t_cp++ = t_l >> 8; \
+ *t_cp = t_l; \
+ (cp) += NS_INT32SZ; \
+} while (0)
+
+/*
+ * ANSI C identifier hiding for bind's lib/nameser.
+ */
+#define ns_msg_getflag __ns_msg_getflag
+#define ns_get16 __ns_get16
+#define ns_get32 __ns_get32
+#define ns_put16 __ns_put16
+#define ns_put32 __ns_put32
+#define ns_initparse __ns_initparse
+#define ns_skiprr __ns_skiprr
+#define ns_parserr __ns_parserr
+#define ns_sprintrr __ns_sprintrr
+#define ns_sprintrrf __ns_sprintrrf
+#define ns_format_ttl __ns_format_ttl
+#define ns_parse_ttl __ns_parse_ttl
+#define ns_datetosecs __ns_datetosecs
+#define ns_name_ntol __ns_name_ntol
+#define ns_name_ntop __ns_name_ntop
+#define ns_name_pton __ns_name_pton
+#define ns_name_unpack __ns_name_unpack
+#define ns_name_pack __ns_name_pack
+#define ns_name_compress __ns_name_compress
+#define ns_name_uncompress __ns_name_uncompress
+#define ns_name_skip __ns_name_skip
+#define ns_name_rollback __ns_name_rollback
+#define ns_sign __ns_sign
+#define ns_sign_tcp __ns_sign_tcp
+#define ns_sign_tcp_init __ns_sign_tcp_init
+#define ns_find_tsig __ns_find_tsig
+#define ns_verify __ns_verify
+#define ns_verify_tcp __ns_verify_tcp
+#define ns_verify_tcp_init __ns_verify_tcp_init
+#define ns_samedomain __ns_samedomain
+#define ns_subdomain __ns_subdomain
+#define ns_makecanon __ns_makecanon
+#define ns_samename __ns_samename
+
+__BEGIN_DECLS
+int ns_msg_getflag __P((ns_msg, int));
+u_int ns_get16 __P((const u_char *));
+u_long ns_get32 __P((const u_char *));
+void ns_put16 __P((u_int, u_char *));
+void ns_put32 __P((u_long, u_char *));
+int ns_initparse __P((const u_char *, int, ns_msg *));
+int ns_skiprr __P((const u_char *, const u_char *, ns_sect, int));
+int ns_parserr __P((ns_msg *, ns_sect, int, ns_rr *));
+int ns_sprintrr __P((const ns_msg *, const ns_rr *,
+ const char *, const char *, char *, size_t));
+int ns_sprintrrf __P((const u_char *, size_t, const char *,
+ ns_class, ns_type, u_long, const u_char *,
+ size_t, const char *, const char *,
+ char *, size_t));
+int ns_format_ttl __P((u_long, char *, size_t));
+int ns_parse_ttl __P((const char *, u_long *));
+u_int32_t ns_datetosecs __P((const char *cp, int *errp));
+int ns_name_ntol __P((const u_char *, u_char *, size_t));
+int ns_name_ntop __P((const u_char *, char *, size_t));
+int ns_name_pton __P((const char *, u_char *, size_t));
+int ns_name_unpack __P((const u_char *, const u_char *,
+ const u_char *, u_char *, size_t));
+int ns_name_pack __P((const u_char *, u_char *, int,
+ const u_char **, const u_char **));
+int ns_name_uncompress __P((const u_char *, const u_char *,
+ const u_char *, char *, size_t));
+int ns_name_compress __P((const char *, u_char *, size_t,
+ const u_char **, const u_char **));
+int ns_name_skip __P((const u_char **, const u_char *));
+void ns_name_rollback __P((const u_char *, const u_char **,
+ const u_char **));
+int ns_sign __P((u_char *, int *, int, int, void *,
+ const u_char *, int, u_char *, int *, time_t));
+int ns_sign_tcp __P((u_char *, int *, int, int,
+ ns_tcp_tsig_state *, int));
+int ns_sign_tcp_init __P((void *, const u_char *, int,
+ ns_tcp_tsig_state *));
+u_char *ns_find_tsig __P((u_char *, u_char *));
+int ns_verify __P((u_char *, int *, void *,
+ const u_char *, int, u_char *, int *,
+ time_t *, int));
+int ns_verify_tcp __P((u_char *, int *, ns_tcp_tsig_state *, int));
+int ns_verify_tcp_init __P((void *, const u_char *, int,
+ ns_tcp_tsig_state *));
+int ns_samedomain __P((const char *, const char *));
+int ns_subdomain __P((const char *, const char *));
+int ns_makecanon __P((const char *, char *, size_t));
+int ns_samename __P((const char *, const char *));
+__END_DECLS
+
+#ifdef BIND_4_COMPAT
+#include <arpa/nameser_compat.h>
+#endif
+
+#endif /* !_ARPA_NAMESER_H_ */
diff --git a/winsup/cygwin/include/arpa/nameser_compat.h b/winsup/cygwin/include/arpa/nameser_compat.h
new file mode 100755
index 000000000..a75f9bc13
--- /dev/null
+++ b/winsup/cygwin/include/arpa/nameser_compat.h
@@ -0,0 +1,231 @@
+/* Copyright (c) 1983, 1989
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * from nameser.h 8.1 (Berkeley) 6/2/93
+ * $Id$
+ */
+
+#ifndef _ARPA_NAMESER_COMPAT_
+#define _ARPA_NAMESER_COMPAT_
+
+#define __BIND 19950621 /* (DEAD) interface version stamp. */
+
+#ifndef BYTE_ORDER
+#if (BSD >= 199103)
+# include <machine/endian.h>
+#else
+#ifdef linux
+# include <endian.h>
+#else
+#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */
+#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */
+#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp)*/
+
+#if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \
+ defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \
+ defined(__alpha__) || defined(__alpha) || \
+ (defined(__Lynx__) && defined(__x86__))
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif
+
+#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \
+ defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \
+ defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\
+ defined(apollo) || defined(__convex__) || defined(_CRAY) || \
+ defined(__hppa) || defined(__hp9000) || \
+ defined(__hp9000s300) || defined(__hp9000s700) || \
+ defined(__hp3000s900) || defined(MPE) || \
+ defined (BIT_ZERO_ON_LEFT) || defined(m68k) || \
+ (defined(__Lynx__) && \
+ (defined(__68k__) || defined(__sparc__) || defined(__powerpc__)))
+#define BYTE_ORDER BIG_ENDIAN
+#endif
+#endif /* linux */
+#endif /* BSD */
+#endif /* BYTE_ORDER */
+
+#if !defined(BYTE_ORDER) || \
+ (BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN && \
+ BYTE_ORDER != PDP_ENDIAN)
+ /* you must determine what the correct bit order is for
+ * your compiler - the next line is an intentional error
+ * which will force your compiles to bomb until you fix
+ * the above macros.
+ */
+ error "Undefined or invalid BYTE_ORDER";
+#endif
+
+/*
+ * Structure for query header. The order of the fields is machine- and
+ * compiler-dependent, depending on the byte/bit order and the layout
+ * of bit fields. We use bit fields only in int variables, as this
+ * is all ANSI requires. This requires a somewhat confusing rearrangement.
+ */
+
+typedef struct {
+ unsigned id :16; /* query identification number */
+#if BYTE_ORDER == BIG_ENDIAN
+ /* fields in third byte */
+ unsigned qr: 1; /* response flag */
+ unsigned opcode: 4; /* purpose of message */
+ unsigned aa: 1; /* authoritive answer */
+ unsigned tc: 1; /* truncated message */
+ unsigned rd: 1; /* recursion desired */
+ /* fields in fourth byte */
+ unsigned ra: 1; /* recursion available */
+ unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
+ unsigned ad: 1; /* authentic data from named */
+ unsigned cd: 1; /* checking disabled by resolver */
+ unsigned rcode :4; /* response code */
+#endif
+#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
+ /* fields in third byte */
+ unsigned rd :1; /* recursion desired */
+ unsigned tc :1; /* truncated message */
+ unsigned aa :1; /* authoritive answer */
+ unsigned opcode :4; /* purpose of message */
+ unsigned qr :1; /* response flag */
+ /* fields in fourth byte */
+ unsigned rcode :4; /* response code */
+ unsigned cd: 1; /* checking disabled by resolver */
+ unsigned ad: 1; /* authentic data from named */
+ unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
+ unsigned ra :1; /* recursion available */
+#endif
+ /* remaining bytes */
+ unsigned qdcount :16; /* number of question entries */
+ unsigned ancount :16; /* number of answer entries */
+ unsigned nscount :16; /* number of authority entries */
+ unsigned arcount :16; /* number of resource entries */
+} HEADER;
+
+#define PACKETSZ NS_PACKETSZ
+#define MAXDNAME NS_MAXDNAME
+#define MAXCDNAME NS_MAXCDNAME
+#define MAXLABEL NS_MAXLABEL
+#define HFIXEDSZ NS_HFIXEDSZ
+#define QFIXEDSZ NS_QFIXEDSZ
+#define RRFIXEDSZ NS_RRFIXEDSZ
+#define INT32SZ NS_INT32SZ
+#define INT16SZ NS_INT16SZ
+#define INADDRSZ NS_INADDRSZ
+#define IN6ADDRSZ NS_IN6ADDRSZ
+#define INDIR_MASK NS_CMPRSFLGS
+#define NAMESERVER_PORT NS_DEFAULTPORT
+
+#define S_ZONE ns_s_zn
+#define S_PREREQ ns_s_pr
+#define S_UPDATE ns_s_ud
+#define S_ADDT ns_s_ar
+
+#define QUERY ns_o_query
+#define IQUERY ns_o_iquery
+#define STATUS ns_o_status
+#define NS_NOTIFY_OP ns_o_notify
+#define NS_UPDATE_OP ns_o_update
+
+#define NOERROR ns_r_noerror
+#define FORMERR ns_r_formerr
+#define SERVFAIL ns_r_servfail
+#define NXDOMAIN ns_r_nxdomain
+#define NOTIMP ns_r_notimpl
+#define REFUSED ns_r_refused
+#define YXDOMAIN ns_r_yxdomain
+#define YXRRSET ns_r_yxrrset
+#define NXRRSET ns_r_nxrrset
+#define NOTAUTH ns_r_notauth
+#define NOTZONE ns_r_notzone
+/*#define BADSIG ns_r_badsig*/
+/*#define BADKEY ns_r_badkey*/
+/*#define BADTIME ns_r_badtime*/
+
+
+#define DELETE ns_uop_delete
+#define ADD ns_uop_add
+
+#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_A6 ns_t_a6
+#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
+
+#define C_IN ns_c_in
+#define C_CHAOS ns_c_chaos
+#define C_HS ns_c_hs
+/* BIND_UPDATE */
+#define C_NONE ns_c_none
+#define C_ANY ns_c_any
+
+#define GETSHORT NS_GET16
+#define GETLONG NS_GET32
+#define PUTSHORT NS_PUT16
+#define PUTLONG NS_PUT32
+
+#endif /* _ARPA_NAMESER_COMPAT_ */
diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h
index 30ae75800..dd448aef2 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -295,12 +295,13 @@ details. */
rresvport_af.
159: Export posix_openpt.
160: Export posix_fadvice, posix_fallocate.
+ 161: Export resolver functions.
*/
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 160
+#define CYGWIN_VERSION_API_MINOR 161
/* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible
diff --git a/winsup/cygwin/include/resolv.h b/winsup/cygwin/include/resolv.h
new file mode 100755
index 000000000..dfefa0f85
--- /dev/null
+++ b/winsup/cygwin/include/resolv.h
@@ -0,0 +1,464 @@
+/*
+ * Copyright (c) 1983, 1987, 1989
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * @(#)resolv.h 8.1 (Berkeley) 6/2/93
+ * $Id$
+ */
+
+#ifndef _RESOLV_H_
+#define _RESOLV_H_
+
+#include <sys/param.h>
+#if !defined(__CYGWIN__) && ((!defined(BSD)) || (BSD < 199306))
+# include <sys/bitypes.h>
+#else
+# include <sys/types.h>
+#endif
+#include <sys/cdefs.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <arpa/nameser.h>
+
+/*
+ * Revision information. This is the release date in YYYYMMDD format.
+ * It can change every day so the right thing to do with it is use it
+ * in preprocessor commands such as "#if (__RES > 19931104)". Do not
+ * compare for equality; rather, use it to determine whether your resolver
+ * is new enough to contain a certain feature.
+ */
+
+#define __RES 19991006
+
+/*
+ * This used to be defined in res_query.c, now it's in herror.c.
+ * [XXX no it's not. It's in irs/irs_data.c]
+ * It was
+ * never extern'd by any *.h file before it was placed here. For thread
+ * aware programs, the last h_errno value set is stored in res->h_errno.
+ *
+ * XXX: There doesn't seem to be a good reason for exposing RES_SET_H_ERRNO
+ * (and __h_errno_set) to the public via <resolv.h>.
+ * XXX: __h_errno_set is really part of IRS, not part of the resolver.
+ * If somebody wants to build and use a resolver that doesn't use IRS,
+ * what do they do? Perhaps something like
+ * #ifdef WANT_IRS
+ * # define RES_SET_H_ERRNO(r,x) __h_errno_set(r,x)
+ * #else
+ * # define RES_SET_H_ERRNO(r,x) (h_errno = (r)->res_h_errno = (x))
+ * #endif
+ */
+
+#define RES_SET_H_ERRNO(r,x) __h_errno_set(r,x)
+struct __res_state; /* forward */
+__BEGIN_DECLS
+void __h_errno_set(struct __res_state *res, int err);
+__END_DECLS
+
+/*
+ * Resolver configuration file.
+ * Normally not present, but may contain the address of the
+ * inital name server(s) to query and the domain search list.
+ */
+
+#ifndef _PATH_RESCONF
+#define _PATH_RESCONF "/etc/resolv.conf"
+#endif
+
+typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error }
+ res_sendhookact;
+
+typedef res_sendhookact (*res_send_qhook)__P((struct sockaddr * const *ns,
+ const u_char **query,
+ int *querylen,
+ u_char *ans,
+ int anssiz,
+ int *resplen));
+
+typedef res_sendhookact (*res_send_rhook)__P((const struct sockaddr *ns,
+ const u_char *query,
+ int querylen,
+ u_char *ans,
+ int anssiz,
+ int *resplen));
+
+struct res_sym {
+ int number; /* Identifying number, like T_MX */
+ const char * name; /* Its symbolic name, like "MX" */
+ const char * humanname; /* Its fun name, like "mail exchanger" */
+};
+
+/*
+ * Global defines and variables for resolver stub.
+ */
+#define MAXNS 3 /* max # name servers we'll track */
+#define MAXDFLSRCH 3 /* # default domain levels to try */
+#define MAXDNSRCH 6 /* max # domains in search path */
+#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */
+
+#define RES_TIMEOUT 5 /* min. seconds between retries */
+#define MAXRESOLVSORT 10 /* number of net to sort on */
+#define RES_MAXNDOTS 15 /* should reflect bit field size */
+#define RES_MAXRETRANS 30 /* only for resolv.conf/RES_OPTIONS */
+#define RES_MAXRETRY 5 /* only for resolv.conf/RES_OPTIONS */
+#define RES_DFLRETRY 2 /* Default #/tries. */
+#define RES_MAXTIME 65535 /* Infinity, in milliseconds. */
+
+struct __res_state_ext;
+
+struct __res_state {
+ int retrans; /* retransmition time interval */
+ int retry; /* number of times to retransmit */
+ u_long options; /* option flags - see below. */
+ int nscount; /* number of name servers */
+ struct sockaddr_in
+ nsaddr_list[MAXNS]; /* address of name server */
+#define nsaddr nsaddr_list[0] /* for backward compatibility */
+ u_short id; /* current message id */
+ char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */
+ char defdname[256]; /* default domain (deprecated) */
+ u_long pfcode; /* RES_PRF_ flags - see below. */
+ unsigned ndots:4; /* threshold for initial abs. query */
+ unsigned nsort:4; /* number of elements in sort_list[] */
+ char unused[3];
+ struct {
+ struct in_addr addr;
+ u_int32_t mask;
+ } sort_list[MAXRESOLVSORT];
+ res_send_qhook qhook; /* query hook */
+ res_send_rhook rhook; /* response hook */
+ int res_h_errno; /* last one set for this context */
+ int _vcsock; /* PRIVATE: for res_send VC i/o */
+ u_int _flags; /* PRIVATE: see below */
+ union {
+ /* On an 32-bit arch this means 512b total. */
+ char pad[72 - 3*sizeof (int) - 2*sizeof (void *)];
+ struct {
+ u_int16_t nscount;
+ u_int16_t nstimes[MAXNS]; /* ms. */
+ int nssocks[MAXNS];
+ struct __res_state_ext *ext; /* extention for IPv6 */
+ } _ext;
+ } _u;
+};
+
+typedef struct __res_state *res_state;
+
+union res_sockaddr_union {
+ struct sockaddr_in sin;
+#ifdef IN6ADDR_ANY_INIT
+ struct sockaddr_in6 sin6;
+#endif
+#ifdef ISC_ALIGN64
+ int64_t __align; /* 64bit alignment */
+#else
+ int32_t __align; /* 32bit alignment */
+#endif
+ char __space[128]; /* max size */
+};
+
+/*
+ * Resolver flags (used to be discrete per-module statics ints).
+ */
+#define RES_F_VC 0x00000001 /* socket is TCP */
+#define RES_F_CONN 0x00000002 /* socket is connected */
+#define RES_F_EDNS0ERR 0x00000004 /* EDNS0 caused errors */
+
+/* res_findzonecut() options */
+#define RES_EXHAUSTIVE 0x00000001 /* always do all queries */
+
+/*
+ * Resolver options (keep these in synch with res_debug.c, please)
+ */
+#define RES_INIT 0x00000001 /* address initialized */
+#define RES_DEBUG 0x00000002 /* print debug messages */
+#define RES_AAONLY 0x00000004 /* authoritative answers only (!IMPL)*/
+#define RES_USEVC 0x00000008 /* use virtual circuit */
+#define RES_PRIMARY 0x00000010 /* query primary server only (!IMPL) */
+#define RES_IGNTC 0x00000020 /* ignore trucation errors */
+#define RES_RECURSE 0x00000040 /* recursion desired */
+#define RES_DEFNAMES 0x00000080 /* use default domain name */
+#define RES_STAYOPEN 0x00000100 /* Keep TCP socket open */
+#define RES_DNSRCH 0x00000200 /* search up local domain tree */
+#define RES_INSECURE1 0x00000400 /* type 1 security disabled */
+#define RES_INSECURE2 0x00000800 /* type 2 security disabled */
+#define RES_NOALIASES 0x00001000 /* shuts off HOSTALIASES feature */
+#define RES_USE_INET6 0x00002000 /* use/map IPv6 in gethostbyname() */
+#define RES_ROTATE 0x00004000 /* rotate ns list after each query */
+#define RES_NOCHECKNAME 0x00008000 /* do not check names for sanity. */
+#define RES_KEEPTSIG 0x00010000 /* do not strip TSIG records */
+#define RES_BLAST 0x00020000 /* blast all recursive servers */
+#define RES_NO_NIBBLE 0x00040000 /* disable IPv6 nibble mode reverse */
+#define RES_NO_BITSTRING 0x00080000 /* disable IPv6 bit string mode reverse */
+/* KAME extensions: use higher bit to avoid conflict with ISC use */
+#define RES_USE_DNAME 0x10000000 /* use DNAME */
+#define RES_USE_A6 0x20000000 /* use A6 */
+#define RES_USE_EDNS0 0x40000000 /* use EDNS0 if configured */
+
+#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH)
+
+/*
+ * Resolver "pfcode" values. Used by dig.
+ */
+#define RES_PRF_STATS 0x00000001
+#define RES_PRF_UPDATE 0x00000002
+#define RES_PRF_CLASS 0x00000004
+#define RES_PRF_CMD 0x00000008
+#define RES_PRF_QUES 0x00000010
+#define RES_PRF_ANS 0x00000020
+#define RES_PRF_AUTH 0x00000040
+#define RES_PRF_ADD 0x00000080
+#define RES_PRF_HEAD1 0x00000100
+#define RES_PRF_HEAD2 0x00000200
+#define RES_PRF_TTLID 0x00000400
+#define RES_PRF_HEADX 0x00000800
+#define RES_PRF_QUERY 0x00001000
+#define RES_PRF_REPLY 0x00002000
+#define RES_PRF_INIT 0x00004000
+/* 0x00008000 */
+
+/* Things involving an internal (static) resolver context. */
+#if defined(_REENTRANT) || defined(__CYGWIN__)
+__BEGIN_DECLS
+extern struct __res_state *__res_state(void);
+__END_DECLS
+#define _res (*__res_state())
+#else
+#ifndef __BIND_NOSTATIC
+extern struct __res_state _res;
+#endif
+#endif
+
+#ifndef __BIND_NOSTATIC
+#define fp_nquery __fp_nquery
+#define fp_query __fp_query
+#define hostalias __hostalias
+#define p_query __p_query
+#define res_close __res_close
+#define res_init __res_init
+#define res_isourserver __res_isourserver
+#define res_mkquery __res_mkquery
+#define res_query __res_query
+#define res_querydomain __res_querydomain
+#define res_search __res_search
+#define res_send __res_send
+#define res_sendsigned __res_sendsigned
+
+__BEGIN_DECLS
+void fp_nquery __P((const u_char *, int, FILE *));
+void fp_query __P((const u_char *, FILE *));
+const char * hostalias __P((const char *));
+void p_query __P((const u_char *));
+void res_close __P((void));
+int res_init __P((void));
+int res_isourserver __P((const struct sockaddr_in *));
+int res_mkquery __P((int, const char *, int, int, const u_char *,
+ int, const u_char *, u_char *, int));
+int res_query __P((const char *, int, int, u_char *, int));
+int res_querydomain __P((const char *, const char *, int, int,
+ u_char *, int));
+int res_search __P((const char *, int, int, u_char *, int));
+int res_send __P((const u_char *, int, u_char *, int));
+int res_sendsigned __P((const u_char *, int, ns_tsig_key *,
+ u_char *, int));
+__END_DECLS
+#endif
+
+#if !defined(SHARED_LIBBIND) || defined(LIB)
+/*
+ * If libbind is a shared object (well, DLL anyway)
+ * these externs break the linker when resolv.h is
+ * included by a lib client (like named)
+ * Make them go away if a client is including this
+ *
+ */
+extern const struct res_sym __p_key_syms[];
+extern const struct res_sym __p_cert_syms[];
+extern const struct res_sym __p_class_syms[];
+extern const struct res_sym __p_type_syms[];
+extern const struct res_sym __p_rcode_syms[];
+#endif /* SHARED_LIBBIND */
+
+#define b64_ntop __b64_ntop
+#define b64_pton __b64_pton
+#define dn_comp __dn_comp
+#define dn_count_labels __dn_count_labels
+#define dn_expand __dn_expand
+#define dn_skipname __dn_skipname
+#define fp_resstat __fp_resstat
+#define loc_aton __loc_aton
+#define loc_ntoa __loc_ntoa
+#define p_cdname __p_cdname
+#define p_cdnname __p_cdnname
+#define p_class __p_class
+#define p_fqname __p_fqname
+#define p_fqnname __p_fqnname
+#define p_option __p_option
+#define p_secstodate __p_secstodate
+#define p_section __p_section
+#define p_time __p_time
+#define p_type __p_type
+#define p_rcode __p_rcode
+#define putlong __putlong
+#define putshort __putshort
+#define res_dnok __res_dnok
+#define res_findzonecut __res_findzonecut
+#define res_hnok __res_hnok
+#define res_hostalias __res_hostalias
+#define res_mailok __res_mailok
+#define res_nameinquery __res_nameinquery
+#define res_nclose __res_nclose
+#define res_ninit __res_ninit
+#define res_nmkquery __res_nmkquery
+#define res_pquery __res_pquery
+#define res_nquery __res_nquery
+#define res_nquerydomain __res_nquerydomain
+#define res_nsearch __res_nsearch
+#define res_nsend __res_nsend
+#define res_nsendsigned __res_nsendsigned
+#define res_nisourserver __res_nisourserver
+#define res_ownok __res_ownok
+#define res_queriesmatch __res_queriesmatch
+#define res_randomid __res_randomid
+#define sym_ntop __sym_ntop
+#define sym_ntos __sym_ntos
+#define sym_ston __sym_ston
+#define res_nopt __res_nopt
+#define res_ndestroy __res_ndestroy
+#define res_nametoclass __res_nametoclass
+#define res_nametotype __res_nametotype
+#define res_setservers __res_setservers
+#define res_getservers __res_getservers
+__BEGIN_DECLS
+int res_hnok __P((const char *));
+int res_ownok __P((const char *));
+int res_mailok __P((const char *));
+int res_dnok __P((const char *));
+int sym_ston __P((const struct res_sym *, const char *, int *));
+const char * sym_ntos __P((const struct res_sym *, int, int *));
+const char * sym_ntop __P((const struct res_sym *, int, int *));
+int b64_ntop __P((u_char const *, size_t, char *, size_t));
+int b64_pton __P((char const *, u_char *, size_t));
+int loc_aton __P((const char *ascii, u_char *binary));
+const char * loc_ntoa __P((const u_char *binary, char *ascii));
+int dn_skipname __P((const u_char *, const u_char *));
+void putlong __P((u_int32_t, u_char *));
+void putshort __P((u_int16_t, u_char *));
+#ifndef __ultrix__
+u_int16_t _getshort __P((const u_char *src));
+u_int32_t _getlong __P((const u_char *src));
+#endif
+const char * p_class __P((int));
+const char * p_time __P((u_int32_t));
+const char * p_type __P((int));
+const char * p_rcode __P((int));
+const u_char * p_cdnname __P((const u_char *, const u_char *, int, FILE *));
+const u_char * p_cdname __P((const u_char *, const u_char *, FILE *));
+const u_char * p_fqnname __P((const u_char *cp, const u_char *msg,
+ int, char *, int));
+const u_char * p_fqname __P((const u_char *, const u_char *, FILE *));
+const char * p_option __P((u_long option));
+char * p_secstodate __P((u_long));
+int dn_count_labels __P((const char *));
+int dn_comp __P((const char *, u_char *, int,
+ u_char **, u_char **));
+int dn_expand __P((const u_char *, const u_char *, const u_char *,
+ char *, int));
+u_int res_randomid __P((void));
+int res_nameinquery __P((const char *, int, int,
+ const u_char *, const u_char *));
+int res_queriesmatch __P((const u_char *, const u_char *,
+ const u_char *, const u_char *));
+const char * p_section __P((int section, int opcode));
+/* Things involving a resolver context. */
+int res_ninit __P((res_state));
+int res_nisourserver __P((const res_state,
+ const struct sockaddr_in *));
+void fp_resstat __P((const res_state, FILE *));
+void res_pquery __P((const res_state, const u_char *, int, FILE *));
+const char * res_hostalias __P((const res_state, const char *,
+ char *, size_t));
+int res_nquery __P((res_state,
+ const char *, int, int, u_char *, int));
+int res_nsearch __P((res_state, const char *, int,
+ int, u_char *, int));
+int res_nquerydomain __P((res_state,
+ const char *, const char *, int, int,
+ u_char *, int));
+int res_nmkquery __P((res_state,
+ int, const char *, int, int, const u_char *,
+ int, const u_char *, u_char *, int));
+int res_nsend __P((res_state, const u_char *, int, u_char *, int));
+int res_nsendsigned __P((res_state, const u_char *, int,
+ ns_tsig_key *, u_char *, int));
+int res_findzonecut __P((res_state, const char *, ns_class, int,
+ char *, size_t, struct in_addr *, int));
+void res_nclose __P((res_state));
+int res_nopt __P((res_state, int, u_char *, int, int));
+void res_send_setqhook __P((res_send_qhook hook));
+void res_send_setrhook __P((res_send_rhook hook));
+int __res_vinit __P((res_state, int));
+void res_destroyservicelist __P((void));
+const char * res_servicename __P((u_int16_t port, const char *proto));
+const char * res_protocolname __P((int num));
+void res_destroyprotolist __P((void));
+void res_buildprotolist __P((void));
+const char * res_get_nibblesuffix __P((res_state));
+const char * res_get_bitstringsuffix __P((res_state));
+void res_ndestroy __P((res_state));
+u_int16_t res_nametoclass __P((const char *buf, int *success));
+u_int16_t res_nametotype __P((const char *buf, int *success));
+void res_setservers __P((res_state,
+ const union res_sockaddr_union *, int));
+int res_getservers __P((res_state,
+ union res_sockaddr_union *, int));
+__END_DECLS
+
+#endif /* !_RESOLV_H_ */
diff --git a/winsup/cygwin/libc/minires-os-if.c b/winsup/cygwin/libc/minires-os-if.c
new file mode 100644
index 000000000..28676cada
--- /dev/null
+++ b/winsup/cygwin/libc/minires-os-if.c
@@ -0,0 +1,572 @@
+/* minires-os-if.c. Stub synchronous resolver for Cygwin.
+
+ Copyright 2006 Red Hat, Inc.
+
+ Written by Pierre A. Humblet <Pierre.Humblet@ieee.org>
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#include "minires.h"
+
+#ifdef __CYGWIN__
+/***********************************************************************
+ *
+ Windows interface code
+
+***********************************************************************/
+
+/* Conflict between Windows definitions and others */
+#undef ERROR
+#undef NOERROR
+#undef DELETE
+
+#include <windows.h>
+#include <iphlpapi.h>
+#include <windns.h>
+#include <sys/cygwin.h>
+
+/***********************************************************************
+ *
+ write_record: Translates a Windows DNS record into a compressed record
+
+ ***********************************************************************/
+
+#define PUTDOMAIN(d,p)\
+ {int res = dn_comp(d, p, EndPtr - p, dnptrs, lastdnptr); p += res < 0 ? strlen(d) : res; }
+
+static u_char * write_record(unsigned char * ptr, PDNS_RECORD rr, unsigned char * EndPtr,
+ unsigned char ** dnptrs, unsigned char ** lastdnptr, int debug)
+{
+ u_char * rd_length_ptr;
+
+ PUTDOMAIN(rr->pName, ptr);
+
+ if (ptr + 4 > EndPtr)
+ ptr += 4;
+ else {
+ PUTSHORT(rr->wType, ptr);
+ PUTSHORT(ns_c_in, ptr);
+ }
+ if ((rr->Flags.DW & 0x3) == DnsSectionQuestion)
+ return ptr;
+
+ if (ptr + 4 > EndPtr)
+ ptr += 4;
+ else {
+ PUTLONG(rr->dwTtl, ptr);
+ }
+ rd_length_ptr = ptr;
+ ptr += 2; /* Placeholder for RDLENGTH */
+
+ /* The default case uses an undocumented feature of the Windows
+ resolver for types greater than 16.
+ The DNS_RECORD Data contains the record in wire format. */
+
+ switch(rr->wType) {
+ case DNS_TYPE_A:
+ {
+ u_char * aptr = (u_char *) & rr->Data.A.IpAddress;
+ if (ptr + 4 <= EndPtr) {
+ ptr[0] = aptr[0];
+ ptr[1] = aptr[1];
+ ptr[2] = aptr[2];
+ ptr[3] = aptr[3];
+ }
+ ptr += 4;
+ break;
+ }
+ case DNS_TYPE_NS:
+ case DNS_TYPE_MD:
+ case DNS_TYPE_MF:
+ case DNS_TYPE_CNAME:
+ case DNS_TYPE_MB:
+ case DNS_TYPE_MG:
+ case DNS_TYPE_MR:
+ case DNS_TYPE_PTR:
+ PUTDOMAIN(rr->Data.PTR.pNameHost, ptr);
+ break;
+ case DNS_TYPE_SOA:
+ PUTDOMAIN(rr->Data.SOA.pNamePrimaryServer, ptr);
+ PUTDOMAIN(rr->Data.SOA.pNameAdministrator, ptr);
+ if (ptr + 20 > EndPtr)
+ ptr += 20;
+ else {
+ PUTLONG(rr->Data.SOA.dwSerialNo, ptr);
+ PUTLONG(rr->Data.SOA.dwRefresh, ptr);
+ PUTLONG(rr->Data.SOA.dwRetry, ptr);
+ PUTLONG(rr->Data.SOA.dwExpire, ptr);
+ PUTLONG(rr->Data.SOA.dwDefaultTtl, ptr);
+ }
+ break;
+ case DNS_TYPE_NULL:
+ if (ptr + rr->Data.Null.dwByteCount <= EndPtr)
+ memcpy(ptr, rr->Data.Null.Data, rr->Data.Null.dwByteCount);
+ ptr += rr->Data.Null.dwByteCount;
+ if (rr->Data.Null.dwByteCount == rr->wDataLength - sizeof(DNS_NULL_DATA) + 1)
+ DPRINTF(debug, "Null byte count has an unexpected value\n");
+ break;
+ case DNS_TYPE_WKS:
+ if (ptr + rr->wDataLength - sizeof(DNS_WKS_DATA) + 1 + 5 > EndPtr)
+ ptr += rr->wDataLength - sizeof(DNS_WKS_DATA) + 1 + 5;
+ else {
+ PUTLONG(rr->Data.WKS.IpAddress, ptr);
+ *ptr++ = rr->Data.WKS.chProtocol;
+ memcpy(ptr, rr->Data.WKS.BitMask, rr->wDataLength - sizeof(DNS_WKS_DATA) + 1);
+ ptr += rr->wDataLength - sizeof(DNS_WKS_DATA) + 1;
+ }
+ break;
+ case DNS_TYPE_MINFO:
+ PUTDOMAIN(rr->Data.MINFO.pNameMailbox, ptr);
+ PUTDOMAIN(rr->Data.MINFO.pNameErrorsMailbox, ptr);
+ break;
+ case DNS_TYPE_MX:
+ if (ptr + 2 > EndPtr)
+ ptr += 2;
+ else
+ PUTSHORT(rr->Data.MX.wPreference, ptr);
+ PUTDOMAIN(rr->Data.MX.pNameExchange, ptr);
+ break;
+ case DNS_TYPE_HINFO:
+ case DNS_TYPE_TEXT:
+ {
+ unsigned int i, len;
+ for (i = 0; i < rr->Data.TXT.dwStringCount; i++) {
+ len = strlen(rr->Data.TXT.pStringArray[i]) & 0xFF;
+ if (ptr + len + 1 > EndPtr)
+ ptr += len + 1;
+ else {
+ *ptr++ = len;
+ memcpy(ptr, rr->Data.TXT.pStringArray[i], len);
+ ptr += len;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ unsigned int len = rr->wDataLength;
+ DPRINTF(debug, "No structure for wType %d\n", rr->wType);
+ if (ptr + len <= EndPtr)
+ memcpy(ptr, (char *) &rr->Data, len);
+ ptr += len;
+ break;
+ }
+ }
+ if (rd_length_ptr + 2 <= EndPtr)
+ PUTSHORT(ptr - rd_length_ptr - 2, rd_length_ptr);
+ return ptr;
+}
+
+/***********************************************************************
+ *
+ cygwin_query: implements res_nquery by calling DnsQuery
+
+ ***********************************************************************/
+static int cygwin_query(res_state statp, const char * DomName, int Class, int Type,
+ unsigned char * AnsPtr, int AnsLength)
+{
+ DNS_STATUS res;
+ PDNS_RECORD pQueryResultsSet, rr;
+ int section, len, counts[4] = {0, 0, 0, 0}, debug = statp->options & RES_DEBUG;
+ unsigned char * dnptrs[256], * ptr;
+
+ dnptrs[0] = AnsPtr;
+ dnptrs[1] = NULL;
+
+ if (Class != ns_c_in) {
+ errno = ENOSYS;
+ statp->res_h_errno = NETDB_INTERNAL;
+ return -1;
+ }
+
+ res = DnsQuery_A(DomName, Type, DNS_QUERY_TREAT_AS_FQDN,
+ NULL, &pQueryResultsSet, NULL);
+#if 0
+#define NETDB_INTERNAL -1 /* see errno */
+#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
+#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
+#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+#define NO_DATA 4 /* Valid name, no data record of requested type */
+#endif
+
+ DPRINTF(debug, "DnsQuery: %lu (Windows)\n", res);
+ if (res) {
+ switch (res) {
+ case ERROR_PROC_NOT_FOUND:
+ errno = ENOSYS;
+ statp->res_h_errno = NO_RECOVERY;
+ break;
+ case ERROR_INVALID_NAME:
+ errno = EINVAL;
+ statp->res_h_errno = NETDB_INTERNAL;;
+ break;
+ case ERROR_TIMEOUT:
+ statp->res_h_errno = TRY_AGAIN;
+ break;
+ case DNS_ERROR_RCODE_NAME_ERROR:
+ statp->res_h_errno = HOST_NOT_FOUND;
+ break;
+ case DNS_ERROR_RCODE_SERVER_FAILURE:
+ statp->res_h_errno = TRY_AGAIN;
+ break;
+ case DNS_ERROR_NO_DNS_SERVERS:
+ case DNS_ERROR_RCODE_FORMAT_ERROR:
+ case DNS_ERROR_RCODE_NOT_IMPLEMENTED:
+ case DNS_ERROR_RCODE_REFUSED:
+ statp->res_h_errno = NO_RECOVERY;
+ break;
+ case DNS_INFO_NO_RECORDS: /* May be returned even if the host doesn't exist */
+ statp->res_h_errno = NO_DATA;
+ break;
+ default:
+ DPRINTF(debug, "Unknown code %lu for %s %d\n", res, DomName, Type);
+ statp->res_h_errno = NO_RECOVERY;
+ break;
+ }
+ len = -1;
+ goto done;
+ }
+
+ ptr = AnsPtr + HFIXEDSZ; /* Skip header */
+
+ rr = pQueryResultsSet;
+ section = 0;
+ while (rr) {
+ if (!counts[0] && (rr->Flags.DW & 0x3)) {
+ /* No question. Adopt the first name as the name in the question */
+ if ((len = dn_comp(rr->pName, ptr, AnsLength - 4,
+ dnptrs, &dnptrs[DIM(dnptrs) - 1])) < 0) {
+ ptr = NULL;
+ break;
+ }
+ ptr += len;
+ PUTSHORT(Type, ptr);
+ PUTSHORT(ns_c_in, ptr);
+ counts[0] = 1;
+ }
+
+ DPRINTF(debug, "%s Section %d Type %u Windows Record Length %u\n",
+ rr->pName, rr->Flags.DW & 0x3, rr->wType, rr->wDataLength);
+
+ /* Check the records are in correct section order */
+ if ((rr->Flags.DW & 0x3) < section) {
+ DPRINTF(debug, "Unexpected section order %s %d\n", DomName, Type);
+ continue;
+ }
+ section = rr->Flags.DW & 0x3;
+
+ ptr = write_record(ptr, rr, AnsPtr + AnsLength, dnptrs,
+ &dnptrs[DIM(dnptrs) - 1], debug);
+
+ counts[section]++;
+ rr = rr->pNext;
+ }
+
+ DnsRecordListFree(pQueryResultsSet, DnsFreeRecordList);
+
+ len = ptr - AnsPtr;
+done:
+ ptr = AnsPtr;
+ PUTSHORT(0, ptr); /* Id */
+ PUTSHORT((QR << 8) + RA + RD, ptr);
+ for (section = 0; section < DIM(counts); section++) {
+ PUTSHORT(counts[section], ptr);
+ }
+ return len;
+}
+
+/***********************************************************************
+ *
+ get_registry_items: returns dns items from the registry
+
+ kHey: Handle to registry key
+ KeyValue: key value to read
+ what: 0 addresses ; 1 search list
+
+***********************************************************************/
+static void get_registry_dns_items(HKEY hKey, LPCTSTR KeyValue,
+ res_state statp, int what)
+{
+ DWORD size = 0;
+ LONG res;
+ LPBYTE list;
+ int debug = statp->options & RES_DEBUG;
+
+ res = RegQueryValueEx( hKey, KeyValue, NULL, NULL, NULL, &size);
+ DPRINTF(debug, "value %s, error %lu (Windows), size %lu\n",
+ KeyValue, res, size);
+ if ((res == ERROR_SUCCESS) && (size > 1)) {
+ if (!(list = (LPBYTE) alloca(size))) {
+ DPRINTF(debug, "alloca: %s\n", strerror(errno));
+ }
+ else if ((res = RegQueryValueEx( hKey, KeyValue, NULL, NULL, list,
+ &size )) != ERROR_SUCCESS) {
+ DPRINTF(debug, "RegQueryValueEx: error %lu (Windows)\n", res);
+ }
+ else if (what == 0) { /* Get the addresses */
+ BYTE *ap, *srch;
+ int numAddresses = 0;
+ for (ap = list; ap < list + size && *ap; ap = srch) {
+ /* The separation character can be 0, ' ', or ','. */
+ for (srch = ap; *srch && (isdigit(*srch) || *srch == '.' ); srch++);
+ *srch++ = 0;
+ if (numAddresses < DIM(statp->nsaddr_list)) {
+ DPRINTF(debug, "server \"%s\"\n", ap);
+ statp->nsaddr_list[numAddresses].sin_addr.s_addr = cygwin_inet_addr(ap);
+ if ( statp->nsaddr_list[numAddresses].sin_addr.s_addr != 0 )
+ numAddresses++;
+ }
+ else
+ DPRINTF(debug, "no space for server \"%s\"\n", ap);
+ }
+ statp->nscount = numAddresses;
+ }
+ else /* Parse the search line */
+ minires_get_search(list, statp);
+ }
+ return;
+}
+
+/***********************************************************************
+ *
+ get_registry_dns:
+
+ Read the registry to get dns server addresses in Network Byte Order,
+ and set statp->nscount
+ (for Win9x and NT <= 4.0, but not Win95 with DHCP)
+ Read the registry SearchList
+
+***********************************************************************/
+
+static void get_registry_dns(res_state statp)
+{
+ HKEY hKey;
+ DWORD res;
+ const char *keyName[] = {"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+ "System\\CurrentControlSet\\Services\\VxD\\MSTCP"};
+ int is9x = !!(GetVersion() & 0x80000000);
+
+ DPRINTF(statp->options & RES_DEBUG, "key %s\n", keyName[is9x]);
+ if ((res = RegOpenKeyEx( HKEY_LOCAL_MACHINE, keyName[is9x], 0,
+ KEY_QUERY_VALUE | KEY_READ, &hKey)) != ERROR_SUCCESS) {
+ DPRINTF(statp->options & RES_DEBUG, "RegOpenKeyEx: error %lu (Windows)\n", res);
+ return;
+ }
+
+ if (statp->nscount == 0)
+ get_registry_dns_items(hKey, "NameServer", statp, 0);
+ if (statp->nscount == 0 && !is9x)
+ get_registry_dns_items(hKey, "DhcpNameServer", statp, 0);
+ if (statp->dnsrch[0] == NULL)
+ get_registry_dns_items(hKey, "SearchList", statp, 1);
+
+ RegCloseKey(hKey);
+
+ return;
+}
+
+/***********************************************************************
+ *
+ get_dns_info: Get the search list or the domain name
+ and the dns server addresses in Network Byte Order
+ Set statp->os_query if DnsQuery is available.
+
+***********************************************************************/
+void get_dns_info(res_state statp)
+{
+#if MAX_HOSTNAME_LEN > MAXHOSTNAMELEN
+#define MAX_HOSTNAME_SIZE (MAX_HOSTNAME_LEN + 1)
+#else
+#define MAX_HOSTNAME_SIZE (MAXHOSTNAMELEN + 1)
+#endif
+#if MAX_HOSTNAME_SIZE > 256 /* sizeof(defdname) */
+#error stap->defdname too short
+#endif
+
+ int res, debug = statp->options & RES_DEBUG;
+
+ ULONG ulOutBufLen = 0;
+ DWORD dwRetVal;
+ IP_ADDR_STRING * pIPAddr;
+ FIXED_INFO * pFixedInfo;
+ HINSTANCE kerneldll;
+ typedef DWORD WINAPI (*GNPType)(PFIXED_INFO, PULONG);
+ GNPType PGetNetworkParams;
+ int numAddresses = 0;
+
+ if (statp->use_os) {
+ DPRINTF(debug, "using dnsapi.dll\n");
+ statp->os_query = (typeof(statp->os_query)) cygwin_query;
+ /* We just need the search list. Avoid loading iphlpapi. */
+ statp->nscount = -1;
+ }
+
+ if (statp->nscount != 0)
+ goto use_registry;
+
+ if (!(kerneldll = LoadLibrary("IPHLPAPI.DLL"))) {
+ DPRINTF(debug, "LoadLibrary: error %lu (Windows)\n", GetLastError());
+ goto use_registry;
+ }
+ if (!(PGetNetworkParams = (GNPType) GetProcAddress(kerneldll,
+ "GetNetworkParams"))) {
+ DPRINTF(debug, "GetProcAddress: error %lu (Windows)\n", GetLastError());
+ goto use_registry;
+ }
+ /* First call to get the buffer length we need */
+ dwRetVal = PGetNetworkParams((FIXED_INFO *) 0, &ulOutBufLen);
+ if (dwRetVal != ERROR_BUFFER_OVERFLOW) {
+ DPRINTF(debug, "GetNetworkParams: error %lu (Windows)\n", dwRetVal);
+ goto use_registry;
+ }
+ if ((pFixedInfo = (FIXED_INFO *) alloca(ulOutBufLen)) == 0) {
+ DPRINTF(debug, "alloca: %s\n", strerror(errno));
+ goto use_registry;
+ }
+ if ((dwRetVal = PGetNetworkParams((FIXED_INFO *) pFixedInfo, & ulOutBufLen))) {
+ DPRINTF(debug, "GetNetworkParams: error %lu (Windows)\n", dwRetVal);
+ goto use_registry;
+ }
+
+ DPRINTF(debug, "GetNetworkParams: OK\n");
+ /* Record server addresses, up to array size */
+ for (pIPAddr = &(pFixedInfo->DnsServerList), numAddresses = 0;
+ pIPAddr;
+ pIPAddr = pIPAddr->Next) {
+ if (numAddresses < DIM(statp->nsaddr_list)) {
+ DPRINTF(debug, "server \"%s\"\n", pIPAddr->IpAddress.String);
+ statp->nsaddr_list[numAddresses].sin_addr.s_addr = cygwin_inet_addr(pIPAddr->IpAddress.String);
+ if (statp->nsaddr_list[numAddresses].sin_addr.s_addr != 0) {
+ numAddresses++;
+ statp->nscount++;
+ }
+ }
+ else
+ DPRINTF(debug, "no space for server \"%s\"\n", pIPAddr->IpAddress.String);
+ }
+
+ use_registry:
+ get_registry_dns(statp);
+
+ if (!statp->dnsrch[0]) {
+ statp->defdname[sizeof(statp->defdname) - 1] = 0;
+ if (!(res = getdomainname(statp->defdname, sizeof(statp->defdname)))) {
+ if (statp->defdname[0] && !statp->defdname[sizeof(statp->defdname) - 1])
+ statp->dnsrch[0] = statp->defdname;
+ }
+ DPRINTF(debug, "getdomainname \"%s\"\n",
+ (res)? strerror(errno) : statp->defdname);
+ }
+}
+
+#else
+/***********************************************************************
+ *
+ Default interface code
+
+***********************************************************************/
+
+void get_dns_info(res_state statp)
+{
+ return;
+}
+
+#endif
+
+
+
+#if 0
+#define DNS_ERROR_RCODE_FORMAT_ERROR 9001L
+#define DNS_ERROR_RCODE_SERVER_FAILURE 9002L
+#define DNS_ERROR_RCODE_NAME_ERROR 9003L
+#define DNS_ERROR_RCODE_NOT_IMPLEMENTED 9004L
+#define DNS_ERROR_RCODE_REFUSED 9005L
+#define DNS_ERROR_RCODE_YXDOMAIN 9006L
+#define DNS_ERROR_RCODE_YXRRSET 9007L
+#define DNS_ERROR_RCODE_NXRRSET 9008L
+#define DNS_ERROR_RCODE_NOTAUTH 9009L
+#define DNS_ERROR_RCODE_NOTZONE 9010L
+#define DNS_ERROR_RCODE_BADSIG 9016L
+#define DNS_ERROR_RCODE_BADKEY 9017L
+#define DNS_ERROR_RCODE_BADTIME 9018L
+#define DNS_INFO_NO_RECORDS 9501L
+#define DNS_ERROR_BAD_PACKET 9502L
+#define DNS_ERROR_NO_PACKET 9503L
+#define DNS_ERROR_RCODE 9504L
+#define DNS_ERROR_UNSECURE_PACKET 9505L
+#define DNS_ERROR_INVALID_TYPE 9551L
+#define DNS_ERROR_INVALID_IP_ADDRESS 9552L
+#define DNS_ERROR_INVALID_PROPERTY 9553L
+#define DNS_ERROR_TRY_AGAIN_LATER 9554L
+#define DNS_ERROR_NOT_UNIQUE 9555L
+#define DNS_ERROR_NON_RFC_NAME 9556L
+#define DNS_STATUS_FQDN 9557L
+#define DNS_STATUS_DOTTED_NAME 9558L
+#define DNS_STATUS_SINGLE_PART_NAME 9559L
+#define DNS_ERROR_INVALID_NAME_CHAR 9560L
+#define DNS_ERROR_NUMERIC_NAME 9561L
+#define DNS_ERROR_NOT_LALOWED_ON_ROOT_SERVER 9562L
+#define DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION 9563L
+#define DNS_ERROR_CANNOT_FIND_ROOT_HINTS 9564L
+#define DNS_ERROR_INCONSISTENT_ROOT_HINTS 9565L
+#define DNS_ERROR_ZONE_DOES_NOT_EXIST 9601L
+#define DNS_ERROR_NO_ZONE_INFO 9602L
+#define DNS_ERROR_INVALID_ZONE_OPERATION 9603L
+#define DNS_ERROR_ZONE_CONFIGURATION_ERROR 9604L
+#define DNS_ERROR_ZONE_HAS_NO_SOA_RECORD 9605L
+#define DNS_ERROR_ZONE_HAS_NO_NS_RECORDS 9606L
+#define DNS_ERROR_ZONE_LOCKED 9607L
+#define DNS_ERROR_ZONE_CREATION_FAILED 9608L
+#define DNS_ERROR_ZONE_ALREADY_EXISTS 9609L
+#define DNS_ERROR_AUTOZONE_ALREADY_EXISTS 9610L
+#define DNS_ERROR_INVALID_ZONE_TYPE 9611L
+#define DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP 9612L
+#define DNS_ERROR_ZONE_NOT_SECONDARY 9613L
+#define DNS_ERROR_NEED_SECONDARY_ADDRESSES 9614L
+#define DNS_ERROR_WINS_INIT_FAILED 9615L
+#define DNS_ERROR_NEED_WINS_SERVERS 9616L
+#define DNS_ERROR_NBSTAT_INIT_FAILED 9617L
+#define DNS_ERROR_SOA_DELETE_INVALID 9618L
+#define DNS_ERROR_FORWARDER_ALREADY_EXISTS 9619L
+#define DNS_ERROR_ZONE_REQUIRES_MASTER_IP 9620L
+#define DNS_ERROR_ZONE_IS_SHUTDOWN 9621L
+#define DNS_ERROR_PRIMARY_REQUIRES_DATAFILE 9651L
+#define DNS_ERROR_INVALID_DATAFILE_NAME 9652L
+#define DNS_ERROR_DATAFILE_OPEN_FAILURE 9653L
+#define DNS_ERROR_FILE_WRITEBACK_FAILED 9654L
+#define DNS_ERROR_DATAFILE_PARSING 9655L
+#define DNS_ERROR_RECORD_DOES_NOT_EXIST 9701L
+#define DNS_ERROR_RECORD_FORMAT 9702L
+#define DNS_ERROR_NODE_CREATION_FAILED 9703L
+#define DNS_ERROR_UNKNOWN_RECORD_TYPE 9704L
+#define DNS_ERROR_RECORD_TIMED_OUT 9705L
+#define DNS_ERROR_NAME_NOT_IN_ZONE 9706L
+#define DNS_ERROR_CNAME_LOOP 9707L
+#define DNS_ERROR_NODE_IS_CNAME 9708L
+#define DNS_ERROR_CNAME_COLLISION 9709L
+#define DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT 9710L
+#define DNS_ERROR_RECORD_ALREADY_EXISTS 9711L
+#define DNS_ERROR_SECONDARY_DATA 9712L
+#define DNS_ERROR_NO_CREATE_CACHE_DATA 9713L
+#define DNS_ERROR_NAME_DOES_NOT_EXIST 9714L
+#define DNS_WARNING_PTR_CREATE_FAILED 9715L
+#define DNS_WARNING_DOMAIN_UNDELETED 9716L
+#define DNS_ERROR_DS_UNAVAILABLE 9717L
+#define DNS_ERROR_DS_ZONE_ALREADY_EXISTS 9718L
+#define DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE 9719L
+#define DNS_INFO_AXFR_COMPLETE 9751L
+#define DNS_ERROR_AXFR 9752L
+#define DNS_INFO_ADDED_LOCAL_WINS 9753L
+#define DNS_STATUS_CONTINUE_NEEDED 9801L
+#define DNS_ERROR_NO_TCPIP 9851L
+#define DNS_ERROR_NO_DNS_SERVERS 9852L
+#define DNS_ERROR_DP_DOES_NOT_EXIST 9901L
+#define DNS_ERROR_DP_ALREADY_EXISTS 9902L
+#define DNS_ERROR_DP_NOT_ENLISTED 9903L
+#define DNS_ERROR_DP_ALREADY_ENLISTED 9904L
+#define DNS_ERROR_DP_NOT_AVAILABLE 9905L
+#endif
diff --git a/winsup/cygwin/libc/minires.c b/winsup/cygwin/libc/minires.c
new file mode 100644
index 000000000..4c9495831
--- /dev/null
+++ b/winsup/cygwin/libc/minires.c
@@ -0,0 +1,916 @@
+/* minires.c. Stub synchronous resolver for Cygwin.
+
+ Copyright 2006 Red Hat, Inc.
+
+ Written by Pierre A. Humblet <Pierre.Humblet@ieee.org>
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#include "minires.h"
+
+/***********************************************************************
+
+Utilities
+
+***********************************************************************/
+/***********************************************************************
+
+dprintf
+***********************************************************************/
+void minires_dprintf(const char * format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ fprintf(stderr, "Minires: ");
+ vfprintf(stderr, format, args);
+ va_end(args);
+}
+
+/***********************************************************************
+
+scanline
+Put pointers in list[] to the beginning of each space or comma delimited
+word in "in", and put the lengths in sizes[] (counting the final 0).
+Return the number of words found
+***********************************************************************/
+static int scanline(char * in, char **list, int * sizes, int maxnum)
+{
+ int i;
+ char * startp;
+ for (i = 0; i < maxnum; i++) {
+ while((*in) && (isspace(*in) || *in == ',')) in++;
+ if (*in == 0)
+ break;
+ startp = in++;
+ while((*in) && !isspace(*in) && *in != ',') in++;
+ list[i] = startp;
+ sizes[i] = in - startp + 1;
+ if (*in)
+ *in++ = 0;
+ }
+ return i;
+}
+
+/***********************************************************************
+
+Read the search string.
+
+***********************************************************************/
+void minires_get_search(char * string, res_state statp)
+{
+ char * words[MAXDNSRCH+1], * ptr;
+ int sizes[MAXDNSRCH+1];
+ int i, j, debug = statp->options & RES_DEBUG;
+
+ i = scanline(string, words, sizes, MAXDNSRCH+1);
+ ptr = statp->defdname;
+ for (j = 0; j < i; j++) {
+ if (j < MAXDNSRCH
+ && ptr + sizes[j] < &statp->defdname[DIM(statp->defdname)]) {
+ statp->dnsrch[j] = strcpy(ptr, words[j]);
+ statp->dnsrch[j+1] = NULL;
+ ptr += sizes[j];
+ DPRINTF(debug, "search \"%s\"\n", words[j]);
+ }
+ else
+ DPRINTF(debug, "no space for \"%s\"\n", words[j]);
+ }
+}
+
+/***********************************************************************
+
+Read options
+
+
+***********************************************************************/
+static void get_options(res_state statp, int i, char **words)
+{
+ char *ptr;
+ int value;
+
+ while (i-- > 0) {
+ if (!strcasecmp("debug", words[i])) {
+ statp->options |= RES_DEBUG;
+ DPRINTF(statp->options & RES_DEBUG, "%s: 1\n", words[i]);
+ continue;
+ }
+ if (!strcasecmp("osquery", words[i])) {
+ statp->use_os = 1;
+ DPRINTF(statp->options & RES_DEBUG, "%s: 1\n", words[i]);
+ continue;
+ }
+
+ if ((ptr = strchr(words[i], ':'))) {
+ *ptr++ = 0;
+ value = atoi(ptr);
+ /* Not supported
+ if (!strcasecmp("ndots", words[i])) {
+ statp->ndots = value;
+ continue;
+ }
+ */
+ if (!strcasecmp("retry", words[i])) {
+ if (value < 1)
+ value = 1;
+ statp->retry = value;
+ DPRINTF(statp->options & RES_DEBUG, "%s: %d\n", words[i], value);
+ continue;
+ }
+ if (!strcasecmp("retrans", words[i])) {
+ if (value < 1)
+ value = 1;
+ statp->retrans = value;
+ DPRINTF(statp->options & RES_DEBUG, "%s: %d\n", words[i], value);
+ continue;
+ }
+ }
+ DPRINTF(statp->options & RES_DEBUG, "unknown option: \"%s\"\n", words[i]);
+ }
+}
+
+/***********************************************************************
+
+Read the resolv.conf file.
+We only look for nameserver, domain, search and options
+
+***********************************************************************/
+#if MAXNS > MAXDNSRCH + 1
+#define MAXSIZE MAXNS
+#else
+#define MAXSIZE MAXDNSRCH + 1 /* Make unused one visible */
+#endif
+static void get_resolv(res_state statp)
+{
+ FILE * fd;
+ char *words[MAXSIZE + 1], line[4096], *ptr;
+ int sizes[DIM(words)];
+ int i, j, ns = 0, have_search, have_address, debug = statp->options & RES_DEBUG;
+
+ fd = fopen(_PATH_RESCONF, "r");
+ DPRINTF(debug, _PATH_RESCONF ": %s\n", fd?"OK":strerror(errno));
+ if (fd == NULL)
+ return;
+
+ statp->use_os = 0; /* Do not use os_query, except if allowed by "options" */
+ have_search = (statp->dnsrch[0] != NULL);
+ have_address = (statp->nscount != 0);
+
+ while ( fgets(line, sizeof(line), fd) != 0) {
+ DPRINTF(debug, "resolv.conf %s", line);
+ if ((i = scanline(line, words, sizes, DIM(words))) > 0) {
+ if (!have_address
+ && !strncasecmp("nameserver", words[0], sizes[0])) {
+ for ( j = 1; j < i ; j++) {
+ unsigned int address;
+ address = cygwin_inet_addr(words[j]);
+ if (address == -1) {
+ DPRINTF(debug, "invalid server \"%s\"\n", words[j]);
+ }
+ else if (ns >= MAXNS) {
+ DPRINTF(debug, "no space for server \"%s\"\n", words[j]);
+ }
+ else {
+ statp->nsaddr_list[ns++].sin_addr.s_addr = address;
+ statp->nscount++;
+ DPRINTF(debug, "server \"%s\"\n", words[j]);
+ }
+ }
+ }
+ else if (!have_search
+ && (!strncasecmp("search", words[0], sizes[0])
+ || !strncasecmp("domain", words[0], sizes[0]))) {
+ ptr = statp->defdname;
+ for (j = 0; j + 1 < i; j++) {
+ if (j < MAXDNSRCH
+ && ptr + sizes[j + 1] < &statp->defdname[DIM(statp->defdname)]) {
+ statp->dnsrch[j] = strcpy(ptr, words[j+1]);
+ statp->dnsrch[j+1] = 0;
+ ptr += sizes[j+1];
+ DPRINTF(debug, "domain|search \"%s\"\n", statp->dnsrch[j]);
+ }
+ else {
+ DPRINTF(debug, "no space for \"%s\"\n", words[j+1]);
+ }
+ }
+ }
+ /* Options line */
+ else if (!strncasecmp("options", words[0], sizes[0]))
+ get_options(statp, i - 1, &words[1]);
+ }
+ }
+ fclose(fd);
+ return;
+}
+
+/****************************************************************************/
+/*
+ open_sock()
+ Create a datagram socket and call bind.
+
+****************************************************************************/
+
+static int open_sock(struct sockaddr_in *CliAddr, int debug)
+{
+ int fd;
+
+ DPRINTF(debug, "opening UDP socket\n");
+
+ /* Create a datagram socket */
+ if ((fd = cygwin_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+ DPRINTF(debug, "socket(UDP): %s\n", strerror(errno));
+ return -1;
+ }
+ CliAddr->sin_family = AF_INET;
+ CliAddr->sin_addr.s_addr = htonl(INADDR_ANY);
+ CliAddr->sin_port = htons(0);
+ bzero(CliAddr->sin_zero, sizeof(CliAddr->sin_zero));
+ /* Get a port */
+ if (cygwin_bind(fd, (struct sockaddr *) CliAddr, sizeof(*CliAddr)) < 0) {
+ DPRINTF(debug, "bind: %s\n", strerror(errno));
+ return -1;
+ }
+ return fd;
+}
+
+/*****************************************************************
+ *
+ __res_state()
+ Undocumented but public. Accessed through _res
+
+ *****************************************************************/
+static struct __res_state res;
+struct __res_state *__res_state(void)
+{
+ return & res;
+}
+
+/*****************************************************************
+ *
+ res_init()
+
+ *****************************************************************/
+int res_ninit(res_state statp)
+{
+ int i;
+ char * ptr;
+
+ statp->res_h_errno = NETDB_SUCCESS;
+ statp->nscount = 0;
+ statp->os_query = NULL;
+ statp->retrans = RES_TIMEOUT; /* timeout in seconds */
+ statp->retry = RES_MAXRETRY; /* max number of retries */
+ statp->use_os = 1; /* use os_query if available and allowed by get_resolv */
+ statp->mypid = -1;
+ statp->sockfd = -1;
+
+ for (i = 0; i < DIM(statp->dnsrch); i++) statp->dnsrch[i] = 0;
+
+ /* Get search list from LOCALDOMAIN */
+ if ((ptr = getenv("LOCALDOMAIN")) != 0 ) {
+ DPRINTF(statp->options & RES_DEBUG, "LOCALDOMAIN \"%s\"\n", ptr);
+ minires_get_search(ptr, statp); /* domain or dnsrch */
+ }
+ /* resolv.conf (dns servers & search list)*/
+ get_resolv(statp);
+ /* Get dns servers and search list from an os-specific routine, set os_query */
+ get_dns_info(statp);
+
+ if (statp->nscount == 0 && !statp->os_query) {
+ errno = ENONET;
+ statp->res_h_errno = NETDB_INTERNAL;
+ DPRINTF(statp->options & RES_DEBUG, "no dns server found\n");
+ return -1;
+ }
+ for (i = 0; i < statp->nscount; i++) {
+ statp->nsaddr_list[i].sin_family = AF_INET;
+ statp->nsaddr_list[i].sin_port = htons(NAMESERVER_PORT);
+ bzero(statp->nsaddr_list[i].sin_zero, sizeof(statp->nsaddr_list[i].sin_zero));
+ }
+ /* Only debug may be set before calling init */
+ statp->options &= RES_DEBUG;
+ statp->options |= RES_INIT | RES_DEFAULT;
+ return 0;
+}
+
+int res_init()
+{
+ int r = res_ninit(& res);
+ h_errno = res.res_h_errno;
+ return r;
+}
+
+/*****************************************************************
+ *
+ res_close()
+
+ *****************************************************************/
+void res_nclose(res_state statp)
+{
+ int res;
+ if (statp->sockfd != -1) {
+ res = close(statp->sockfd);
+ DPRINTF(statp->options & RES_DEBUG, "close sockfd %d: %s\n",
+ statp->sockfd, (res == 0)?"OK":strerror(errno));
+ statp->sockfd = -1;
+ }
+}
+
+void res_close()
+{
+ res_nclose(& res);
+}
+
+/*****************************************************************
+ *
+ get_tcp_buf()
+
+ *****************************************************************/
+static int get_tcp_buf(int fd, unsigned char *buf, int size, int debug)
+{
+ int res;
+ while (size > 0) {
+ if ((res = read(fd, buf, size)) < 0) {
+ DPRINTF(debug, "read: %s\n", strerror(errno));
+ return -1;
+ }
+ DPRINTF(debug, "read %d out of %d\n", res, size);
+ size -= res;
+ buf += res;
+ }
+ return 0;
+}
+
+/*****************************************************************
+ *
+ get_tcp()
+
+ *****************************************************************/
+static int get_tcp(struct sockaddr_in *CliAddr,
+ const unsigned char * MsgPtr, int MsgLength,
+ unsigned char * AnsPtr, int AnsLength, int debug)
+{
+ int fd, res = -1;
+ unsigned short ans_length;
+ union {short len; u_char buf[sizeof(short)];} len_buf;
+
+ DPRINTF(debug, "retrying with TCP\n");
+
+ /* Create a tcp socket */
+ if ((fd = cygwin_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+ DPRINTF(debug, "socket(TCP): %s\n", strerror(errno));
+ return -1;
+ }
+
+ if (cygwin_connect(fd, (struct sockaddr *) CliAddr, sizeof(* CliAddr)) < 0) {
+ DPRINTF(debug, "connect: %s\n", strerror(errno));
+ goto done;
+ }
+
+ /* Send the length then the message */
+ len_buf.len = htons(MsgLength);
+ if (write(fd, len_buf.buf, sizeof(len_buf)) != sizeof(len_buf)
+ || write(fd, MsgPtr, MsgLength) != MsgLength) {
+ DPRINTF(debug, "write: %s\n", strerror(errno));
+ goto done;
+ }
+
+ /* Read the answer length */
+ if (get_tcp_buf(fd, len_buf.buf, sizeof(len_buf), debug))
+ goto done;
+ ans_length = ntohs(len_buf.len);
+
+ /* Read the answer */
+ if (get_tcp_buf(fd, AnsPtr, MIN(ans_length, AnsLength), debug))
+ goto done;
+ res = ans_length;
+
+ done:
+ close (fd);
+ return res;
+}
+
+/*****************************************************************
+ **
+ res_send
+ Assumes that the message is a query starting with a short id.
+ Handles retransmissions until that id is received.
+
+*****************************************************************/
+int res_nsend( res_state statp, const unsigned char * MsgPtr,
+ int MsgLength, unsigned char * AnsPtr, int AnsLength)
+{
+ /* Current server, shared by all tasks */
+ volatile static unsigned int SServ = 0XFFFFFFFF;
+ int tcp;
+ const int debug = statp->options & RES_DEBUG;
+
+ fd_set fdset_read;
+ int rslt, addrLen, transNum, wServ;
+ struct sockaddr_in mySockAddr, dnsSockAddr;
+ struct timeval timeOut;
+
+ statp->res_h_errno = NETDB_SUCCESS;
+ if (((statp->options & RES_INIT) == 0) && (res_ninit(statp) != 0))
+ return -1;
+
+ /* Close the socket if it had been opened before a fork.
+ Reuse of pid's cannot hurt */
+ if ((statp->sockfd != -1) && (statp->mypid != getpid())) {
+ res_nclose(statp);
+ }
+
+ /* Open a socket for this process */
+ if (statp->sockfd == -1) {
+ /* Create a socket and bind it (to any port) */
+ statp->sockfd = open_sock(& mySockAddr, debug);
+ if (statp->sockfd < 0 ) {
+ statp->res_h_errno = NETDB_INTERNAL;
+ return -1;
+ }
+ /* Set close on exec flag */
+ if (fcntl(statp->sockfd, F_SETFD, 1) == -1) {
+ DPRINTF(debug, "fcntl: %s\n",
+ strerror(errno));
+ statp->res_h_errno = NETDB_INTERNAL;
+ return -1;
+ }
+ statp->mypid = getpid();
+ if (SServ == 0XFFFFFFFF) /* Pseudo random */
+ SServ = statp->mypid % statp->nscount;
+ }
+
+ transNum = 0;
+ while ( transNum++ < statp->retry) {
+ if ((wServ = SServ + 1) >= statp->nscount)
+ wServ = 0;
+ SServ = wServ;
+ /* Send the message */
+ rslt = cygwin_sendto(statp->sockfd, MsgPtr, MsgLength, 0,
+ (struct sockaddr *) &statp->nsaddr_list[wServ],
+ sizeof(struct sockaddr_in));
+ DPRINTF(debug, "sendto: server %08x sockfd %d %s\n",
+ statp->nsaddr_list[wServ].sin_addr.s_addr,
+ statp->sockfd, (rslt == MsgLength)?"OK":strerror(errno));
+ if (rslt != MsgLength) {
+ statp->res_h_errno = NETDB_INTERNAL;
+ return -1;
+ };
+ /*
+ Wait for a reply with select()
+ */
+ FD_ZERO(&fdset_read);
+ FD_SET (statp->sockfd, &fdset_read );
+ timeOut.tv_sec = statp->retrans;
+ timeOut.tv_usec = 0;
+ rslt = cygwin_select(statp->sockfd + 1, &fdset_read, NULL, NULL, &timeOut);
+ if ( rslt == 0 ) { /* Timeout */
+ DPRINTF(statp->options & RES_DEBUG, "timeout for server %08x\n",
+ statp->nsaddr_list[wServ].sin_addr.s_addr);
+ continue;
+ }
+ else if ((rslt != 1) || (FD_ISSET(statp->sockfd, &fdset_read) == 0)) {
+ DPRINTF(debug, "select: %s\n", strerror(errno));
+ statp->res_h_errno = NETDB_INTERNAL;
+ return -1;
+ }
+
+ addrLen = sizeof(dnsSockAddr);
+ rslt = cygwin_recvfrom(statp->sockfd, AnsPtr, AnsLength, 0,
+ (struct sockaddr *) & dnsSockAddr, & addrLen);
+ if (rslt <= 0) {
+ DPRINTF(debug, "recvfrom: %s\n", strerror(errno));
+ statp->res_h_errno = NETDB_INTERNAL;
+ return -1;
+ }
+ /*
+ Prepare to retry with tcp
+ */
+ for (tcp = 0; tcp < 2; tcp++) {
+ /* Check if this is the message we expected */
+ if ((*MsgPtr == *AnsPtr) /* Ids match */
+ && (*(MsgPtr + 1) == *(AnsPtr + 1))
+/* We have stopped checking this because the question may not be present on error,
+ in particular when the name in the question is not a valid name.
+ Simply check that the header is present. */
+ && (rslt >= HFIXEDSZ)
+/* && (rslt >= MsgLength )
+ && (memcmp(MsgPtr + HFIXEDSZ, AnsPtr + HFIXEDSZ, MsgLength - HFIXEDSZ) == 0) */
+ && ((AnsPtr[2] & QR) != 0)) {
+
+ DPRINTF(debug, "answer %u from %08x. Error %d. Count %d.\n",
+ rslt, dnsSockAddr.sin_addr.s_addr,
+ AnsPtr[3] & ERR_MASK, AnsPtr[6]*256 + AnsPtr[7]);
+#if 0
+ NETDB_INTERNAL -1 /* see errno */
+ NETDB_SUCCESS 0 /* no problem */
+ HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
+ TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
+ Also seen returned by some servers when the name is too long
+ NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+ NO_DATA 4 /* Valid name, no data record of requested type */
+#endif
+ if ((AnsPtr[3] & ERR_MASK) == NOERROR) {
+ if ((AnsPtr[2] & TC) && !(statp->options & RES_IGNTC)) { /* Truncated. Try TCP */
+ rslt = get_tcp(&statp->nsaddr_list[wServ], MsgPtr, MsgLength,
+ AnsPtr, AnsLength, statp->options & RES_DEBUG);
+ continue;
+ }
+ else if ((AnsPtr[6] | AnsPtr[7])!= 0)
+ return rslt;
+ else
+ statp->res_h_errno = NO_DATA;
+ }
+ else {
+ /* return HOST_NOT_FOUND even for non-authoritative answers */
+ if ((AnsPtr[3] & ERR_MASK) == NXDOMAIN)
+ statp->res_h_errno = HOST_NOT_FOUND;
+ else if ((AnsPtr[3] & ERR_MASK) == SERVFAIL)
+ statp->res_h_errno = TRY_AGAIN;
+ else
+ statp->res_h_errno = NO_RECOVERY;
+ }
+ return -1;
+ }
+ else {
+ DPRINTF(debug, "unexpected answer %u from %x to query to %x\n",
+ rslt, dnsSockAddr.sin_addr.s_addr,
+ statp->nsaddr_list[wServ].sin_addr.s_addr);
+ break;
+ }
+ } /* TCP */
+ }
+ DPRINTF(debug, "too many retries\n");
+ statp->res_h_errno = TRY_AGAIN;
+ return -1;
+}
+
+int res_send( const unsigned char * MsgPtr, int MsgLength,
+ unsigned char * AnsPtr, int AnsLength)
+{
+ int r = res_nsend(& res, MsgPtr, MsgLength, AnsPtr, AnsLength);
+ h_errno = res.res_h_errno;
+ return r;
+}
+
+/*****************************************************************
+ *
+ res_mkquery
+
+ Return: packet size
+ -1 name format is incorrect
+*****************************************************************/
+int res_nmkquery (res_state statp,
+ int op, const char * dnameptr, int qclass, int qtype,
+ const unsigned char * dataptr, int datalen,
+ const unsigned char * newrr, unsigned char * buf, int buflen)
+{
+ int i, len;
+ short id;
+
+ if (op == QUERY) {
+ /* Write the name and verify buffer length */
+ len = dn_comp(dnameptr, buf + HFIXEDSZ, buflen - HFIXEDSZ - QFIXEDSZ, NULL, NULL);
+ if (len < 0) {
+ DPRINTF(statp->options & RES_DEBUG,
+ "\"%s\" invalid or buffer too short\n", dnameptr);
+ statp->res_h_errno = NETDB_INTERNAL;
+ return -1;
+ }
+ /* Fill the header */
+ id = statp->id;
+ PUTSHORT(id, buf);
+ PUTSHORT(RD, buf);
+ PUTSHORT(1, buf); /* Number of questions */
+ for (i = 0; i < 3; i++)
+ PUTSHORT(0, buf); /* Number of answers */
+
+ /* Write qtype and qclass */
+ buf += len;
+ PUTSHORT(qtype, buf);
+ PUTSHORT(qclass, buf);
+ return len + 16; /* packet size */
+ }
+ else { /* Not implemented */
+ errno = ENOSYS;
+ statp->res_h_errno = NETDB_INTERNAL;
+ return -1;
+ }
+}
+
+int res_mkquery (int op, const char * dnameptr, int qclass, int qtype,
+ const unsigned char * dataptr, int datalen,
+ const unsigned char * newrr, unsigned char * buf, int buflen)
+{
+ int r = res_nmkquery (& res, op, dnameptr, qclass, qtype,
+ dataptr, datalen, newrr, buf, buflen);
+ h_errno = res.res_h_errno;
+ return r;
+
+}
+
+/*****************************************************************
+ *
+ res_query()
+
+ *****************************************************************/
+
+int res_nquery( res_state statp, const char * DomName, int Class, int Type,
+ unsigned char * AnsPtr, int AnsLength)
+{
+ u_char packet[PACKETSZ];
+ int len;
+
+ DPRINTF(statp->options & RES_DEBUG, "query \"%s\" type %d\n", DomName, Type);
+ statp->res_h_errno = NETDB_SUCCESS;
+
+ /* If a hook exists to a native implementation, use it */
+ if (statp->os_query)
+ return ((os_query_t *) statp->os_query)(statp, DomName, Class, Type, AnsPtr, AnsLength);
+
+ if ((len = res_nmkquery (statp, QUERY, DomName, Class, Type,
+ 0, 0, 0, packet, PACKETSZ)) < 0)
+ return -1;
+ return res_nsend( statp, packet, len, AnsPtr, AnsLength);
+}
+
+int res_query( const char * DomName, int Class, int Type, unsigned char * AnsPtr, int AnsLength)
+{
+ int r = res_nquery(& res, DomName, Class, Type, AnsPtr, AnsLength);
+ h_errno = res.res_h_errno;
+ return r;
+}
+
+/*****************************************************************
+ *
+ res_querydomain()
+
+ *****************************************************************/
+int res_nquerydomain( res_state statp, const char * Name, const char * DomName,
+ int Class, int Type, unsigned char * AnsPtr, int AnsLength)
+{
+ char fqdn[MAXDNAME], *ptr;
+ int nlen;
+
+ if (!DomName)
+ ptr = (char *) Name;
+ else if ((nlen = strlen(Name)) >= sizeof(fqdn) - 1)
+ goto error;
+ else {
+ strcpy(fqdn, Name);
+ ptr = &fqdn[nlen];
+ if (nlen && *(ptr - 1) != '.')
+ *(ptr++ - 1) = '.';
+ fqdn[sizeof(fqdn) - 1] = 0;
+ strncpy(ptr, DomName, sizeof(fqdn) - (ptr - fqdn));
+ if (fqdn[sizeof(fqdn) - 1])
+ goto error;
+ ptr = fqdn;
+ }
+ return res_nquery(statp, ptr, Class, Type, AnsPtr, AnsLength);
+
+ error:
+ DPRINTF(statp->options & RES_DEBUG, "querydomain: name too long\n");
+ errno = EINVAL;
+ statp->res_h_errno = NETDB_INTERNAL;;
+ return -1;
+}
+
+int res_querydomain( const char * Name, const char * DomName, int Class,
+ int Type, unsigned char * AnsPtr, int AnsLength)
+{
+ int r = res_nquerydomain(& res, Name, DomName, Class, Type, AnsPtr,
+ AnsLength);
+ h_errno = res.res_h_errno;
+ return r;
+}
+
+/*****************************************************************
+ *
+ res_search()
+
+ *****************************************************************/
+
+int res_nsearch( res_state statp, const char * DomName, int Class, int Type,
+ unsigned char * AnsPtr, int AnsLength)
+{
+ int len, stat, i;
+ char fullDomName[MAXDNAME], *ptr, *sptr;
+
+ DPRINTF(statp->options & RES_DEBUG, "search \"%s\" type %d\n", DomName, Type);
+
+ if (((statp->options & RES_INIT) == 0) && (res_ninit(statp) != 0))
+ return -1;
+
+ stat = res_nquery( statp, DomName, Class, Type, AnsPtr, AnsLength);
+
+ /* Check if will skip search */
+ if (statp->res_h_errno != HOST_NOT_FOUND /* Success or hard failure */
+ || ((ptr = strrchr(DomName, '.')) && (!*(ptr+1))) /* Final dot */
+ || (((statp->options & RES_DNSRCH) == 0) /* Or no search */
+ && ((ptr != NULL) /* And some dot */
+ || ((statp->options & RES_DEFNAMES) == 0)))/* or no def domain */
+ || (!(sptr = statp->dnsrch[0])))
+ return stat;
+
+ len = strlen(DomName);
+ if (len >= MAXDNAME - 1) /* Space for next dot */
+ goto error;
+ strcpy(fullDomName, DomName);
+ fullDomName[len++] = '.';
+ fullDomName[MAXDNAME - 1] = 0; /* Overflow indicator */
+ i = 0;
+ do {
+ strncpy(fullDomName + len, sptr, MAXDNAME - len);
+ if (fullDomName[MAXDNAME - 1])
+ goto error;
+ stat = res_nquery(statp, fullDomName, Class, Type, AnsPtr, AnsLength);
+ } while ((sptr = statp->dnsrch[++i]) != NULL
+ && statp->res_h_errno == HOST_NOT_FOUND
+ && (statp->options & RES_DNSRCH) != 0);
+
+ /* Return last stat */
+ return stat;
+
+ error:
+ DPRINTF(statp->options & RES_DEBUG, "name too long during search\n");
+ errno = EINVAL;
+ statp->res_h_errno = NETDB_INTERNAL;
+ return -1;
+}
+
+int res_search( const char * DomName, int Class, int Type,
+ unsigned char * AnsPtr, int AnsLength)
+{
+ int r = res_nsearch(& res, DomName, Class, Type, AnsPtr, AnsLength);
+ h_errno = res.res_h_errno;
+ return r;
+}
+
+/*****************************************************************
+ *
+ dn_expand
+
+ *****************************************************************/
+
+int dn_expand(const unsigned char *msg, const unsigned char *eomorig,
+ const unsigned char *comp_dn, char *exp_dn, int length)
+{
+ unsigned int len, complen = 0;
+ const unsigned char *comp_dn_orig = comp_dn;
+/* char * exp_start = exp_dn; */
+
+ errno = EINVAL;
+ if (comp_dn >= eomorig)
+ goto expand_fail;
+ if ((len = *comp_dn++) == 0) /* Weird case */
+ exp_dn++;
+ else do {
+ if (len <= MAXLABEL) {
+ if ((length -= (len + 1)) > 0 /* Need space for final . */
+ && comp_dn + len <= eomorig) {
+ do { *exp_dn++ = *comp_dn++; } while (--len != 0);
+ *exp_dn++ = '.';
+ }
+ else
+ goto expand_fail;
+ }
+ else if (len >= (128+64)) {
+ if (!complen) /* Still in the original field? */
+ complen = (comp_dn - comp_dn_orig) + 1;
+ comp_dn = msg + (((len & ~(128+64)) << 8) + *comp_dn);
+ if (comp_dn >= eomorig)
+ goto expand_fail;
+ }
+ else
+ goto expand_fail;
+ } while ((len = *comp_dn++) != 0);
+ /* Replace last . with a 0 */
+ *(--exp_dn) = 0;
+ if (!complen)
+ complen = comp_dn - comp_dn_orig;
+/* fprintf(stderr, "dn_expand %s\n", exp_start); */
+ return complen;
+
+expand_fail:
+/* fprintf(stderr, "dn_expand fails\n"); */
+ return -1;
+}
+
+
+/*****************************************************************
+ *
+ dn_comp
+
+ Return -1 in case of overflow, but still fill buffer correctly.
+ We do not check the alphabet of the host names
+ nor the length of the compressed name and we
+ preserve the letter cases.
+
+ *****************************************************************/
+int dn_comp(const char * exp_dn, u_char * comp_dn, int length,
+ u_char ** dnptrs, u_char ** lastdnptr)
+{
+ u_char *cptr = comp_dn, *dptr, *lptr, *rptr;
+ unsigned int i, len;
+ u_char * const eptr = comp_dn + length - 1; /* Last valid */
+
+ errno = EINVAL;
+
+ if (*exp_dn == '.' && !*(exp_dn + 1))
+ exp_dn++;
+ while (1) {
+ if (*exp_dn == '.' || cptr > eptr)
+ return -1;
+ if (*exp_dn == 0) {
+ *cptr++ = 0;
+ break;
+ }
+ /* Try to compress */
+ if (dnptrs) {
+ for (i = 1; dnptrs[i]; i++) {
+ dptr = dnptrs[i];
+ if (dptr >= comp_dn) /* Handle name.name */
+ continue;
+ rptr = (u_char *) exp_dn;
+ len = *dptr++;
+ while (1) {
+ do {
+ if (*dptr++ != *rptr++)
+ goto next_dn;
+ } while (--len);
+ len = *dptr++;
+ if (len == 0) { /* last label */
+ if (!*rptr || (*rptr == '.' && !*(rptr + 1))) { /* Full match */
+ len = (dnptrs[i] - dnptrs[0]) | 0xC000;
+ /* Write pointer */
+ *cptr++ = len >> 8;
+ if (cptr > eptr)
+ return -1;
+ *cptr++ = len;
+ goto done;
+ }
+ goto next_dn;
+ }
+ if (*rptr++ != '.')
+ goto next_dn;
+ if (len >= 128 + 64) {
+ dptr = dnptrs[0] + ((len - 128 - 64) << 8) + *dptr;
+ len = *dptr++;
+ }
+ }
+ next_dn: ;
+ }
+ /* Record label if asked and if space is available and if not too far off */
+ if (lastdnptr && (lastdnptr != &dnptrs[i]) && (cptr - dnptrs[0]) < 0xC000) {
+ dnptrs[i] = cptr;
+ dnptrs[i+1] = NULL;
+ }
+ }
+ /* Write label */
+ lptr = cptr++; /* Length byte */
+ rptr = (u_char *) exp_dn;
+ do {
+ if (cptr <= eptr)
+ *cptr++ = *rptr;
+ } while ((*++rptr != '.') && (*rptr != 0));
+ len = rptr - (u_char *) exp_dn;
+ if (len > MAXLABEL)
+ return -1;
+ *lptr = len;
+ exp_dn = (char *) rptr;
+ if (*exp_dn != 0)
+ exp_dn++; /* Skip over . */
+ }
+ done:
+ return cptr - comp_dn;
+}
+
+/*****************************************************************
+ *
+ dn_skipname
+
+ Measures the compressed domain name length and returns it.
+ *****************************************************************/
+int dn_skipname(const unsigned char *comp_dn, const unsigned char *eom)
+{
+ int len;
+ const unsigned char *comp_dn_orig = comp_dn;
+
+ do {
+ len = *comp_dn++;
+ if (len >= (128 + 64)) {
+ comp_dn++;
+ break;
+ }
+ if (len > MAXLABEL ||
+ (comp_dn += len) > eom)
+ return -1;
+ } while (len != 0);
+
+ return comp_dn - comp_dn_orig;
+}
diff --git a/winsup/cygwin/libc/minires.h b/winsup/cygwin/libc/minires.h
new file mode 100644
index 000000000..ce063d16f
--- /dev/null
+++ b/winsup/cygwin/libc/minires.h
@@ -0,0 +1,68 @@
+/* minires.h. Stub synchronous resolver for Cygwin.
+
+ Copyright 2006 Red Hat, Inc.
+
+ Written by Pierre A. Humblet <Pierre.Humblet@ieee.org>
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#define __INSIDE_CYGWIN_NET__
+
+#include "winsup.h"
+#include <string.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <netdb.h>
+#include <ctype.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <sys/unistd.h>
+#include <netdb.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+extern in_addr_t cygwin_inet_addr (const char *);
+extern int cygwin_socket (int, int, int);
+extern int cygwin_bind (int, const struct sockaddr *, socklen_t);
+extern int cygwin_connect (int, const struct sockaddr *, socklen_t);
+extern int cygwin_select (int, fd_set *, fd_set *, fd_set *, struct timeval *);
+extern int cygwin_sendto (int, const void *, size_t, int,
+ const struct sockaddr *, socklen_t);
+extern int cygwin_recvfrom (int, void *, size_t, int, struct sockaddr *,
+ socklen_t *);
+
+/* Number of elements is an array */
+#define DIM(x) (sizeof(x) / sizeof(*(x)))
+
+/* Definitions to parse the messages */
+#define RD (1<<8) /* Offset in a short */
+#define RA (1<<7)
+#define QR (1<<7) /* Offsets in a char */
+#define TC (1<<1)
+#define ERR_MASK 0xF
+
+/* Type for os specific res_lookup */
+typedef int (os_query_t) (res_state, const char *, int, int, u_char *, int);
+
+/* Special use of state elements */
+#define sockfd _vcsock
+#define mypid _flags
+#define os_query qhook
+#define use_os pfcode
+
+#define DPRINTF(cond, format...) if (cond) minires_dprintf(format)
+
+/* Utility functions */
+void minires_dprintf(const char * format, ...);
+void minires_get_search(char * string, res_state statp);
+void get_dns_info(res_state statp);
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index a8d4a3321..1c485cc1f 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -515,6 +515,7 @@ sigproc_terminate (exit_states es)
sigproc_printf ("entering");
sig_send (myself_nowait, __SIGEXIT);
proc_terminate (); // clean up process stuff
+ CloseHandle (my_sendsig);
}
}