svn rev #25273: trunk/src/ config/ util/ util/wshelper/ windows/ windows/wshelper/

hartmans@MIT.EDU hartmans at MIT.EDU
Wed Sep 28 16:57:53 EDT 2011


http://src.mit.edu/fisheye/changelog/krb5/?cs=25273
Commit By: hartmans
Log Message:
Windows fixes: enable DNS lookups; turn on KDC lookup by default.

Moved wshelper from windows to util to fix build order dependencies.

Signed-off-by: Kevin Wasserman <kevin.wasserman at painless-security.com>


Changed Files:
U   trunk/src/Makefile.in
U   trunk/src/config/win-pre.in
U   trunk/src/util/Makefile.in
A   trunk/src/util/wshelper/
A   trunk/src/util/wshelper/Makefile.in
A   trunk/src/util/wshelper/dllmain.c
A   trunk/src/util/wshelper/gethna.c
A   trunk/src/util/wshelper/hesiod.c
A   trunk/src/util/wshelper/hesmailh.c
A   trunk/src/util/wshelper/hespwnam.c
A   trunk/src/util/wshelper/hesservb.c
A   trunk/src/util/wshelper/inetaton.c
A   trunk/src/util/wshelper/pwd.h
A   trunk/src/util/wshelper/res_comp.c
A   trunk/src/util/wshelper/res_init.c
A   trunk/src/util/wshelper/res_quer.c
A   trunk/src/util/wshelper/resource.h
A   trunk/src/util/wshelper/resource.rc
A   trunk/src/util/wshelper/string.rc
A   trunk/src/util/wshelper/ver.rc.inc
A   trunk/src/util/wshelper/wsh-int.h
A   trunk/src/util/wshelper/wshelp32.def
A   trunk/src/util/wshelper/wshelp64.def
A   trunk/src/util/wshelper/wshelper.def
U   trunk/src/windows/Makefile.in
D   trunk/src/windows/wshelper/Makefile.in
D   trunk/src/windows/wshelper/dllmain.c
D   trunk/src/windows/wshelper/gethna.c
D   trunk/src/windows/wshelper/hesiod.c
D   trunk/src/windows/wshelper/hesmailh.c
D   trunk/src/windows/wshelper/hespwnam.c
D   trunk/src/windows/wshelper/hesservb.c
D   trunk/src/windows/wshelper/inetaton.c
D   trunk/src/windows/wshelper/pwd.h
D   trunk/src/windows/wshelper/res_comp.c
D   trunk/src/windows/wshelper/res_init.c
D   trunk/src/windows/wshelper/res_quer.c
D   trunk/src/windows/wshelper/resource.h
D   trunk/src/windows/wshelper/resource.rc
D   trunk/src/windows/wshelper/string.rc
D   trunk/src/windows/wshelper/ver.rc.inc
D   trunk/src/windows/wshelper/wsh-int.h
D   trunk/src/windows/wshelper/wshelp32.def
D   trunk/src/windows/wshelper/wshelp64.def
D   trunk/src/windows/wshelper/wshelper.def
Modified: trunk/src/Makefile.in
===================================================================
--- trunk/src/Makefile.in	2011-09-28 20:57:15 UTC (rev 25272)
+++ trunk/src/Makefile.in	2011-09-28 20:57:53 UTC (rev 25273)
@@ -191,7 +191,8 @@
 	util\et\Makefile util\profile\Makefile util\profile\testmod\Makefile \
 	util\support\Makefile \
 	util\windows\Makefile \
-	windows\Makefile windows\wshelper\Makefile windows\lib\Makefile \
+	util\wshelper\Makefile \
+	windows\Makefile windows\lib\Makefile \
 	windows\cns\Makefile windows\gina\Makefile \
 	windows\gss\Makefile windows\ms2mit\Makefile \
 	windows\wintel\Makefile windows\kfwlogon\Makefile windows\leashdll\Makefile
@@ -304,14 +305,14 @@
 ##DOS##	$(WCONFIG) config < $@.in > $@
 ##DOS##util\windows\Makefile: util\windows\Makefile.in $(MKFDEP)
 ##DOS##	$(WCONFIG) config < $@.in > $@
+##DOS##util\wshelper\Makefile: util\wshelper\Makefile.in $(MKFDEP)
+##DOS##	$(WCONFIG) config < $@.in > $@
 ##DOS##windows\Makefile: windows\Makefile.in $(MKFDEP)
 ##DOS##	$(WCONFIG) config < $@.in > $@
 ##DOS##windows\lib\Makefile: windows\lib\Makefile.in $(MKFDEP)
 ##DOS##	$(WCONFIG) config < $@.in > $@
 ##DOS##windows\cns\Makefile: windows\cns\Makefile.in $(MKFDEP)
 ##DOS##	$(WCONFIG) config < $@.in > $@
-##DOS##windows\wshelper\Makefile: windows\wshelper\Makefile.in $(MKFDEP)
-##DOS##	$(WCONFIG) config < $@.in > $@
 ##DOS##windows\gina\Makefile: windows\gina\Makefile.in $(MKFDEP)
 ##DOS##	$(WCONFIG) config < $@.in > $@
 ##DOS##windows\gss\Makefile: windows\gss\Makefile.in $(MKFDEP)
@@ -555,6 +556,8 @@
 	copy appl\gss-sample\$(OUTPRE)gss-server.exe "$(KRB_INSTALL_DIR)\bin\."
 	copy appl\gss-sample\$(OUTPRE)gss-client.exe "$(KRB_INSTALL_DIR)\bin\."
 	copy windows\ms2mit\$(OUTPRE)ms2mit.exe "$(KRB_INSTALL_DIR)\bin\."
+	copy util\wshelper\$(OUTPRE)$(DLIB).lib "$(KRB_INSTALL_DIR)\lib\."
+	copy util\wshelper\$(OUTPRE)$(DLIB).dll "$(KRB_INSTALL_DIR)\bin\."
 	copy ccapi\lib\win\srctmp\$(OUTPRE)$(CCLIB).dll "$(KRB_INSTALL_DIR)\bin\."
 	copy ccapi\server\win\srctmp\$(OUTPRE)ccapiserver.exe "$(KRB_INSTALL_DIR)\bin\."
 	copy clients\kvno\$(OUTPRE)kvno.exe "$(KRB_INSTALL_DIR)\bin\."

Modified: trunk/src/config/win-pre.in
===================================================================
--- trunk/src/config/win-pre.in	2011-09-28 20:57:15 UTC (rev 25272)
+++ trunk/src/config/win-pre.in	2011-09-28 20:57:53 UTC (rev 25273)
@@ -88,6 +88,11 @@
 srcdir = .
 top_srcdir = $(srcdir)\$(BUILDTOP)
 
+KRB5_USE_DNS=1
+KRB5_USE_DNS_KDC=1
+DNS_LIB=$(BUILDTOP)\util\wshelper\$(OUTPRE)$(DLIB).lib
+DNS_INC=$(BUILDTOP)\util\wshelper
+
 !if defined(KRB5_USE_DNS) || defined(KRB5_USE_DNS_KDC) || defined(KRB5_USE_DNS_REALMS)
 !if defined(KRB5_NO_WSHELPER)
 DNSMSG=resolver
@@ -195,6 +200,7 @@
 K4LIB=$(BUILDTOP)\lib\$(OUTPRE)krb4_32.lib
 SLIB=$(BUILDTOP)\lib\$(OUTPRE)k5sprt32.lib
 GLIB=$(BUILDTOP)\lib\$(OUTPRE)gssapi32.lib
+DLIB=wshelp32
 CCLIB=krbcc32
 WLIB=
 
@@ -205,6 +211,7 @@
 K4LIB=$(BUILDTOP)\lib\$(OUTPRE)krb4_64.lib
 SLIB=$(BUILDTOP)\lib\$(OUTPRE)k5sprt64.lib
 GLIB=$(BUILDTOP)\lib\$(OUTPRE)gssapi64.lib
+DLIB=wshelp64
 CCLIB=krbcc64
 WLIB=
 

Modified: trunk/src/util/Makefile.in
===================================================================
--- trunk/src/util/Makefile.in	2011-09-28 20:57:15 UTC (rev 25272)
+++ trunk/src/util/Makefile.in	2011-09-28 20:57:53 UTC (rev 25273)
@@ -6,7 +6,7 @@
 SUBDIRS=support $(MAYBE_ET_ at COM_ERR_VERSION@) $(MAYBE_SS_ at SS_VERSION@) \
 	profile send-pr gss-kernel-lib $(MAYBE_VERTO_ at VERTO_VERSION@)
 ##WIN32##!endif
-WINSUBDIRS=windows support et profile
+WINSUBDIRS=windows support et profile wshelper
 BUILDTOP=$(REL)..
 
 MAYBE_ET_k5 = et

Copied: trunk/src/util/wshelper/Makefile.in (from rev 25272, trunk/src/windows/wshelper/Makefile.in)
===================================================================
--- trunk/src/util/wshelper/Makefile.in	                        (rev 0)
+++ trunk/src/util/wshelper/Makefile.in	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,64 @@
+BUILDTOP=..\..
+
+DLL_NAME=wshelp32
+DEF_FILE=wshelp32.def
+
+# Use 64-bit DLL_NAME and DEF_FILE on 64-bit platforms
+!if ("$(CPU)" == "IA64") || ("$(CPU)" == "AMD64") || ("$(CPU)" == "ALPHA64")
+DLL_NAME=wshelp64
+DEF_FILE=wshelp64.def
+!endif
+
+
+OBJS=	$(OUTPRE)dllmain.$(OBJEXT) \
+	$(OUTPRE)gethna.$(OBJEXT) \
+	$(OUTPRE)hesiod.$(OBJEXT) \
+	$(OUTPRE)hesmailh.$(OBJEXT) \
+	$(OUTPRE)hespwnam.$(OBJEXT) \
+	$(OUTPRE)hesservb.$(OBJEXT) \
+	$(OUTPRE)inetaton.$(OBJEXT) \
+	$(OUTPRE)res_comp.$(OBJEXT) \
+	$(OUTPRE)res_init.$(OBJEXT) \
+	$(OUTPRE)res_quer.$(OBJEXT)
+
+RESFILE = $(OUTPRE)resource.res
+XOBJS	= $(RESFILE)
+
+RCFLAGS = -I$(BUILDTOP)\include -I$(BUILDTOP) -DWSHELPER_LIB
+
+###From another project inside K 1.9:
+###VERSIONRC = $(BUILDTOP)\windows\version.rc
+###RCFLAGS=$(CPPFLAGS) -I$(top_srcdir) -D_WIN32 -DRES_ONLY
+
+
+# Set NODEBUG if building release instead of debug
+
+LOCALINCLUDES = -I$(BUILDTOP)\include
+
+WINLIBS = advapi32.lib user32.lib ws2_32.lib dnsapi.lib
+
+WINDLLFLAGS = /nologo /dll /incremental:no /release $(LOPTS)
+
+DEFINES = -DUNICODE -D_UNICODE
+!ifdef NODEBUG
+DEFINES = $(DEFINES)
+!else
+DEFINES = $(DEFINES) -DDBG
+!endif
+
+all-windows::
+all-windows:: $(OUTPRE)$(DLL_NAME).dll
+
+clean-windows::
+	$(RM) $(OUTPRE)$(DLL_NAME).dll
+
+$(OUTPRE)$(DLL_NAME).dll: $(DEF_FILE) $(OBJS) $(XOBJS)
+	link $(WINDLLFLAGS) -def:$(DEF_FILE) -out:$*.dll \
+	$(OBJS) $(XOBJS) $(WINLIBS) $(SCLIB)
+	$(_VC_MANIFEST_EMBED_DLL)
+
+$(OUTPRE)dllmain.$(OBJEXT): pwd.h
+$(OUTPRE)hespwnam.$(OBJEXT): pwd.h
+$(OUTPRE)dllmain.$(OBJEXT): wsh-int.h
+$(OUTPRE)res_init.$(OBJEXT): wsh-int.h
+$(RESFILE): resource.rc  ../../windows/version.rc ../../windows/kerberos.ver

Copied: trunk/src/util/wshelper/dllmain.c (from rev 25272, trunk/src/windows/wshelper/dllmain.c)
===================================================================
--- trunk/src/util/wshelper/dllmain.c	                        (rev 0)
+++ trunk/src/util/wshelper/dllmain.c	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,264 @@
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winsock.h>
+#include "wsh-int.h"
+#include <windns.h>
+#include "hesiod.h"
+#include "pwd.h"
+
+
+DWORD dwHesIndex; // for hes_to_bind
+DWORD dwHesMailIndex; // for hes_getmailhost
+DWORD dwHesServIndex;  // for hes_getservbyname
+DWORD dwHesPwNamIndex; // for hes_getpwnam;
+DWORD dwHesPwUidIndex; // for hes_getpwuid
+DWORD dwGhnIndex; // for rgethostbyname
+DWORD dwGhaIndex; // for rgethostbyaddr
+
+#define LISTSIZE 15
+
+void FreeThreadLocalMemory();
+void AllocateThreadLocalMemory();
+void FreePasswdStruct(LPVOID lpvData);
+void FreeHostentStruct(LPVOID lpvData);
+
+BOOL
+WINAPI
+DllMain(
+    HINSTANCE hinstDLL,  // handle to DLL module
+    DWORD fdwReason,     // reason for calling function
+    LPVOID lpvReserved   // reserved
+)
+{
+    switch(fdwReason)
+    {
+    case DLL_PROCESS_ATTACH:
+        if ((dwHesIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+            return FALSE;
+        if ((dwHesMailIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+            return FALSE;
+        if ((dwHesServIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+            return FALSE;
+        if ((dwHesPwNamIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+            return FALSE;
+	if ((dwHesPwUidIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+            return FALSE;
+	if ((dwHesPwUidIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+            return FALSE;
+	if ((dwGhnIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+            return FALSE;
+	if ((dwGhaIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+            return FALSE;
+        res_init_startup();
+     case DLL_THREAD_ATTACH:
+        // Initialize the TLS index for this thread.
+        AllocateThreadLocalMemory();
+        break;
+
+     case DLL_THREAD_DETACH:
+
+        // Release the allocated memory for this thread.
+        FreeThreadLocalMemory();
+        break;
+
+
+    case DLL_PROCESS_DETACH:
+        // Release the TLS index.
+        FreeThreadLocalMemory();
+        TlsFree(dwHesIndex);
+        TlsFree(dwHesMailIndex);
+        TlsFree(dwHesServIndex);
+        TlsFree(dwHesPwNamIndex);
+	TlsFree(dwHesPwUidIndex);
+	TlsFree(dwGhnIndex);
+	TlsFree(dwGhaIndex);
+
+        res_init_cleanup();
+        break;
+    }
+    return TRUE;
+}
+
+void AllocateThreadLocalMemory()
+{
+    LPVOID lpvData;
+
+    lpvData = (LPVOID) LocalAlloc(LPTR, DNS_MAX_NAME_BUFFER_LENGTH);
+    if (lpvData != NULL)
+        TlsSetValue(dwHesIndex, lpvData);
+
+    lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hes_postoffice));
+    if (lpvData != NULL)
+        TlsSetValue(dwHesMailIndex, lpvData);
+
+    lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct servent));
+    if (lpvData != NULL)
+        TlsSetValue(dwHesServIndex, lpvData);
+
+    lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct passwd));
+    if (lpvData != NULL)
+        TlsSetValue(dwHesPwNamIndex, lpvData);
+
+    lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct passwd));
+    if (lpvData != NULL)
+        TlsSetValue(dwHesPwUidIndex, lpvData);
+
+    lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hostent));
+    if (lpvData != NULL)
+        TlsSetValue(dwGhnIndex, lpvData);
+
+    lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hostent));
+    if (lpvData != NULL)
+        TlsSetValue(dwGhaIndex, lpvData);
+
+}
+void FreeThreadLocalMemory()
+{
+    LPVOID lpvData;
+    int i;
+
+    lpvData = TlsGetValue(dwHesIndex);
+    if (lpvData != NULL)
+        LocalFree((HLOCAL) lpvData);
+
+    // free hes_postoffice
+    lpvData = TlsGetValue(dwHesMailIndex);
+    if (lpvData)
+    {
+        struct hes_postoffice* p = (struct hes_postoffice*) lpvData;
+        if (p->po_type)
+        {
+            LocalFree(p->po_type);
+            p->po_type = NULL;
+        }
+        if (p->po_host)
+        {
+           LocalFree(p->po_host);
+           p->po_host = NULL;
+        }
+        if (p->po_name)
+        {
+            LocalFree(p->po_name);
+            p->po_name = NULL;
+        }
+        LocalFree((HLOCAL) lpvData);
+     }
+
+    // free servent
+    lpvData = TlsGetValue(dwHesServIndex);
+    if (lpvData)
+    {
+        struct servent* s = (struct servent*) lpvData;
+        if (s->s_name)
+        {
+            LocalFree(s->s_name);
+            s->s_name = NULL;
+        }
+        if (s->s_proto)
+        {
+            LocalFree(s->s_proto);
+            s->s_proto = NULL;
+        }
+        if (s->s_aliases)
+        {
+            for (i = 0; i<LISTSIZE; i++)
+            {
+                if (s->s_aliases[i])
+                {
+                    LocalFree(s->s_aliases[i]);
+                    s->s_aliases[i] = NULL;
+                }
+            }
+            LocalFree(s->s_aliases);
+        }
+        LocalFree((HLOCAL) lpvData);
+    }
+
+    // free struct passwd
+    lpvData = TlsGetValue(dwHesPwNamIndex);
+    FreePasswdStruct(lpvData);
+
+    lpvData = TlsGetValue(dwHesPwUidIndex);
+    FreePasswdStruct(lpvData);
+
+    // free struct hostent
+    lpvData = TlsGetValue(dwGhnIndex);
+    FreeHostentStruct(lpvData);
+
+    lpvData = TlsGetValue(dwGhaIndex);
+    FreeHostentStruct(lpvData);
+
+}
+
+
+void FreeHostentStruct(LPVOID lpvData)
+{
+    if (lpvData)
+    {
+	int i = 0;
+	struct hostent* host = (struct hostent*) lpvData;
+	if (host->h_name)
+	    LocalFree(host->h_name);
+	if (host->h_aliases)
+	{
+	    while(host->h_aliases[i])
+	    {
+		LocalFree(host->h_aliases[i]);
+		host->h_aliases[i] = NULL;
+		i++;
+	    }
+	    LocalFree(host->h_aliases);
+	}
+	if (host->h_addr_list)
+	{
+	    i = 0;
+	    while (host->h_addr_list[i])
+	    {
+		LocalFree(host->h_addr_list[i]);
+		host->h_addr_list[i] = NULL;
+		i++;
+	    }
+	    LocalFree(host->h_addr_list);
+	}
+	LocalFree((HLOCAL) lpvData);
+    }
+}
+
+void FreePasswdStruct(LPVOID lpvData)
+{
+    if (lpvData)
+    {
+        struct passwd* p = (struct passwd*) lpvData;
+        if (p->pw_name)
+        {
+            LocalFree(p->pw_name);
+            p->pw_name = NULL;
+        }
+        if (p->pw_passwd)
+        {
+            LocalFree(p->pw_passwd);
+            p->pw_passwd = NULL;
+        }
+        if (p->pw_comment)
+        {
+            LocalFree(p->pw_comment);
+            p->pw_comment = NULL;
+        }
+        if (p->pw_gecos)
+        {
+            LocalFree(p->pw_gecos);
+            p->pw_gecos = NULL;
+        }
+        if (p->pw_dir)
+        {
+            LocalFree(p->pw_dir);
+            p->pw_dir = NULL;
+        }
+        if (p->pw_shell)
+        {
+            LocalFree(p->pw_shell);
+            p->pw_shell = NULL;
+        }
+        LocalFree((HLOCAL) lpvData);
+    }
+}

Copied: trunk/src/util/wshelper/gethna.c (from rev 25272, trunk/src/windows/wshelper/gethna.c)
===================================================================
--- trunk/src/util/wshelper/gethna.c	                        (rev 0)
+++ trunk/src/util/wshelper/gethna.c	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,477 @@
+/*
+*	@doc RESOLVE
+*
+*	@module gethna.c  |
+*
+*	This file contains the function definitions for:
+*		rgethostbyname,
+*		rgethostbyaddr,
+*		rdn_expand,
+*		gethinfobyname,
+*		getmxbyname,
+*		getrecordbyname,
+*		rrhost,
+*		rgetservbyname,
+*	and some other internal functions called by these functions.
+*
+*
+*	WSHelper DNS/Hesiod Library for WINSOCK
+*
+*/
+
+/*
+ * Copyright (c) 1985, 1988 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)gethostnamadr.c	6.48 (Berkeley) 1/10/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <windows.h>
+#include <winsock.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <windns.h>
+
+#ifdef _WIN32
+#include <mitwhich.h>
+#endif
+
+#define MAXALIASES      35
+#define MAXADDRS        35
+
+extern DWORD dwGhnIndex;
+extern DWORD dwGhaIndex;
+
+unsigned long WINAPI inet_aton(register const char *, struct in_addr *);
+
+
+#ifdef _DEBUG
+#ifndef DEBUG
+#define DEBUG
+#endif
+#endif
+
+
+extern int WINAPI hes_error( void );
+DNS_STATUS doquery(const char* queryname, struct hostent* host);
+
+/*
+	query the dns name space for a host given the host name
+	\param[in]	name Pointer to the null-terminated name of the host to resolve. It can be a fully qualified host name such as x.mit.edu
+				or it can be a simple host name such as x. If it is a simple host name, the default domain name is
+				appended to do the search.
+	\retval		a pointer to the structure hostent. a structure allocated by the library. The hostent structure contains
+				the results of a successful search for the host specified in the name parameter. The caller must never
+				attempt to modify this structure or to free any of its components. Furthermore, only one copy of this
+				structure is allocated per call per thread, so the application should copy any information it needs before
+				issuing another rgethostbyname.
+				NULL if the search has failed
+
+*/
+struct hostent *
+WINAPI
+rgethostbyname(char *name)
+{
+    struct hostent* host;
+    DNS_STATUS status;
+    const char *cp;
+    char queryname[DNS_MAX_NAME_BUFFER_LENGTH ];
+#ifdef DEBUG
+    char debstr[80];
+#endif
+    char** domain;
+    struct in_addr host_addr;
+
+    host = (struct hostent*)(TlsGetValue(dwGhnIndex));
+    if (host == NULL) {
+	LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hostent));
+	if (lpvData != NULL) {
+	    TlsSetValue(dwGhnIndex, lpvData);
+	    host = (struct hostent*)lpvData;
+	} else
+	    return NULL;
+    }
+
+    if (host->h_name == NULL)
+	host->h_name = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH);
+    if (host->h_aliases == NULL)
+	host->h_aliases = LocalAlloc(LPTR, 1*sizeof(LPSTR));
+    if (host->h_addr_list == NULL)
+    {
+	host->h_addr_list = LocalAlloc(LPTR, 2*sizeof(LPSTR));
+	host->h_addr_list[0] = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH);
+    }
+
+
+    /*
+     * disallow names consisting only of digits/dots, unless
+     * they end in a dot.
+     */
+    if (isdigit(name[0])) {
+        for (cp = name;; ++cp) {
+            if (!*cp) {
+                if (*--cp == '.')
+                    break;
+                /*
+                 * All-numeric, no dot at the end.
+                 * Fake up a hostent as if we'd actually
+                 * done a lookup.
+                 */
+                if (!inet_aton(name, &host_addr)) {
+                    return((struct hostent *) NULL);
+                }
+                strcpy(host->h_name, name);
+                host->h_aliases[0] = NULL;
+                host->h_addrtype = AF_INET;
+                host->h_length = sizeof(u_long);
+                memcpy(host->h_addr_list[0], &host_addr, sizeof(host_addr));
+				host->h_addr_list[1] = NULL;
+                return (host);
+            }
+            if (!isdigit(*cp) && *cp != '.')
+                break;
+        }
+    }
+
+    strcpy(queryname, name);
+
+    if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+        return NULL;
+    if (strchr(name, '.') == NULL)
+    {
+	if (_res.options & RES_DEFNAMES)
+	{
+	    for (domain = _res.dnsrch; *domain; domain++) {
+		strcpy(queryname, name);
+		strcat(queryname, ".");
+		strcat(queryname, *domain);
+		status = doquery(queryname, host);
+		if (status == 0)
+		    break;
+	    }
+	}
+    }
+    else {
+	status = doquery(queryname, host);
+    }
+
+    if (status) {
+#ifdef DEBUG
+	if (_res.options & RES_DEBUG)
+	{
+	    wsprintf(debstr, "res_query failed\n");
+	    OutputDebugString(debstr);
+	}
+#endif
+        return  NULL;
+    }
+    return host;
+}
+
+
+/*
+	an internal function used by rgethostbyname that does the actual DnsQuery call and populates the hostent
+	structure.
+
+	\param[in]	Name of the owner of the record set being queried
+	\param[in, out] populated hostent structure
+
+	\retval		DNS_STATUS value returned by DnsQuery
+
+*/
+DNS_STATUS doquery(const char* queryname, struct hostent* host)
+{
+    DNS_STATUS status;
+    PDNS_RECORD pDnsRecord, pDnsIter;
+    DNS_FREE_TYPE freetype ;
+    struct in_addr host_addr;
+    char querynamecp[DNS_MAX_NAME_BUFFER_LENGTH];
+    size_t len;
+
+    freetype =  DnsFreeRecordListDeep;
+    strcpy(querynamecp, queryname);
+    status = DnsQuery_A(queryname,          //pointer to OwnerName
+			DNS_TYPE_A,         //Type of the record to be queried
+                        DNS_QUERY_STANDARD,
+                        NULL,               //contains DNS server IP address
+                        &pDnsRecord,        //Resource record comprising the response
+                        NULL);              //reserved for future use
+
+    if (status)
+	return status;
+
+    /* If the query name includes a trailing separator in order to prevent
+     * a local domain search, remove the separator during the file name
+     * comparisons. */
+    len = strlen(querynamecp);
+    if (querynamecp[len-1] == '.')
+	querynamecp[len-1] = '\0';
+
+    for (pDnsIter = pDnsRecord; pDnsIter; pDnsIter=pDnsIter->pNext) {
+	/* if we get an A record, keep it */
+	if (pDnsIter->wType == DNS_TYPE_A && stricmp(querynamecp, pDnsIter->pName)==0)
+	    break;
+
+	/* if we get a CNAME, look for a corresponding A record */
+	if (pDnsIter->wType == DNS_TYPE_CNAME && stricmp(queryname, pDnsIter->pName)==0) {
+	    strcpy(querynamecp, pDnsIter->Data.CNAME.pNameHost);
+	}
+    }
+    if (pDnsIter == NULL)
+	return DNS_ERROR_RCODE_NAME_ERROR;
+
+    strcpy(host->h_name, pDnsIter->pName);
+    host->h_addrtype = AF_INET;
+    host->h_length = sizeof(u_long);
+    host->h_aliases[0] = NULL;
+    host_addr.S_un.S_addr = (pDnsIter->Data.A.IpAddress);
+    memcpy(host->h_addr_list[0], (char*)&host_addr, sizeof(pDnsIter->Data.A.IpAddress));
+    host->h_addr_list[1] = NULL;
+    DnsRecordListFree(pDnsRecord, freetype);
+
+    return 0;
+}
+
+
+/*
+	retrieves the host information corresponding to a network address in the DNS database
+	\param[in]	addr Pointer to an address in network byte order
+	\param[in]	len  Length of the address, in bytes
+	\param[in]  type Type of the address, such as the AF_INET address family type (defined as TCP,
+				UDP, and other associated Internet protocols). Address family types and their corresponding
+				values are defined in the Winsock2.h header file.
+	\retval		returns a pointer to the hostent structure that contains the name and address corresponding
+				to the given network address. The structure is allocated by the library.  The caller must never
+				attempt to modify this structure or to free any of its components. Furthermore, only one copy of this
+				structure is allocated per call per thread, so the application should copy any information it needs before
+				issuing another rgethostbyaddr.
+				NULL if the search has failed
+
+*/
+
+struct hostent *
+WINAPI
+rgethostbyaddr(const char *addr, int len, int type)
+{
+    DNS_STATUS status;
+    struct hostent* host;
+#ifdef DEBUG
+    char debstr[80];
+#endif
+
+    PDNS_RECORD pDnsRecord;
+    DNS_FREE_TYPE freetype ;
+    char qbuf[BUFSIZ];
+
+    if (type != AF_INET)
+        return ((struct hostent *) NULL);
+
+    wsprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
+         ((unsigned)addr[3] & 0xff),
+         ((unsigned)addr[2] & 0xff),
+         ((unsigned)addr[1] & 0xff),
+         ((unsigned)addr[0] & 0xff));
+
+
+    freetype =  DnsFreeRecordListDeep;
+
+
+    status = DnsQuery_A(qbuf,                 //pointer to OwnerName
+                        DNS_TYPE_PTR,         //Type of the record to be queried
+                        DNS_QUERY_STANDARD,
+                        NULL,                   //contains DNS server IP address
+                        &pDnsRecord,                //Resource record comprising the response
+                        NULL);                     //reserved for future use
+
+    if (status) {
+#ifdef DEBUG
+        if (_res.options & RES_DEBUG)
+        {
+            wsprintf(debstr, "res_query failed\n");
+            OutputDebugString(debstr);
+        }
+#endif
+
+        return  NULL;
+    }
+
+    host = (struct hostent*)(TlsGetValue(dwGhaIndex));
+    if (host == NULL) {
+	LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hostent));
+	if (lpvData != NULL) {
+	    TlsSetValue(dwGhaIndex, lpvData);
+	    host = (struct hostent*)lpvData;
+	} else
+	    return NULL;
+    }
+
+    if (host->h_name == NULL)
+	host->h_name = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH);
+    if (host->h_aliases == NULL)
+	host->h_aliases = LocalAlloc(LPTR, 1*sizeof(LPSTR));
+    if (host->h_addr_list == NULL)
+    {
+	host->h_addr_list = LocalAlloc(LPTR, 2*sizeof(LPSTR));
+	host->h_addr_list[0] = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH);
+    }
+
+    strcpy(host->h_name, pDnsRecord->Data.Ptr.pNameHost);
+    host->h_addrtype = type;
+    host->h_length = len;
+    host->h_aliases[0] = NULL;
+    memcpy(host->h_addr_list[0], addr, sizeof(unsigned long));
+    host->h_addr_list[1] = NULL;
+    DnsRecordListFree(pDnsRecord, freetype);
+
+    return host;
+
+}
+
+
+/*
+
+  @doc MISC
+
+  @func LPSTR WINAPI | gethinfobyname | Given the name
+  of a host query the nameservers for the T_HINFO information
+  associated with the host. unsupported
+
+  @parm LPSTR | name | pointer to the name of the host that the query is about.
+
+  @rdesc NULL or a pointer to the T_HINFO.
+
+
+*/
+
+LPSTR
+WINAPI
+gethinfobyname(LPSTR name)
+{
+    return NULL;
+
+}
+
+
+/*
+
+  @func struct mxent  * WINAPI | getmxbyname | This
+  function will query the nameservers for the MX records associated
+  with the given hostname. Note that the return is a pointer to the
+  mxent structure so an application making this call can iterate
+  through the different records returned and can also reference the
+  preference information associated with each hostname returned. unsupported
+
+  @parm LPSTR | name | The name of the host for which we want MX records.
+
+  @rdesc NULL or a pointer to a mxent structure.
+
+ */
+
+struct mxent  *
+WINAPI
+getmxbyname(LPSTR name)
+{
+    return NULL;
+}
+
+
+/*
+
+  @func LPSTR WINAPI | getrecordbyname | This function
+  will query the nameservers about the given hostname for and DNS
+  record type that the application wishes to query. unsupported
+
+  @parm LPSTR | name | a pointer to the hostname
+
+  @parm int | rectype | a DNS record type, e.g. T_MX, T_HINFO, ...
+
+  @rdesc The return is NULL or a pointer to a string containing the
+  data returned. It is up to the calling application to parse the
+  string appropriately for the rectype queried.
+
+*/
+
+LPSTR
+WINAPI
+getrecordbyname(LPSTR name, int rectype)
+{
+    return NULL;
+}
+
+
+/*
+
+  @func DWORD WINAPI | rrhost | This function emulates the
+  rhost function that was part of Excelan / Novell's LAN WorkPlace TCP/IP API.
+  Given a pointer to an IP hostname it will return the IP address as a 32 bit
+  integer.
+
+
+  @parm LPSTR | lpHost | a pointer to the hostname.
+
+  @rdesc 0 or the IP address as a 32 bit integer.
+
+*/
+
+DWORD WINAPI rrhost( LPSTR lpHost )
+{
+    return (DWORD) 0;
+}
+
+
+/*
+	retrieves service information corresponding to a service name and protocol.
+
+	\param[in]	name Pointer to a null-terminated service name.
+	\param[in]  proto pointer to a null-terminated protocol name. getservbyname should match both
+				the name and the proto.
+
+	\retval		a pointer to the servent structure containing the name(s) and service number that match the name and proto
+				parameters. The structure is allocated by the library.  The caller must never
+				attempt to modify this structure or to free any of its components. Furthermore, only one copy of this
+				structure is allocated per call per thread, so the application should copy any information it needs before
+				issuing another rgetservbyname.
+				NULL if the search has failed
+
+*/
+
+struct servent  * WINAPI rgetservbyname(LPCSTR name, LPCSTR proto)
+{
+    struct servent  * WINAPI hes_getservbyname(LPCSTR name, LPCSTR proto);
+    struct servent  *tmpent;
+
+    tmpent = hes_getservbyname(name, proto);
+    return (!hes_error()) ? tmpent : getservbyname(name, proto);
+}

Copied: trunk/src/util/wshelper/hesiod.c (from rev 25272, trunk/src/windows/wshelper/hesiod.c)
===================================================================
--- trunk/src/util/wshelper/hesiod.c	                        (rev 0)
+++ trunk/src/util/wshelper/hesiod.c	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,359 @@
+/*
+  @doc HESIOD
+
+  @module hesiod.c |
+
+  This module contains the defintions for the exported functions:
+		hes_to_bind
+		hes_resolve
+		hes_error
+        hes_free
+  as well as the internal function hes_init. The hes_init function
+  is the one that determines what the Hesiod servers are for your
+  site and will parse the configuration files, if any are
+  present.
+
+  WSHelper DNS/Hesiod Library for WINSOCK
+
+*/
+
+/* This file is part of the Hesiod library.
+ *
+ * The BIND 4.8.1 implementation of T_TXT is incorrect; BIND 4.8.1 declares
+ * it as a NULL terminated string.  The RFC defines T_TXT to be a length
+ * byte followed by arbitrary changes.
+ *
+ * Because of this incorrect declaration in BIND 4.8.1, when this bug is fixed,
+ * T_TXT requests between machines running different versions of BIND will
+ * not be compatible (nor is there any way of adding compatibility).
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.  See the
+ * file <mit-copyright.h> for copying and distribution information.
+ */
+
+#define index(str, c) strchr(str,c)
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <windows.h>
+#include <winsock.h>
+#include <string.h>
+#include <hesiod.h>
+#include <resolv.h>
+#include <windns.h>
+
+#include "resource.h"
+
+
+#define USE_HS_QUERY	/* undefine this if your higher-level name servers */
+			/* don't know class HS */
+
+char HesConfigFile[_MAX_PATH];
+static char Hes_LHS[256];
+static char Hes_RHS[256];
+static int Hes_Errno = HES_ER_UNINIT;
+
+extern  DWORD dwHesIndex;
+
+
+
+/*
+
+  @func int | hes_init |
+
+  This function is not exported.  It takes no arguments. However it is
+  important to understand how this works. It sets the global variables
+  Hes_LHS and Hes_RHS which are used to form the Hesiod
+  queries. Understanding how this works and setting up the correct
+  configuration will determine if the Hesiod queries will work at your
+  site. Settings can be configured by makgin source code changes and
+  rebuilding the DLL, editing resources in the DLL, using a
+  configuration file, or setting an environment variable.
+
+  The function first tries to open the HesConfigFile and set the
+  Hes_RHS and Hes_LHS variables from this. If there is no config file
+  then the function tries to load a string resource from the DLL to
+  set the LHS and RHS. If the string resources cannot be loaded then
+  the LHS and RHS will be set by the values of DEF_LHS and DEF_RHS,
+  these are defined in hesiod.h. Note that the string resources are by
+  default set to these same values since the RC files include hesiod.h
+
+  Finally if the user sets the environment variable HES_DOMAIN the RHS
+  will be overridden by the value of the HES_DOMAIN value.
+
+  Note that LoadString requires us to first find the module handle of
+  the DLL. We have to use the internal module name as defined in the
+  DEF file. If you change the library name within the DEF file you
+  also need to change the appropriate string in hesiod.c
+
+*/
+int hes_init( void )
+{
+    register FILE *fp;
+    register char  *key;
+    register char  *cp;
+    char buf[MAXDNAME+7];
+    HMODULE hModWSHelp;
+
+
+    Hes_Errno = HES_ER_UNINIT;
+    Hes_LHS[0] = '\0';
+    Hes_RHS[0] = '\0';
+
+    // Note: these must match the DEF file entries
+#if defined(_WIN64)
+	hModWSHelp = GetModuleHandle( "WSHELP64" );
+#else
+	hModWSHelp = GetModuleHandle( "WSHELP32" );
+#endif
+
+    if(!LoadString( hModWSHelp, IDS_DEF_HES_CONFIG_FILE,
+                    HesConfigFile, sizeof(HesConfigFile) )){
+        strcpy( HesConfigFile, HESIOD_CONF);
+    }
+
+    if ((fp = fopen(HesConfigFile, "r")) == NULL) {
+        /* use defaults compiled in */
+        /* no file or no access uses defaults */
+        /* but poorly formed file returns error */
+
+        if(!LoadString( hModWSHelp, IDS_DEF_HES_RHS, Hes_RHS, sizeof(Hes_RHS) )){
+            strcpy( Hes_RHS, DEF_RHS);
+        }
+
+        if(!LoadString( hModWSHelp, IDS_DEF_HES_LHS, Hes_LHS, sizeof(Hes_LHS) )){
+            strcpy( Hes_LHS, DEF_LHS);
+        }
+    } else {
+        while(fgets((LPSTR) buf, MAXDNAME+7, fp) != NULL) {
+            cp = (LPSTR) buf;
+            if (*cp == '#' || *cp == '\n'){
+                continue;
+            }
+            while(*cp == ' ' || *cp == '\t'){
+                cp++;
+            }
+            key = cp;
+            while(*cp != ' ' && *cp != '\t' && *cp != '='){
+                cp++;
+            }
+            *cp++ = '\0';
+            if (strcmp(key, "lhs") == 0){
+                strncpy(&Hes_LHS[0], cp, (strlen(cp)-1));
+            } else if (strcmp(key, "rhs") == 0){
+                strncpy(&Hes_RHS[0], cp, (strlen(cp)-1));
+            } else {
+                continue;
+            }
+            while(*cp == ' ' || *cp == '\t' || *cp == '='){
+                cp++;
+            }
+            if (*cp != '.') {
+                Hes_Errno = HES_ER_CONFIG;
+                fclose(fp);
+                return(Hes_Errno);
+            }
+            // len = strlen(cp);
+            // *cpp = calloc((unsigned int) len, sizeof(char));
+            // (void) strncpy(*cpp, cp, len-1);
+        }
+        fclose(fp);
+    }
+    /* see if the RHS is overridden by environment variable */
+    if ((cp = getenv("HES_DOMAIN")) != NULL){
+        // Hes_RHS = strcpy(malloc(strlen(cp)+1),cp);
+        strcpy(Hes_RHS,cp);
+    }
+    /* the LHS may be null, the RHS must not be null */
+    if (Hes_RHS == NULL)
+        Hes_Errno = HES_ER_CONFIG;
+    else
+        Hes_Errno = HES_ER_OK;
+    return(Hes_Errno);
+}
+
+
+/*
+  hes_to_bind function use the LHS and RHS values and
+  binds them with the parameters so that a well formed DNS query may
+  be performed.
+
+  \param[in]	HesiodName		The Hesiod name such as a username or service name
+  \param[in]	HesiodNameType	The Hesiod name type such as pobox, passwd, or sloc
+
+  \retval		Returns NULL if there was an error. Otherwise the pointer to a string containing a valid query is returned.
+
+*/
+char *
+WINAPI
+hes_to_bind(LPSTR HesiodName,
+            LPSTR HesiodNameType)
+{
+    register char *cp, **cpp;
+    char* bindname;
+    LPVOID lpvData;
+    char *RHS;
+
+    cp = NULL;
+    cpp = NULL;
+
+    bindname = (LPSTR)(TlsGetValue(dwHesIndex));
+    if (bindname == NULL)
+    {
+        lpvData = LocalAlloc(LPTR, DNS_MAX_NAME_BUFFER_LENGTH);
+        if (lpvData != NULL)
+        {
+            TlsSetValue(dwHesIndex, lpvData);
+            bindname = (LPSTR)lpvData;
+        }
+        else
+            return NULL;
+    }
+    if (Hes_Errno == HES_ER_UNINIT || Hes_Errno == HES_ER_CONFIG)
+        (void) hes_init();
+    if (Hes_Errno == HES_ER_CONFIG)
+	return(NULL);
+    if (cp = index(HesiodName,'@')) {
+        if (index(++cp,'.'))
+            RHS = cp;
+        else
+            if (cpp = hes_resolve(cp, "rhs-extension"))
+                RHS = *cpp;
+            else {
+                Hes_Errno = HES_ER_NOTFOUND;
+                return(NULL);
+            }
+        (void) strcpy(bindname,HesiodName);
+        (*index(bindname,'@')) = '\0';
+    } else {
+        RHS = Hes_RHS;
+        (void) strcpy(bindname, HesiodName);
+    }
+    (void) strcat(bindname, ".");
+    (void) strcat(bindname, HesiodNameType);
+    if (Hes_LHS) {
+        if (Hes_LHS[0] != '.')
+            (void) strcat(bindname,".");
+        (void) strcat(bindname, Hes_LHS);
+    }
+    if (RHS[0] != '.')
+        (void) strcat(bindname,".");
+    (void) strcat(bindname, RHS);
+
+    if(cpp != NULL )
+        hes_free(cpp);
+
+    return(bindname);
+}
+
+
+/*
+	This function calls hes_to_bind to form a valid hesiod query, then queries the dns database.
+	defined in hesiod.c
+
+	\param[in]	HesiodName		The Hesiod name such as a username or service name
+	\param[in]	HesiodNameType	The Hesiod name type such as pobox, passwd, or sloc
+
+	\retval		returns a NULL terminated vector of strings (a la argv),
+				one for each resource record containing Hesiod data, or NULL if
+				there is any error. If there is an error call hes_error() to get
+				further information. You will need to call hes_free to free the result
+
+*/
+char **
+WINAPI
+hes_resolve(LPSTR HesiodName, LPSTR HesiodNameType)
+{
+    register char  *cp;
+    LPSTR* retvec;
+    DNS_STATUS status;
+
+    PDNS_RECORD pDnsRecord;
+    PDNS_RECORD pR;
+    DNS_FREE_TYPE freetype ;
+    int i = 0;
+    freetype =  DnsFreeRecordListDeep;
+
+
+    cp = hes_to_bind(HesiodName, HesiodNameType);
+    if (cp == NULL) return(NULL);
+    errno = 0;
+
+
+    status = DnsQuery_A(cp,                 //pointer to OwnerName
+                        DNS_TYPE_TEXT,         //Type of the record to be queried
+                        DNS_QUERY_STANDARD,     // Bypasses the resolver cache on the lookup.
+                        NULL,                   //contains DNS server IP address
+                        &pDnsRecord,                //Resource record comprising the response
+                        NULL);                     //reserved for future use
+
+    if (status) {
+        errno = status;
+        Hes_Errno = HES_ER_NOTFOUND;
+        return  NULL;
+    }
+
+    pR = pDnsRecord;
+    while (pR)
+    {
+        if (pR->wType == DNS_TYPE_TEXT)
+            i++;
+        pR = pR->pNext;
+    }
+    i++;
+    retvec = LocalAlloc(LPTR, i*sizeof(LPSTR));
+    pR = pDnsRecord;
+    i = 0;
+    while (pR)
+    {
+        if (pR->wType == DNS_TYPE_TEXT){
+            SIZE_T l = strlen(((pR->Data).Txt.pStringArray)[0]);
+            retvec[i] = LocalAlloc(LPTR, l+1);
+            strcpy(retvec[i], ((pR->Data).Txt.pStringArray)[0]);
+            i++;
+        }
+        pR = pR->pNext;
+    }
+    retvec[i] = NULL;
+    DnsRecordListFree(pDnsRecord, freetype);
+    return retvec;
+
+}
+
+
+/*
+	The  function  hes_error may be called to determine the
+	source of the error.  It does not take an argument.
+
+	\retval		return one of the HES_ER_* codes defined in hesiod.h.
+*/
+
+int
+WINAPI
+hes_error(void)
+{
+    return(Hes_Errno);
+}
+
+
+/*
+
+	The function hes_free should be called to free up memeory returned by
+	hes_resolve
+
+	\param[in]	hesinfo		a NULL terminiated array of strings returned by hes_resolve
+
+
+*/
+void
+WINAPI
+hes_free(LPSTR* info)
+{
+    int i= 0;
+    for (; info[i]; i++)
+    {
+        LocalFree(info[i]);
+    }
+    LocalFree(info);
+}
\ No newline at end of file

Copied: trunk/src/util/wshelper/hesmailh.c (from rev 25272, trunk/src/windows/wshelper/hesmailh.c)
===================================================================
--- trunk/src/util/wshelper/hesmailh.c	                        (rev 0)
+++ trunk/src/util/wshelper/hesmailh.c	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,87 @@
+/*
+ *	@doc HESIOD
+ *
+ * @module hesmailh.c |
+ *
+ * This file contains hes_postoffice, which retrieves post-office information
+ * for a user.
+ *
+ *  For copying and distribution information, see the file
+ *  <lt> mit-copyright.h <gt>
+ *
+ *  Original version by Steve Dyer, IBM/Project Athena.
+ *
+ *	WSHelper DNS/Hesiod Library for WINSOCK
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h> /*s*/
+
+#include <hesiod.h>
+
+
+#define LINESIZE 80
+
+extern DWORD dwHesMailIndex;
+
+
+/*
+	This call is used to obtain a user's type of mail account and the location of that
+	account. E.g. POP PO10.MIT.EDU or IMAP IMAP-TEST.MIT.EDU
+
+	defined in hesmailh.c
+
+	\param[in]	user	The username to be used when querying for the Hesiod Name Type POBOX.
+
+	\retval				NULL if there was an error or if there was no entry for the
+						username. Otherwise a pointer to a hes_postoffice structure is
+						returned. The caller must never attempt to modify this structure or to free
+						any of its components. Furthermore, only one copy of this structure is allocated per call per thread, so the application should copy any information it needs before
+						issuing another getmailhost call
+
+*/
+struct hes_postoffice  *
+WINAPI
+hes_getmailhost(LPSTR user)
+{
+    struct hes_postoffice* ret;
+    char linebuf[LINESIZE];
+    char *p, *tmp;
+    char **cp;
+
+
+    cp = hes_resolve(user, "pobox");
+    if (cp == NULL) return(NULL);
+
+    ret = (struct hes_postoffice*)(TlsGetValue(dwHesMailIndex));
+    if (ret == NULL) {
+	LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct hes_postoffice));
+	if (lpvData != NULL) {
+	    TlsSetValue(dwHesMailIndex, lpvData);
+	    ret = (struct hes_postoffice*)lpvData;
+	} else
+	    return NULL;
+    }
+    if (!ret->po_type)
+        ret->po_type = LocalAlloc(LPTR, LINESIZE);
+    if (!ret->po_host)
+        ret->po_host = LocalAlloc(LPTR, LINESIZE);
+    if (!ret->po_name)
+        ret->po_name = LocalAlloc(LPTR, LINESIZE);
+    strcpy(linebuf, *cp);
+
+    p = linebuf;
+    tmp = linebuf;
+    while(!isspace(*p)) p++;
+    *p++ = '\0';
+    strcpy(ret->po_type, tmp);
+    tmp = p;
+    while(!isspace(*p)) p++;
+    *p++ = '\0';
+    strcpy(ret->po_host, tmp);
+    strcpy(ret->po_name, p);
+    if (cp)
+        hes_free(cp);
+    return(ret);
+}

Copied: trunk/src/util/wshelper/hespwnam.c (from rev 25272, trunk/src/windows/wshelper/hespwnam.c)
===================================================================
--- trunk/src/util/wshelper/hespwnam.c	                        (rev 0)
+++ trunk/src/util/wshelper/hespwnam.c	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,196 @@
+/*
+ *	@doc HESIOD
+ *
+ * @module hespwnam.c |
+ *
+ * This file contains hes_getpwnam, for retrieving passwd information about
+ * a user.
+ *
+ * For copying and distribution information, see the file
+ * <lt> mit-copyright.h <gt>
+ *
+ * Original version by Steve Dyer, IBM/Project Athena.
+ *
+ *	  WSHelper DNS/Hesiod Library for WINSOCK
+ *
+ *
+ */
+
+/* This file contains hes_getpwnam, for retrieving passwd information about
+ * a user.
+ *
+ * For copying and distribution information, see the file <mit-copyright.h>
+ *
+ * Original version by Steve Dyer, IBM/Project Athena.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h> /*s*/
+
+#include <stdlib.h>
+
+#include <windows.h>
+#include <hesiod.h>
+
+#include "pwd.h"
+
+extern DWORD dwHesPwNamIndex;
+extern DWORD dwHesPwUidIndex;
+
+#define MAX_PW_BUFFER_LENGTH  64
+
+static char *
+_NextPWField(char *ptr);
+
+struct passwd *  GetPasswdStruct(struct passwd* pw, char* buf);
+
+
+
+
+/*
+	Given a UID this function will return the pwd information, eg username, uid,
+	gid, fullname, office location, phone number, home directory, and default shell
+
+	defined in hespwnam.c
+	\param	uid			The user ID
+	\retval				NULL if there was an error or a pointer to the passwd structure. The caller must
+						never attempt to modify this structure or to free any of its components.
+						Furthermore, only one copy of this structure is allocated per call per thread, so the application should copy any information it needs before
+						issuing another hes_getpwuid call
+*/
+struct passwd *
+WINAPI
+hes_getpwuid(int uid)
+{
+    char **pp;
+    struct passwd* pw = NULL;
+    char buf[256];
+
+    char nam[8];
+    sprintf(nam, "%d", uid);
+
+    pp = hes_resolve(nam, "uid");
+    if (pp == NULL || *pp == NULL)
+        return(NULL);
+
+    pw = (struct passwd*)(TlsGetValue(dwHesPwUidIndex));
+    if (pw == NULL) {
+	LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct passwd));
+	if (lpvData != NULL) {
+	    TlsSetValue(dwHesPwUidIndex, lpvData);
+	    pw = (struct passwd*)lpvData;
+	} else
+	    return NULL;
+    }
+
+    strcpy(buf, pp[0]);
+    hes_free(pp);
+    return GetPasswdStruct(pw, buf);
+}
+
+
+/*
+	Given a username this function will return the pwd information, eg
+	username, uid, gid, fullname, office location, phone number, home
+	directory, and default shell
+
+	defined in hespwnam.c
+
+	\param	nam			a pointer to the username
+
+	\retval				NULL if there was an error or a pointer to the passwd structure. The caller must
+						never attempt to modify this structure or to free any of its components.
+						Furthermore, only one copy of this structure is allocated per call per thread, so the application should copy any information it needs before
+						issuing another hes_getpwnam call
+
+*/
+struct passwd *
+WINAPI
+hes_getpwnam(char *nam)
+{
+
+   char **pp;
+   struct passwd* pw = NULL;
+   char buf[256];
+
+    pp = hes_resolve(nam, "passwd");
+    if (pp == NULL || *pp == NULL)
+        return(NULL);
+
+    pw = (struct passwd*)(TlsGetValue(dwHesPwNamIndex));
+    if (pw == NULL) {
+	LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct passwd));
+	if (lpvData != NULL) {
+	    TlsSetValue(dwHesPwNamIndex, lpvData);
+	    pw = (struct passwd*)lpvData;
+	} else
+	    return NULL;
+    }
+
+    strcpy(buf, pp[0]);
+    hes_free(pp);
+    return GetPasswdStruct(pw, buf);
+}
+
+
+struct passwd*  GetPasswdStruct(struct passwd* pw, char* buf)
+{
+    char* temp;
+    char* p;
+
+    if (pw->pw_name == NULL)
+	pw->pw_name = LocalAlloc(LPTR, MAX_PW_BUFFER_LENGTH);
+    if (pw->pw_passwd == NULL)
+	pw->pw_passwd = LocalAlloc(LPTR, MAX_PW_BUFFER_LENGTH);
+    if (pw->pw_comment == NULL)
+	pw->pw_comment = LocalAlloc(LPTR, MAX_PW_BUFFER_LENGTH);
+    if (pw->pw_gecos == NULL)
+	pw->pw_gecos = LocalAlloc(LPTR, MAX_PW_BUFFER_LENGTH);
+    if (pw->pw_dir == NULL)
+	pw->pw_dir = LocalAlloc(LPTR, MAX_PW_BUFFER_LENGTH);
+    if (pw->pw_shell == NULL)
+	pw->pw_shell = LocalAlloc(LPTR, MAX_PW_BUFFER_LENGTH);
+    /* choose only the first response (only 1 expected) */
+    p = buf;
+    temp = p;
+    p = _NextPWField(p);
+    strcpy(pw->pw_name, temp);
+    temp = p;
+    p = _NextPWField(p);
+    strcpy(pw->pw_passwd, temp);
+    pw->pw_uid = atoi(p);
+    p = _NextPWField(p);
+    pw->pw_gid = atoi(p);
+    pw->pw_quota = 0;
+    strcpy(pw->pw_comment, "");
+    p = _NextPWField(p);
+    temp = p;
+    p = _NextPWField(p);
+    strcpy(pw->pw_gecos, temp);
+    temp = p;
+    p = _NextPWField(p);
+    strcpy(pw->pw_dir,  temp);
+    temp = p;
+    while (*p && *p != '\n')
+        p++;
+    *p = '\0';
+    strcpy(pw->pw_shell, temp);
+    return pw;
+
+
+}
+
+/* Move the pointer forward to the next colon-separated field in the
+ * password entry.
+ */
+
+static char *
+_NextPWField(char *ptr)
+{
+    while (*ptr && *ptr != '\n' && *ptr != ':')
+        ptr++;
+    if (*ptr)
+        *ptr++ = '\0';
+    return(ptr);
+}

Copied: trunk/src/util/wshelper/hesservb.c (from rev 25272, trunk/src/windows/wshelper/hesservb.c)
===================================================================
--- trunk/src/util/wshelper/hesservb.c	                        (rev 0)
+++ trunk/src/util/wshelper/hesservb.c	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,137 @@
+/*
+ *	@doc HESIOD
+ *
+ * @module hesservb.c |
+ *
+ *
+ *	  Contains the definition for hes_getservbyname,
+ *
+ *	  WSHelper DNS/Hesiod Library for WINSOCK
+ *
+ */
+
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getservbyname.c	5.3 (Berkeley) 5/19/86";
+#endif /* LIBC_SCCS and not lint */
+
+#include <hesiod.h>
+#include <windows.h>
+#include <winsock.h>
+#include <windns.h>
+
+#include <string.h>
+
+#include <stdio.h>
+#include <ctype.h>
+
+#define cistrcmp stricmp
+
+#define LISTSIZE 15
+
+
+/*
+	This function will query a Hesiod server for a servent structure given
+	a service name and protocol. This is a replacement for the Winsock
+	getservbyname function which normally just uses a local services
+	file. This allows a site to use a centralized database for adding new
+	services.
+
+	defined in hesservb.c
+
+	\param[in]	name	pointer to the official name of the service, eg "POP3".
+	\param[in]	proto	pointer to the protocol to use when contacting the service, e.g. "TCP"
+
+	\retval				NULL if there was an error or a pointer to a servent structure. The caller must
+						never attempt to modify this structure or to free any of its components.
+						Furthermore, only one copy of this structure is allocated per call per thread, so the application should copy any information it needs before
+						issuing another hes_getservbyname call
+
+*/
+
+extern DWORD dwHesServIndex;
+struct servent *
+WINAPI
+hes_getservbyname(char *name, char *proto)
+{
+    struct servent *p;
+    register char **cp;
+    register char** hesinfo;
+    register int i = 0;
+
+    char buf[DNS_MAX_NAME_BUFFER_LENGTH];
+    char* l;
+
+    hesinfo = hes_resolve(name, "service");
+    cp = hesinfo;
+    if (cp == NULL)
+	return(NULL);
+    p = (struct servent*)(TlsGetValue(dwHesServIndex));
+    if (p == NULL) {
+	LPVOID lpvData = (LPVOID) LocalAlloc(LPTR, sizeof(struct servent));
+	if (lpvData != NULL) {
+	    TlsSetValue(dwHesServIndex, lpvData);
+	    p = (struct servent*)lpvData;
+	} else
+	    return NULL;
+    }
+    if (!p->s_name)
+        p->s_name = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH);
+    if (!p->s_proto)
+        p->s_proto = LocalAlloc(LPTR, DNS_MAX_LABEL_BUFFER_LENGTH);
+    if (!p->s_aliases)
+        p->s_aliases = LocalAlloc(LPTR, LISTSIZE*sizeof(LPSTR));
+
+    for (;*cp; cp++) {
+	register char *servicename, *protoname, *port;
+        strcpy(buf, *cp);
+        l = buf;
+	while(*l && (*l == ' ' || *l == '\t')) l++;
+	servicename = l;
+	while(*l && *l != ' ' && *l != '\t' && *l != ';') l++;
+	if (*l == '\0') continue; /* malformed entry */
+	*l++ = '\0';
+	while(*l && (*l == ' ' || *l == '\t')) l++;
+	protoname = l;
+	while(*l && *l != ' ' && *l != ';') l++;
+	if (*l == '\0') continue; /* malformed entry */
+	*l++ = '\0';
+	if (cistrcmp(proto, protoname)) continue; /* wrong port */
+	while(*l && (*l == ' ' || *l == '\t' || *l == ';')) l++;
+	if (*l == '\0') continue; /* malformed entry */
+	port = l;
+	while(*l && (*l != ' ' && *l != '\t' && *l != ';')) l++;
+	if (*l) *l++ = '\0';
+	if (*l != '\0') {
+	    do {
+		char* tmp = l;
+		while(*l && !isspace(*l)) l++;
+		if (*l) *l++ = 0;
+                if (p->s_aliases[i])
+                    p->s_aliases[i] = LocalAlloc(LPTR, strlen(tmp));
+                strcpy(p->s_aliases[i], tmp);
+                i++;
+	    } while(*l);
+	}
+	p->s_aliases[i] = NULL;
+        for (; i<LISTSIZE; i++)
+        {
+            if (p->s_aliases[i]){
+                LocalFree(p->s_aliases[i]);
+                p->s_aliases[i] = NULL;
+            }
+        }
+	strcpy(p->s_name, servicename);
+	p->s_port = htons((u_short)atoi(port));
+	strcpy(p->s_proto, protoname);
+        if (hesinfo)
+            hes_free(hesinfo);
+	return (p);
+    }
+    return(NULL);
+}

Copied: trunk/src/util/wshelper/inetaton.c (from rev 25272, trunk/src/windows/wshelper/inetaton.c)
===================================================================
--- trunk/src/util/wshelper/inetaton.c	                        (rev 0)
+++ trunk/src/util/wshelper/inetaton.c	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,153 @@
+/*
+ *
+ *	@doc RESOLVE
+ *
+ * @module inetaton.c  |
+ *
+ *      from the BIND 4.9.x inetaddr.c
+ *
+ *	  Contains implementation of inet_aton
+
+ *	  WSHelper DNS/Hesiod Library for WINSOCK
+ *
+ */
+
+/*
+ * Copyright (c) 1983, 1990 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_addr.c	5.11 (Berkeley) 12/9/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <windows.h>
+#include <winsock.h>
+#include <ctype.h>
+
+
+/*
+	converts a string containing an (Ipv4) Internet Protocol dotted address into a proper address for the in_addr structure
+
+	\param[in]	cp Null-terminated character string representing a number expressed in the
+	Internet standard ".'' (dotted) notation.
+	\param[in, out] addr pointer to the in_addr structure. The s_addr memeber will be populated
+
+
+	\retval Returns 1 if the address is valid, 0 if not.
+
+ */
+unsigned long
+WINAPI
+inet_aton(register const char *cp, struct in_addr *addr)
+{
+    register u_long val, base;
+	ULONG_PTR n;
+    register char c;
+    u_long parts[4], *pp = parts;
+
+    for (;;) {
+        /*
+         * Collect number up to ``.''.
+         * Values are specified as for C:
+         * 0x=hex, 0=octal, other=decimal.
+         */
+        val = 0; base = 10;
+        if (*cp == '0') {
+            if (*++cp == 'x' || *cp == 'X')
+                base = 16, cp++;
+            else
+                base = 8;
+        }
+        while ((c = *cp) != '\0') {
+            if (isascii(c) && isdigit(c)) {
+                val = (val * base) + (c - '0');
+                cp++;
+                continue;
+            }
+            if (base == 16 && isascii(c) && isxdigit(c)) {
+                val = (val << 4) +
+                    (c + 10 - (islower(c) ? 'a' : 'A'));
+                cp++;
+                continue;
+            }
+            break;
+        }
+        if (*cp == '.') {
+            /*
+             * Internet format:
+             *	a.b.c.d
+             *	a.b.c	(with c treated as 16-bits)
+             *	a.b	(with b treated as 24 bits)
+             */
+            if (pp >= parts + 3 || val > 0xff)
+                return (0);
+            *pp++ = val, cp++;
+        } else
+            break;
+    }
+    /*
+     * Check for trailing characters.
+     */
+    if (*cp && (!isascii(*cp) || !isspace(*cp)))
+        return (0);
+    /*
+     * Concoct the address according to
+     * the number of parts specified.
+     */
+    n = pp - parts + 1;
+    switch (n) {
+
+    case 1:				/* a -- 32 bits */
+        break;
+
+    case 2:				/* a.b -- 8.24 bits */
+        if (val > 0xffffff)
+            return (0);
+        val |= parts[0] << 24;
+        break;
+
+	case 3:				/* a.b.c -- 8.8.16 bits */
+            if (val > 0xffff)
+                return (0);
+            val |= (parts[0] << 24) | (parts[1] << 16);
+            break;
+
+	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
+            if (val > 0xff)
+                return (0);
+            val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+            break;
+    }
+    if (addr)
+        addr->s_addr = htonl(val);
+    return (1);
+}

Copied: trunk/src/util/wshelper/pwd.h (from rev 25272, trunk/src/windows/wshelper/pwd.h)
===================================================================
--- trunk/src/util/wshelper/pwd.h	                        (rev 0)
+++ trunk/src/util/wshelper/pwd.h	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,15 @@
+/*	pwd.h	4.1	83/05/03	*/
+
+struct	passwd { /* see getpwent(3) */
+	char	*pw_name;
+	char	*pw_passwd;
+	int	pw_uid;
+	int	pw_gid;
+	int	pw_quota;
+	char	*pw_comment;
+	char	*pw_gecos;
+	char	*pw_dir;
+	char	*pw_shell;
+};
+
+struct passwd *getpwent(), *getpwuid(), *getpwnam();

Copied: trunk/src/util/wshelper/res_comp.c (from rev 25272, trunk/src/windows/wshelper/res_comp.c)
===================================================================
--- trunk/src/util/wshelper/res_comp.c	                        (rev 0)
+++ trunk/src/util/wshelper/res_comp.c	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,361 @@
+/*
+ *
+ *	@doc RESOLVE
+ *
+ * @module res_comp.c |
+ *
+ *	  Contains the implementations for dn_comp and rdn_expand as well as
+ *	  some other functions used internally by these two functions.
+ *
+ *	  WSHelper DNS/Hesiod Library for WINSOCK
+ *
+ */
+
+/*
+ * Copyright (c) 1985 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_comp.c	6.22 (Berkeley) 3/19/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <windows.h>
+#include <winsock.h>
+#include <resolv.h>
+#include <stdio.h>
+
+
+static dn_find();
+
+/*
+	replacement for dn_expand called rdn_expand. Older versions of
+	the DLL used to this as dn_expand but this has caused some
+	conflict with more recent versions of the MSDEV
+	libraries. rdn_expand() expands the compressed domain name comp_dn to
+	a full domain name.  Expanded names are converted to upper case.
+
+	\param[in]	msg		msg is a pointer to the  beginning  of  the  message
+	\param[in]	eomorig
+	\param[in]			comp_dn the compressed domain name.
+	\param[in, out]		expn_dn	a pointer to the result buffer
+	\param[in]			length	size of the result in expn_dn
+
+	\retval				the size of compressed name is returned or -1 if there was an error.
+*/
+
+
+
+int WINAPI
+rdn_expand(const u_char *msg, const u_char *eomorig,
+		   const u_char *comp_dn, u_char *exp_dn, int length)
+{
+    register u_char *cp, *dn;
+    register int n, c;
+    u_char *eom;
+	INT_PTR len = -1;
+    int checked = 0;
+
+    dn = exp_dn;
+    cp = (u_char *)comp_dn;
+    eom = exp_dn + length;
+    /*
+     * fetch next label in domain name
+     */
+    while (n = *cp++) {
+        /*
+         * Check for indirection
+         */
+        switch (n & INDIR_MASK) {
+        case 0:
+            if (dn != exp_dn) {
+                if (dn >= eom)
+                    return (-1);
+                *dn++ = '.';
+            }
+            if (dn+n >= eom)
+                return (-1);
+            checked += n + 1;
+            while (--n >= 0) {
+                if ((c = *cp++) == '.') {
+                    if (dn + n + 2 >= eom)
+                        return (-1);
+                    *dn++ = '\\';
+                }
+                *dn++ = c;
+                if (cp >= eomorig)      /* out of range */
+                    return(-1);
+            }
+            break;
+
+        case INDIR_MASK:
+            if (len < 0)
+                len = cp - comp_dn + 1;
+            cp = (u_char *)msg + (((n & 0x3f) << 8) | (*cp & 0xff));
+            if (cp < msg || cp >= eomorig)  /* out of range */
+                return(-1);
+            checked += 2;
+            /*
+             * Check for loops in the compressed name;
+             * if we've looked at the whole message,
+             * there must be a loop.
+             */
+            if (checked >= eomorig - msg)
+                return (-1);
+            break;
+
+        default:
+            return (-1);                    /* flag error */
+        }
+    }
+    *dn = '\0';
+    if (len < 0)
+        len = cp - comp_dn;
+    return (int)(len);
+}
+
+
+/*
+	Compress domain name 'exp_dn' into 'comp_dn'
+	\param[in]	exp_dn	name to compress
+	\param[in, out]	comp_dn		result of the compression
+	\paramp[in]	length			the size of the array pointed to by 'comp_dn'.
+	\param[in, out]	dnptrs		a list of pointers to previous compressed names. dnptrs[0]
+								is a pointer to the beginning of the message. The list ends with NULL.
+	\param[in]	lastdnptr		a pointer to the end of the arrary pointed to by 'dnptrs'. Side effect
+								is to update the list of pointers for labels inserted into the
+								message as we compress the name. If 'dnptr' is NULL, we don't try to
+								compress names. If 'lastdnptr' is NULL, we don't update the list.
+	\retval						Return the size of the compressed name or -1
+ */
+int WINAPI
+dn_comp(const u_char *exp_dn, u_char *comp_dn, int length,
+        u_char **dnptrs, u_char **lastdnptr)
+{
+    register u_char *cp, *dn;
+    register int c, l;
+    u_char **cpp, **lpp, *sp, *eob;
+    u_char *msg;
+
+    dn = (u_char *)exp_dn;
+    cp = comp_dn;
+    eob = cp + length;
+    if (dnptrs != NULL) {
+        if ((msg = *dnptrs++) != NULL) {
+            for (cpp = dnptrs; *cpp != NULL; cpp++)
+                ;
+            lpp = cpp;      /* end of list to search */
+        }
+    } else
+        msg = NULL;
+    for (c = *dn++; c != '\0'; ) {
+        /* look to see if we can use pointers */
+        if (msg != NULL) {
+            if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) {
+                if (cp+1 >= eob)
+                    return (-1);
+                *cp++ = (l >> 8) | INDIR_MASK;
+                *cp++ = l % 256;
+                return (int)(cp - comp_dn);
+            }
+            /* not found, save it */
+            if (lastdnptr != NULL && cpp < lastdnptr-1) {
+                *cpp++ = cp;
+                *cpp = NULL;
+            }
+        }
+        sp = cp++;      /* save ptr to length byte */
+        do {
+            if (c == '.') {
+                c = *dn++;
+                break;
+            }
+            if (c == '\\') {
+                if ((c = *dn++) == '\0')
+                    break;
+            }
+            if (cp >= eob) {
+                if (msg != NULL)
+                    *lpp = NULL;
+                return (-1);
+            }
+            *cp++ = c;
+        } while ((c = *dn++) != '\0');
+        /* catch trailing '.'s but not '..' */
+        if ((l =(int)( cp - sp - 1)) == 0 && c == '\0') {
+            cp--;
+            break;
+        }
+        if (l <= 0 || l > MAXLABEL) {
+            if (msg != NULL)
+                *lpp = NULL;
+            return (-1);
+        }
+        *sp = l;
+    }
+    if (cp >= eob) {
+        if (msg != NULL)
+            *lpp = NULL;
+        return (-1);
+    }
+    *cp++ = '\0';
+    return (int)(cp - comp_dn);
+}
+
+/*
+ * Skip over a compressed domain name. Return the size or -1.
+ */
+__dn_skipname(const u_char *comp_dn, const u_char *eom)
+{
+    register u_char *cp;
+    register int n;
+
+    cp = (u_char *)comp_dn;
+    while (cp < eom && (n = *cp++)) {
+        /*
+         * check for indirection
+         */
+        switch (n & INDIR_MASK) {
+        case 0:         /* normal case, n == len */
+            cp += n;
+            continue;
+        default:        /* illegal type */
+            return (-1);
+        case INDIR_MASK:        /* indirection */
+            cp++;
+        }
+        break;
+    }
+    return (int)(cp - comp_dn);
+}
+
+/*
+ * Search for expanded name from a list of previously compressed names.
+ * Return the offset from msg if found or -1.
+ * dnptrs is the pointer to the first name on the list,
+ * not the pointer to the start of the message.
+ */
+static
+dn_find(u_char *exp_dn, u_char *msg, u_char **dnptrs, u_char **lastdnptr)
+{
+    register u_char *dn, *cp, **cpp;
+    register int n;
+    u_char *sp;
+
+    for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
+        dn = exp_dn;
+        sp = cp = *cpp;
+        while (n = *cp++) {
+            /*
+             * check for indirection
+             */
+            switch (n & INDIR_MASK) {
+            case 0:         /* normal case, n == len */
+                while (--n >= 0) {
+                    if (*dn == '.')
+                        goto next;
+                    if (*dn == '\\')
+                        dn++;
+                    if (*dn++ != *cp++)
+                        goto next;
+                }
+                if ((n = *dn++) == '\0' && *cp == '\0')
+                    return (int)(sp - msg);
+                if (n == '.')
+                    continue;
+                goto next;
+
+            default:        /* illegal type */
+                return (-1);
+
+            case INDIR_MASK:        /* indirection */
+                cp = msg + (((n & 0x3f) << 8) | *cp);
+            }
+        }
+        if (*dn == '\0')
+            return (int)(sp - msg);
+    next:   ;
+    }
+    return (-1);
+}
+
+/*
+ * Routines to insert/extract short/long's. Must account for byte
+ * order and non-alignment problems. This code at least has the
+ * advantage of being portable.
+ *
+ * used by sendmail.
+ */
+
+u_short
+_getshort(u_char *msgp)
+{
+    register u_char *p = (u_char *) msgp;
+#ifdef vax
+    /*
+     * vax compiler doesn't put shorts in registers
+     */
+    register u_long u;
+#else
+    register u_short u;
+#endif
+
+    u = *p++ << 8;
+    return ((u_short)(u | *p));
+}
+
+u_long
+_getlong(u_char *msgp)
+{
+    register u_char *p = (u_char *) msgp;
+    register u_long u;
+
+    u = *p++; u <<= 8;
+    u |= *p++; u <<= 8;
+    u |= *p++; u <<= 8;
+    return (u | *p);
+}
+
+void
+__putshort(register u_short s, register u_char *msgp)
+{
+    msgp[1] = LOBYTE(s);
+    msgp[0] = HIBYTE(s);
+}
+
+void
+__putlong(register u_long l, register u_char *msgp)
+{
+    msgp[3] = LOBYTE(LOWORD(l));
+    msgp[2] = HIBYTE(LOWORD(l));
+    msgp[1] = LOBYTE(HIWORD(l));
+    msgp[0] = HIBYTE(HIWORD(l));
+}

Copied: trunk/src/util/wshelper/res_init.c (from rev 25272, trunk/src/windows/wshelper/res_init.c)
===================================================================
--- trunk/src/util/wshelper/res_init.c	                        (rev 0)
+++ trunk/src/util/wshelper/res_init.c	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,814 @@
+/*
+ * @doc RESOLVE
+ *
+ * @module res_init.c |
+ *
+ * Contains the implementation for res_init, res_getopts, res_setopts
+ * and supplementary internal functions. If you are adding support for a
+ * new TCP/IP stack of resolver configuration information this is where
+ * it will go.
+ * @xref <f res_init> <f res_setopts> <f res_getopts> <f WhichOS> <f getRegKey>
+ *
+ * WSHelper DNS/Hesiod Library for WINSOCK
+ *
+ */
+
+/*-
+ * Copyright (c) 1985, 1989 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_init.c  6.15 (Berkeley) 2/24/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <windows.h>
+#include <winsock.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <windns.h>   //DNS api's
+
+#include <shellapi.h>
+
+
+#include <mitwhich.h>
+
+#include "resource.h"
+
+char debstr[80];
+
+#define index strchr
+
+#ifndef MAKELONG
+#define MAKELONG(a, b)      ((LONG)(((WORD)(a)) | ((DWORD)((WORD)(b))) << 16))
+#endif
+
+#define TCPIP_PATH "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"
+#define HKEY_MIT_PRIVATE HKEY_CLASSES_ROOT
+#define WSH_MIT_PRIVATE_DOMAIN_SUBKEY TCPIP_PATH"\\Domain"
+#define WSH_MIT_PRIVATE_NAMESERVER_SUBKEY TCPIP_PATH"\\NameServer"
+
+DWORD WhichOS( DWORD *check);
+
+static int const getRegKeyEx(const HKEY key, const char *subkey, const char *value, char *buf, unsigned int len);
+
+int WINAPI wsh_getdomainname(char* name, int size);
+
+static HMODULE this_module();
+
+
+/*
+ * Resolver state default settings
+ */
+// @struct _res | a structure of this type holds the state information for the
+// resolver options
+struct state _res = {
+    RES_TIMEOUT,                    /* @field retransmition time interval */
+    4,                              /* @field number of times to retransmit */
+    RES_DEFAULT,                    /* @field options flags */
+    1,                              /* @field number of name servers */
+};
+
+#ifndef _MSC_VER
+
+#define _upcase(c) (((c) <= 'Z' && (c) >= 'A') ? (c) + 'a' - 'A' : (c))
+#define _chricmp(a, b) (_upcase(a) - _upcase(b))
+
+int
+#ifdef __cplusplus
+inline
+#endif
+_strnicmp( register const char *a, register const char *b, register size_t n)
+{
+    register int cmp = 0; /* equal */
+    while( n-- && !(cmp = _chricmp(*a, *b)) && (a++, *b++) /* *a == *b anyways */ );
+    return cmp;
+};
+
+#endif
+
+
+/*
+	This function retrieves the default domain name and search order. It will look to see if an
+	environment variable LOCALDOMAIN is defined. Otherwise, the domain associated with the local host
+	is used. Otherwise, it will try to find the domain name from the registry
+
+	\retval		The return value is 0 if the operation was successful.
+				Otherwise the value -1 is returned.
+
+*/
+int
+WINAPI
+res_init()
+{
+    register char *cp, **pp;
+
+    register int n;
+
+    int haveenv = 0;	/* have an environment variable for local domain */
+    int havedomain = 0; /* 0 or 1 do we have a value for the domain */
+
+    LONG result1 = -1995;
+
+#define WSH_SPACES " \t,;="
+
+    _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
+    _res.nsaddr.sin_family = AF_INET;
+    _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
+    _res.nscount = 1;
+
+
+    /* Allow user to override the local domain definition */
+    if ((cp = getenv("LOCALDOMAIN")) != NULL) {
+        strncpy(_res.defdname, cp, sizeof(_res.defdname));
+        haveenv++;
+        havedomain++;
+    };
+
+    if (!havedomain) {
+        if (!wsh_getdomainname(_res.defdname, sizeof(_res.defdname)))
+            havedomain++;
+    }
+
+
+
+    if( 0 != havedomain){
+        // return early, we've done our job
+        /* find components of local domain that might be searched */
+
+            pp = _res.dnsrch;
+            *pp++ = _res.defdname;
+            for (cp = _res.defdname, n = 0; *cp; cp++)
+                if (*cp == '.')
+                    n++;
+            cp = _res.defdname;
+            for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH;
+                 n--) {
+                cp = index(cp, '.');
+                *pp++ = ++cp;
+            }
+            *pp++ = 0;
+    }
+
+   _res.options |= RES_INIT;
+        return(0);
+}
+
+
+/*
+ res_setopts -- unsupported
+*/
+
+void
+WINAPI
+res_setopts(long opts)
+{
+}
+
+
+
+/*
+	res_getopts -- unsupported
+*/
+
+long
+WINAPI
+res_getopts()
+{
+    return -1;
+}
+
+/* --------------------------------------------------------------------------*/
+/* Excerpt from IPTYPES.H */
+#define MAX_HOSTNAME_LEN                128 // arb.
+#define MAX_DOMAIN_NAME_LEN             128 // arb.
+#define MAX_SCOPE_ID_LEN                256 // arb.
+
+
+
+/*
+
+  @doc MISC
+
+  @func DWORD | WhichOS | This function will attempt to
+  determine which Operating System and subsystem is being used by the
+  application. It should function under Win16, Windows NT amd Windows
+  95 at least.  It does call WSAStartup() and WSACleanup(). This
+  function does have side effects on some global variables.  See the
+  comments below.
+
+  @parm DWORD *| check | a pointer to a DWORD, a value indicating
+  which operating system and/or subsystem is being used will be stored
+  in this parameter upon return.
+
+  @rdesc a NULL will indicate that we could not determine what OS is
+  being used. The high word contains:
+
+
+  @flag MS_OS_WIN     (1) | The application is running under Windows or WFWG
+  @flag	MS_OS_95      (2) | The application is running under Windows 95
+  @flag	MS_OS_NT      (3) | The application is running under Windows NT
+  @flag	MS_OS_2000    (4) | The application is running under Windows 2000
+  @flag	MS_OS_XP      (5) | The application is running under Windows XP
+  @flag	MS_OS_2003    (6) | The application is running under Windows 2003
+  @flag	MS_OS_NT_UNKNOWN (7) | The application is running under Windows NT family beyond 2003
+  @flag	MS_OS_UNKNOWN (0) | It looks like Windows but not any version that
+                            we know of.
+
+  <nl>these are defined in mitwhich.h<nl>
+
+The low word contains one of the following, which is derived from the winsock implementation: <nl>
+
+  @flag MS_NT_32 (1) | The MS 32 bit Winsock stack for NT is being used
+  @flag MS_NT_16 (2) | The MS 16 bit Winsock stack under NT is being used
+  @flag	MS_95_32 (3) | The MS 32 bit Winsock stack under 95 is being used
+  @flag	MS_95_16 (4) | The MS 16 bit Winsock stack under 95 is being used
+  @flag	NOVELL_LWP_16       (5)  | The Novell 16 Winsock stack is being used
+  @flag UNKNOWN_16_UNDER_32 (-2) | We don't know the stack.
+  @flag UNKNOWN_16_UNDER_16 (-3) | We don't know the stack.
+  @flag UNKNOWN_32_UNDER_32 (-4) | We don't know the stack.
+  @flag UNKNOWN_32_UNDER_16 (-5) | We don't know the stack.
+
+*/
+DWORD
+WhichOS(
+    DWORD *check
+    )
+{
+    WORD wVersionRequested;
+    WSADATA wsaData; // should be a global?
+    int err;
+
+    int checkStack = 0;
+    int checkOS = 0;
+    static DWORD dwCheck = 0xFFFFFFFF;
+
+    if ( dwCheck != 0xFFFFFFFF ) {
+        if ( check )
+            *check = dwCheck;
+        return dwCheck;
+    }
+
+    // first get the information from WSAStartup because it may give
+    // more consistent information than Microsoft APIs.
+
+    wVersionRequested = 0x0101;
+
+    err = WSAStartup( wVersionRequested, &wsaData );
+
+    if( err != 0 ){
+        MessageBox( NULL,
+                    "It looks like a useable winsock.dll\n"
+                    "could not be located by the wshelp*.dll\n"
+                    "Please check your system configuration.",
+                    "Problem in wshelper.dll", MB_OK );
+        check = 0;
+        return(0);
+    }
+
+    WSACleanup();
+
+    if( _res.options & RES_DEBUG ){
+        wsprintf( debstr, wsaData.szDescription );
+        OutputDebugString( debstr );
+    }
+
+    if( (0 == checkStack) && (0 == stricmp( wsaData.szDescription, NT_32 ))){
+        // OK we appear to be running under NT in the 32 bit subsystem
+        // so we must be a 32 bit application.
+        // This also implies that we can get the TCPIP parameters out
+        // of the NT registry.
+        checkStack = MS_NT_32;
+    }
+
+    if( (0 == checkStack) && (0 == stricmp( wsaData.szDescription, NT_16 ))){
+        // this implies we're running under NT in the 16 bit subsystem
+        // so we must be a 16 bit application
+        // This means we have to go through some strange gyrations to read the
+        // TCPIP parameters out of the NT 32 bit registry.
+        checkStack = MS_NT_16;
+        checkOS = MS_OS_NT;
+    }
+
+    if( (0 == checkStack) && (0 == stricmp( wsaData.szDescription, W95_32 ))){
+	// get the TCPIP parameters out of the Win95 registry
+        checkStack = MS_95_32;
+        checkOS = MS_OS_95; // ??
+    }
+
+    if( (0 == checkStack) && (0 == stricmp( wsaData.szDescription, W95_16 ))){
+        // go through the pain of getting the TCPIP parameters out of the Win95
+        // 32 bit registry
+        checkStack = MS_95_16;
+        checkOS = MS_OS_95;
+    }
+
+    if( (0 == checkStack) && (0 == stricmp( wsaData.szDescription, LWP_16 ))){
+        // get the information out of the %NDIR%\TCP\RESOLV.CFG file
+        checkStack = NOVELL_LWP_16;
+        checkOS = MS_OS_WIN;
+    }
+
+    if( 0 == checkStack ){
+        // at this time we don't easily know how to support this stack
+        checkStack = STACK_UNKNOWN;
+    }
+
+#if !defined(_WIN32)
+    // Note, if this is the 32 bit DLL we can't use the following
+    // functions to determine the OS because they are
+    // obsolete. However, we should be able to use them in the 16 bit
+    // DLL.
+    {
+        DWORD dwVersion = 0;
+        DWORD dwFlags = 0;
+
+        dwFlags = GetWinFlags();
+        if( _res.options & RES_DEBUG ){
+            wsprintf( debstr, "dwFlags = %x ", dwFlags );
+            OutputDebugString( debstr );
+        }
+
+        dwVersion = GetVersion();
+
+        if( _res.options & RES_DEBUG ){
+            wsprintf( debstr, "dwVersion = %8lx ", dwVersion );
+            OutputDebugString( debstr );
+        }
+
+        if( 95 == (DWORD)(HIBYTE(LOWORD(dwVersion))) ){
+            // OK, we're a 16 bit app running on 95?
+            checkOS = MS_OS_95;
+        }
+
+        if( dwFlags & 0x4000 ){
+            // This means that this is a 16 bit application running
+            // under WOW layer on NT.
+
+            // So, we're going to get the TCPIP parameters out of the
+            // 32 bit registry, but we don't know which set of
+            // registry entries yet.
+
+            // Since we see these version numbers and we're under WOW
+            // we must be under NT 4.0 but we don't necessarily know
+            // the stack
+            checkOS = MS_OS_NT;
+        }
+
+
+        if( checkOS == 0 ){
+            // We are a 16 bit application running on a 16 bit operating system
+            checkOS = MS_OS_WIN; // assumption, but we're not under 95 and not under NT, it looks like
+            if( checkStack == STACK_UNKNOWN ){
+                checkStack = UNKNOWN_16_UNDER_16;
+            }
+        }
+    }
+#endif // !_WIN32
+
+#if defined(_WIN32)
+    // This must be a 32 bit application so we are either under NT,
+    // Win95, or WIN32s
+    {
+        OSVERSIONINFO osvi;
+
+        memset( &osvi, 0, sizeof(OSVERSIONINFO));
+        osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+        GetVersionEx( &osvi );
+
+        if( osvi.dwPlatformId == VER_PLATFORM_WIN32s ){
+            if( checkStack == STACK_UNKNOWN ){
+                checkStack = UNKNOWN_16_UNDER_16;
+            }
+            checkOS = MS_OS_WIN;
+            wsprintf( debstr, "Microsoft Win32s %d.%d (Build %d)\n",
+                      osvi.dwMajorVersion,
+                      osvi.dwMinorVersion,
+                      osvi.dwBuildNumber & 0xFFFF );
+        }
+
+        if( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ){
+            if( checkStack == STACK_UNKNOWN ){
+                checkStack = UNKNOWN_32_UNDER_32;
+            }
+            checkOS = MS_OS_95;
+            wsprintf( debstr, "Microsoft Windows 95 %d.%d (Build %d)\n",
+                      osvi.dwMajorVersion,
+                      osvi.dwMinorVersion,
+                      osvi.dwBuildNumber & 0xFFFF );
+        }
+
+        if( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT ){
+            if( checkStack == STACK_UNKNOWN ){
+                checkStack = UNKNOWN_32_UNDER_32;
+            }
+            if ( osvi.dwMajorVersion <= 4 )
+                checkOS = MS_OS_NT;
+            else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
+                checkOS = MS_OS_2000;
+            else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
+                checkOS = MS_OS_XP;
+            else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )
+                checkOS = MS_OS_2003;
+            else
+                checkOS = MS_OS_NT_UNKNOWN;
+            wsprintf( debstr, "Microsoft Windows NT family %d.%d (Build %d)\n",
+                      osvi.dwMajorVersion,
+                      osvi.dwMinorVersion,
+                      osvi.dwBuildNumber & 0xFFFF );
+        }
+
+        if( _res.options & RES_DEBUG ){
+            OutputDebugString( debstr );
+        }
+    }
+
+#endif // _WIN32
+
+    // At this point we should know the OS.
+    // We should also know the subsystem but not always the stack.
+
+    dwCheck = MAKELONG(checkOS, checkStack);
+    if ( check )
+        *check = dwCheck;
+    return( dwCheck );
+}
+
+
+static
+BOOL
+get_nt5_adapter_param(
+    char* param,
+    WORD skip,
+    char* buf,
+    unsigned int   len
+    )
+{
+    static char linkage[BUFSIZ*4];
+    char* p;
+    char* q;
+    HKEY hAdapters;
+
+    char* DEVICE_STR = "\\Device\\";
+    SIZE_T DEVICE_LEN = strlen(DEVICE_STR);
+
+#define TCPIP_PATH_ADAPTERS "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"
+#define TCPIP_PATH_LINKAGE "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage"
+
+    if (!getRegKeyEx(HKEY_LOCAL_MACHINE, TCPIP_PATH_LINKAGE, "Bind", linkage, sizeof(linkage)))
+        return FALSE;
+
+    p = linkage;
+
+    RegOpenKeyEx(HKEY_LOCAL_MACHINE, TCPIP_PATH_ADAPTERS, 0,
+                 KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
+                 &hAdapters);
+
+    while (*p) {
+        q = strstr(p, DEVICE_STR);
+        if (!q) {
+            while (*p) p++;
+            p++;
+            continue;
+        }
+        q += DEVICE_LEN;
+        p = q;
+        while (*p) p++;
+        p++;
+        buf[0] = '\0';
+        if (getRegKeyEx(hAdapters, q, param, buf, len) && !buf[0]) {
+            if (!skip) {
+                RegCloseKey(hAdapters);
+                return TRUE;
+            }
+            else
+                skip--;
+        }
+    }
+    RegCloseKey(hAdapters);
+
+    // Bottom out by looking at default parameters
+    {
+        char Tcpip_path[_MAX_PATH];
+
+        if(!LoadString(this_module(), IDS_TCPIP_PATH_NT,
+                       Tcpip_path, sizeof(Tcpip_path)))
+            strcpy(Tcpip_path, NT_TCP_PATH);
+        return getRegKeyEx(HKEY_LOCAL_MACHINE, Tcpip_path, param, buf, len);
+    }
+    return FALSE;
+}
+
+
+
+static
+BOOL
+_getdomainname(
+    char* name,
+    int size
+    )
+{
+    char buf[BUFSIZ];
+
+    char* dhcp_param = "DhcpDomain";
+    char* param = "Domain";
+    BOOL ok = FALSE;
+    char* rbuf;
+    unsigned int rlen;
+
+    if (!name || (size <= 0))
+        return FALSE;
+
+    rbuf = (size >= sizeof(buf))?name:buf;
+    rlen = (size >= sizeof(buf))?size:sizeof(buf);
+
+
+    ok = get_nt5_adapter_param(dhcp_param, 0, rbuf, rlen);
+    if (!ok || !rbuf[0])
+        ok = get_nt5_adapter_param(param, 0, rbuf, rlen);
+
+    if (ok && rbuf[0]) {
+        if (size < (lstrlen(rbuf) + 1))
+            return FALSE;
+        if (rbuf != name)
+            strncpy(name, rbuf, size);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+	Gets the base part of the hostname
+	defined in wshelper\res_init.c
+
+	\param[in, out]	name pointer to a buffer that receives a null-terminated string containing the computer name
+	\param[in]		size specifies the size of the buffer, in chars (must be large
+                    enough to hold NULL-terminated host name)
+
+	\retval			return 0 ifsuccess,  -1 on error.
+
+*/
+int WINAPI
+wsh_gethostname(char* name, int size)
+{
+    if (name){
+       // Get and display the name of the computer.
+
+        if( GetComputerName(name, &size) )
+        {
+            while (*name && (*name != '.'))
+            {
+                *name = tolower(*name);
+                name++;
+            }
+            if (*name == '.') *name = 0;
+                return 0;
+        }
+    }
+    return -1;
+}
+
+/*
+	Gets the machine's domain name
+
+	\param[in, out]	name pointer to a buffer that receives a null-terminated string containing the domain name
+	\param[in]		size specifies the size of the buffer, in chars (must be large
+                    enough to hold NULL-terminated domain name)
+
+	\retval			return 0 ifsuccess,  -1 on error.
+
+
+*/
+int WINAPI
+wsh_getdomainname(char* name, int size)
+{
+    DNS_STATUS status;
+
+    PDNS_RECORD pDnsRecord;
+    DNS_FREE_TYPE freetype ;
+
+    DWORD length;
+    char hostName[BUFSIZ];
+
+    length = BUFSIZ;
+    freetype =  DnsFreeRecordListDeep;
+
+
+   // Get and display the name of the computer.
+
+   if( GetComputerName(hostName, &length) )
+   {
+
+        status = DnsQuery_A(hostName,                 //pointer to OwnerName
+                        DNS_TYPE_A,                      //Type of the record to be queried
+                        DNS_QUERY_BYPASS_CACHE|DNS_QUERY_NO_LOCAL_NAME,     // Bypasses the resolver cache on the lookup.
+                        NULL,                   //contains DNS server IP address
+                        &pDnsRecord,                //Resource record comprising the response
+                        NULL);                     //reserved for future use
+
+        if (status)
+            return -1;
+        else
+        {
+            char* cp;
+            cp = index(pDnsRecord->pName, '.');
+            if (cp)
+            {
+                cp++;
+                strncpy(name, cp, size);
+                name[size-1] = '\0';
+                DnsRecordListFree(pDnsRecord, freetype);
+                return(0);
+            }
+            DnsRecordListFree(pDnsRecord, freetype);
+
+        }
+   }
+
+    /* try to get local domain from the registry */
+    if (_getdomainname(name, size))
+        return 0;
+    else
+        return -1;
+}
+
+
+
+
+
+
+
+
+// @func int | getRegKeyEx | This function is only used when the library is
+//                           running under a known 32-bit Microsoft Operating
+//                           system
+
+// @parm const HKEY | key | Specifies a a currently open key or any
+//  of the following predefined reserved handle values:
+//	HKEY_CLASSES_ROOT
+//	KEY_CURRENT_USER
+//	HKEY_LOCAL_MACHINE
+//	HKEY_USERS
+//
+// @parm const char * | subkey | Specifies a pointer to a null-terminated
+//  string containing the name of the subkey to open. If this parameter is NULL
+//  or a pointer to an empty string, the function will open a new handle
+//  of the key identified by the key parameter.
+//
+// @parm const char * | value | Specifiea a pointer to a null-terminated
+//  string containing the name of the value to be queried.
+//
+// @parm char * | buf | Specifies a pointer to a buffer that recieves the
+//  key's data. This parameter can be NULL if the data is not required.
+//
+// @parm unsigned int | len | Specifies the size of buffer 'buf'.
+//
+// @rdesc Returns an int  that can mean:
+//
+// FALSE - if the subkey cannot be queried or possibly opened.
+// TRUE  - if the subkey can be queried but it is not of type: REG_EXPAND_SZ
+// If the subkey can be queried, and its type is REG_EXPAND_SZ, and it can
+// be expanded the return value is the number of characters stored in the
+// buf parameter. If the number of characters is greater than the size of the
+// of the destination buffer, the return value should be the size of the
+// buffer required to hold the value.
+
+static
+int const
+getRegKeyEx(
+    const HKEY key,
+    const char *subkey,
+    const char *value,
+    char *buf,
+    unsigned int len
+    )
+{
+    HKEY hkTcpipParameters;
+    LONG err;
+    DWORD type, cb;
+    char *env_buf;
+
+
+    if (RegOpenKey(key, subkey, &hkTcpipParameters) == ERROR_SUCCESS) {
+        cb = len;
+        err = RegQueryValueEx(hkTcpipParameters, value, 0, &type, buf, &cb);
+        RegCloseKey(hkTcpipParameters);
+        if( err == ERROR_SUCCESS ){
+            if( type == REG_EXPAND_SZ ){
+                if( env_buf = malloc( cb ) ){
+                    err = ExpandEnvironmentStrings( strcpy( env_buf, buf ), buf, len );
+                    free( env_buf );
+                    return err;
+                } else {
+                    return FALSE;
+                }
+            }
+            return TRUE; // subkey could be queried but it was not of type REG_EXPAND_SZ
+        } else {
+            return FALSE; // subkey exists but could not be queried
+        }
+    }
+    else
+
+// #endif // WIN32
+
+        return FALSE; // subkey could not be opened
+}
+
+#ifdef __cplusplus
+inline
+#endif
+
+#include "wsh-int.h"
+
+static
+HMODULE
+this_module()
+{
+    static HMODULE hModWSHelp = 0;
+    if (!hModWSHelp)
+    {
+        // Note: these must match the DEF file entries
+#if defined (_WIN32)
+        hModWSHelp = GetModuleHandle("WSHELP32");
+#else
+        hModWSHelp = GetModuleHandle("WSHELPER");
+#endif
+    }
+    return hModWSHelp;
+}
+
+static
+int
+try_registry(
+    HKEY  hBaseKey,
+    const char * name,
+    DWORD * value
+    )
+{
+    HKEY hKey;
+    LONG err;
+    DWORD size;
+
+    err = RegOpenKeyEx(hBaseKey,
+                       "Software\\MIT\\WsHelper",
+                       0,
+                       KEY_QUERY_VALUE,
+                       &hKey);
+    if (err)
+        return 0;
+    size = sizeof(value);
+    err = RegQueryValueEx(hKey, name, 0, 0, value, &size);
+    RegCloseKey(hKey);
+    return !err;
+}
+
+void
+res_init_startup()
+{
+    DWORD debug_on = 0;
+
+
+    if (try_registry(HKEY_CURRENT_USER, "DebugOn", &debug_on) ||
+        try_registry(HKEY_LOCAL_MACHINE, "DebugOn", &debug_on))
+    {
+        if (debug_on)
+            _res.options |= RES_DEBUG;
+    }
+}
+
+void
+res_init_cleanup()
+{
+
+}

Copied: trunk/src/util/wshelper/res_quer.c (from rev 25272, trunk/src/windows/wshelper/res_quer.c)
===================================================================
--- trunk/src/util/wshelper/res_quer.c	                        (rev 0)
+++ trunk/src/util/wshelper/res_quer.c	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,561 @@
+/*
+ *
+ *	@doc RESOLVE
+ *
+ *
+ *	@module res_quer.c | Contains the implementation of res_query,
+ *	res_search, and res_querydomain
+ *
+ * WSHelper DNS/Hesiod Library for WINSOCK
+ *
+ */
+
+/*
+ * Copyright (c) 1988 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_query.c	5.11 (Berkeley) 3/6/91";
+#endif /* LIBC_SCCS and not lint */
+
+#include <windows.h>
+#include <winsock.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <windns.h>
+
+#define MAX_MSG_SIZE 0x8000
+
+#define strcasecmp	stricmp
+
+#ifdef _DEBUG
+#define DEBUG
+#endif
+int
+__hostalias(register const char *name, char* abuf);
+DNS_STATUS do_res_search(const char *name, int qclass, int type, u_char *retanswer, int retanswerlen, int* anslen);
+void __putshort(register u_short, register u_char *);
+void __putlong(register u_long, u_char *);
+int build_rr(char* p, PDNS_RECORD ptr, int qclass);
+int put_qname(char* p, char* qname);
+
+
+
+/*
+	a generic query interface to the DNS name space. The query is performed with the dnsapi and
+	the answer buffer is populated based on the returned RR set.
+
+	\param[in]	name	domain name
+	\param[in]	qclass  class of query(such as DNS_CLASS_INTERNET, DNS_CLASS_CSNET, DNS_CLASS_CHAOS,
+						DNS_CLASS_HESIOD. Defined in windns.h)
+	\param[in]	type	type of query(such as DNS_TYPE_A, DNS_TYPE_NS, DNS_TYPE_MX, DNS_TYPE_SRV. Defined in
+						windns.h)
+	\param[in]	answer  buffer to put answer in
+	\param[in]	anslen	size of the answer buffer. compare the anslen with the return value, if the return
+						value is bigger than anslen, it means the answer buffer doesn't contain the complete
+						response. You will need to call this function again with a bigger answer buffer if
+						you care about the complete response
+
+	\retval		return the size of the response on success, -1 on error
+
+
+ */
+int WINAPI
+res_search(const char *name, int qclass, int type, u_char *answer, int anslen)
+    /* domain name, class and type of query, buffer to put answer, size of answer */
+{
+    char debstr[80];
+    int n = 0;
+    DNS_STATUS status;
+    char queryname[DNS_MAX_NAME_BUFFER_LENGTH ];
+    register const char *cp;
+    int len = 0;
+
+    char** domain;
+
+    status = -1;
+    memset(answer, 0, anslen);
+    memset(queryname, 0, sizeof(queryname));
+
+    if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+        return (-1);
+
+    for (cp = name, n = 0; *cp; cp++)
+        if (*cp == '.')
+            n++;
+
+    if (n == 0 && !__hostalias(name, queryname) && strlen(queryname)>0)
+    {
+	status = do_res_search(queryname, qclass, type, answer, anslen, &len);
+	if (status == 0)
+	    return len;
+    }
+
+    if ((n == 0 && _res.options & RES_DEFNAMES))
+	// (n != 0 && *--cp != '.' && _res.options & RES_DNSRCH))
+    {
+	for (domain = _res.dnsrch; *domain; domain++) {
+	    strcpy(queryname, name);
+	    strcat(queryname, ".");
+	    strcat(queryname, *domain);
+	    status = do_res_search(queryname, qclass, type, answer, anslen, &len);
+	    if (status == 0)
+		return len;
+	}
+    }
+
+
+    strcpy(queryname, name);
+    status = do_res_search(queryname, qclass, type, answer, anslen, &len);
+
+
+    if (status)
+    {
+#ifdef DEBUG
+        if (_res.options & RES_DEBUG)
+        {
+            wsprintf(debstr, "res_query failed\n");
+            OutputDebugString(debstr);
+        }
+#endif
+	return -1;
+    }
+    return len;
+}
+
+int
+put_qname(char* cp, char* qname)
+{
+    char* p;
+    char* temp;
+    INT_PTR n = 0;
+    INT_PTR i = 0;
+    temp = qname;
+    while (p = strchr(temp, '.'))
+    {
+	n = p - temp;
+	if (n == 0)
+	{
+	    temp++;
+	    break;
+	}
+	cp[0] = (int)n;
+	cp++;
+	i++;
+	strncpy(cp, temp, n);
+	temp = p+1;
+	cp =  cp + n;
+	i = i + n;
+    }
+    n = strlen(temp);
+    if (n > 0)
+    {
+	cp[0] = (int)n;
+	cp++;
+	i++;
+	strcpy(cp, temp);
+	cp = cp+n;
+    }
+    cp[0] = 0;
+    i = i+n+1;
+    return (int)i;
+}
+
+DNS_STATUS
+do_res_search(const char *queryname, int qclass, int type, u_char *retanswer, int retanswerlen, int* anslen)
+{
+    PDNS_RECORD pDnsRecord;
+    PDNS_RECORD ptr;
+    DNS_STATUS status;
+    DNS_FREE_TYPE freetype ;
+    HEADER *hp;
+    char *cp;
+    int  n;
+    int i;
+    u_char  answer[MAX_MSG_SIZE];
+    DWORD options = DNS_QUERY_STANDARD;
+    freetype =  DnsFreeRecordListDeep;
+
+    memset(answer, 0, MAX_MSG_SIZE);
+    if (!(_res.options & RES_RECURSE))
+	options = options | DNS_QUERY_NO_RECURSION;
+    if (_res.options & RES_USEVC)
+	options = options | DNS_QUERY_USE_TCP_ONLY;
+    if (_res.options & RES_IGNTC)
+	options = options | DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE;
+
+    status = DnsQuery_A(queryname,                 //pointer to OwnerName
+                        type,         //Type of the record to be queried
+                        options,
+                        NULL,                   //contains DNS server IP address
+                        &pDnsRecord,                //Resource record comprising the response
+                        NULL);                     //reserved for future use
+
+    if (status)
+        return  status;
+
+
+    hp = (HEADER *) answer;
+    cp = answer + sizeof(HEADER);
+
+    // populating the header
+    hp->id = htons(++_res.id); // query id
+    hp->qr = 1;  // 0 for query 1 for response
+    hp->opcode = 0; // standard query
+    hp->aa = 1; // authoritative answer
+    hp->tc = 0; // no truncation
+    hp->rd = (_res.options & RES_RECURSE) != 0; // resursion desired
+    hp->ra = 1;  // recursion available
+    hp->pr = (_res.options & RES_PRIMARY) != 0; // primary server required
+    hp->rcode = NOERROR;
+    hp->qdcount = htons(1); // number of question entries
+    i = put_qname(cp, (char*)queryname);
+    cp = cp + i;
+    __putshort(type, (u_char *)cp);
+    cp += sizeof(u_short);
+    __putshort(qclass, (u_char *)cp);
+    cp += sizeof(u_short);
+
+    // get the answer
+    for (n = 0, ptr = pDnsRecord; ptr; ptr = ptr->pNext)
+    {
+	if ((ptr->Flags).S.Section == DNSREC_ANSWER ||
+	     (type == DNS_TYPE_PTR && (ptr->Flags).S.Section==DNSREC_QUESTION))
+	{
+	    i = build_rr(cp, ptr, qclass);
+	    cp = cp + i;
+	    //strcpy(cp, pDnsRecord->pName);
+	    //cp += strlen(pDnsRecord->pName);
+	    //cp++;
+
+	    n++;
+	}
+    }
+    hp->ancount = htons(n);
+
+    // get the authority
+    for (n = 0, ptr = pDnsRecord; ptr; ptr = ptr->pNext)
+    {
+	if ((ptr->Flags).S.Section == DNSREC_AUTHORITY )
+	{
+	    i = build_rr(cp, ptr, qclass);
+	    cp = cp + i;
+
+	    n++;
+	}
+    }
+    hp->nscount = htons(n);
+
+    // get the additional resource
+    for (n = 0, ptr = pDnsRecord; ptr; ptr = ptr->pNext)
+    {
+	if ((ptr->Flags).S.Section == DNSREC_ADDITIONAL)
+	{
+	    i = build_rr(cp, ptr, qclass);
+	    cp = cp + i;
+
+	    n++;
+	}
+
+    }
+    hp->arcount = htons(n);
+
+    *anslen = (int)(cp - answer);
+    if (*anslen > retanswerlen)
+	memcpy(retanswer, answer, retanswerlen); // partial copy
+    else
+	memcpy(retanswer, answer, *anslen);
+    DnsRecordListFree(pDnsRecord, freetype);
+    return status;
+}
+
+int
+build_rr(char* p, PDNS_RECORD ptr, int qclass)
+{
+    int i = 0;
+    int n = 0;
+    char* cp = p;
+    char* temp = NULL;
+    unsigned int index = 0;
+
+    i = put_qname(cp, ptr->pName);
+    cp = p + i;
+
+    __putshort(ptr->wType, (u_char *)cp);
+    i += sizeof(u_short);
+    cp = p + i;
+    __putshort(qclass, (u_char *)cp);
+    i += sizeof(u_short);
+    cp = p + i;
+    __putlong(ptr->dwTtl, (u_char*)cp);
+    i += sizeof(u_long);
+    cp = p + i;
+    switch (ptr->wType)
+    {
+    case DNS_TYPE_A:
+	__putshort(sizeof(ptr->Data.A), (u_char*)cp); //RDLENGTH
+	i += sizeof(u_short);
+	cp = p + i;
+	memcpy(cp, &(ptr->Data.A), sizeof(ptr->Data.A));
+	i += sizeof(ptr->Data.A);
+	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:
+	temp = cp;     // hold the spot for RD length
+	i += sizeof(u_short);
+	cp = p+i;
+	n = put_qname(cp, ptr->Data.Ptr.pNameHost);
+	i += n;
+	__putshort(n, (u_char*)temp); //set RDLENGTH
+	break;
+    case DNS_TYPE_TEXT:
+    case DNS_TYPE_HINFO:
+    case DNS_TYPE_ISDN:
+    case DNS_TYPE_X25:
+	temp = cp; // hold the spot for RDLENGTH
+	i += sizeof(u_short);
+	cp = p + i;
+	n = 0;
+	for (index = 0; index < ptr->Data.Txt.dwStringCount; index++)
+	{
+	    *cp = (int)(strlen(ptr->Data.Txt.pStringArray[index]));
+	    n += *cp;
+	    n++;
+	    strcpy(++cp, ptr->Data.Txt.pStringArray[index]);
+	}
+	i += n;
+	__putshort(n,(u_char*)temp); // set RDLENGTH
+	break;
+    case DNS_TYPE_SRV:
+	temp = cp; // hold the spot for RDLENGTH
+	i += sizeof(u_short);
+	cp = p + i;
+	// priority
+	__putshort(ptr->Data.Srv.wPriority, (u_char*)cp);
+	i += sizeof(u_short);
+	cp = p + i;
+	//weight
+	__putshort(ptr->Data.Srv.wWeight, (u_char*)cp);
+	i += sizeof(u_short);
+	cp = p + i;
+	//port
+	__putshort(ptr->Data.Srv.wPort, (u_char*)cp);
+	i += sizeof(u_short);
+	cp = p + i;
+
+	n = put_qname(cp, ptr->Data.Srv.pNameTarget);
+	i+=n;
+	__putshort((u_short)(n + sizeof(u_short)*3),(u_char*)temp);
+
+	break;
+    case DNS_TYPE_MX:
+    case DNS_TYPE_AFSDB:
+    case DNS_TYPE_RT:
+	temp = cp; // hold the spot for RDLENGTH
+	i += sizeof(u_short);
+	cp = p + i;
+	__putshort(ptr->Data.Mx.wPreference, (u_char*)cp); // put wPreference
+	i += sizeof(u_short);
+	cp = p + i;
+	n = put_qname(cp, ptr->Data.Mx.pNameExchange);
+	i+=n;
+	__putshort((u_short)(n+sizeof(u_short)),(u_char*)temp);
+	break;
+	case DNS_TYPE_SOA:
+	temp = cp; // hold the spot for RDLENGTH
+	i += sizeof(u_short);
+	cp = p + i;
+	// primary server name
+	n = put_qname(cp, ptr->Data.Soa.pNamePrimaryServer);
+	i+= n;
+	cp = p + i;
+	//the person responsible for this zone.
+	n += put_qname(cp, ptr->Data.Soa.pNameAdministrator);
+	i += n;
+	cp = p + i;
+	//SERIAL
+	__putlong(ptr->Data.Soa.dwSerialNo, cp);
+	n += sizeof(u_long);
+	i += sizeof(u_long);
+	cp = p + i;
+	//refresh
+	__putlong(ptr->Data.Soa.dwRefresh, cp);
+	n += sizeof(u_long);
+	i += sizeof(u_long);
+	cp = p + i;
+	//retry
+	__putlong(ptr->Data.Soa.dwRetry, cp);
+	n += sizeof(u_long);
+	i += sizeof(u_long);
+	cp = p + i;
+	// expire
+	__putlong(ptr->Data.Soa.dwExpire, cp);
+	n += sizeof(u_long);
+	i += sizeof(u_long);
+	cp = p + i;
+	// minimum TTL
+	__putlong(ptr->Data.Soa.dwDefaultTtl, cp);
+	n += sizeof(u_long);
+	i += sizeof(u_long);
+	// set RDLength
+	__putshort(n,(u_char*)temp);
+	break;
+	case DNS_TYPE_NULL:
+	__putshort((short)ptr->Data.Null.dwByteCount, (u_char*)cp); //RDLENGTH
+	i += sizeof(u_short);
+	cp = p + i;
+	memcpy(cp, ptr->Data.Null.Data, ptr->Data.Null.dwByteCount);
+	i += ptr->Data.Null.dwByteCount;
+	break;
+	case DNS_TYPE_WKS:   // needs more work
+	temp = cp; // hold the spot for RDLENGTH
+	i += sizeof(u_short);
+	cp = p + i;
+	// address
+	memcpy(cp, &(ptr->Data.Wks.IpAddress), sizeof(ptr->Data.Wks.IpAddress));
+	n = sizeof(ptr->Data.Wks.IpAddress);
+	i += sizeof(ptr->Data.Wks.IpAddress);
+	cp = p + i;
+	// protocol
+	*cp = ptr->Data.Wks.chProtocol;
+	i++;
+	n++;
+	cp = p + i;
+	//bit mask
+	memcpy(cp, &(ptr->Data.Wks.BitMask), sizeof(ptr->Data.Wks.BitMask));
+	n+=sizeof(ptr->Data.Wks.BitMask);
+	i += n;
+	// set RDLength
+	__putshort(n,(u_char*)temp);
+	break;
+	case DNS_TYPE_MINFO:
+	case DNS_TYPE_RP:
+	temp = cp; // hold the spot for RDLENGTH
+	i += sizeof(u_short);
+	cp = p + i;
+	// pNameMailbox
+	n = put_qname(cp, ptr->Data.Minfo.pNameMailbox);
+	i+= n;
+	cp = p + i;
+	// pNameErrorsMailbox;
+	n += put_qname(cp, ptr->Data.Minfo.pNameMailbox);
+	i += n;
+	// set RDLength
+	__putshort(n,(u_char*)temp);
+    break;
+	case DNS_TYPE_AAAA:
+	__putshort(sizeof(ptr->Data.AAAA), (u_char*)cp); //RDLENGTH
+	i += sizeof(u_short);
+	cp = p + i;
+	memcpy(cp, &(ptr->Data.AAAA), sizeof(ptr->Data.AAAA));
+	i += sizeof(ptr->Data.AAAA);
+
+    break;
+    }
+    return i;
+}
+
+
+int
+__hostalias(register const char *name, char* abuf)
+{
+    register char *C1, *C2;
+    FILE *fp;
+    char *file;
+//  char *getenv(), *strcpy(), *strncpy();  // pbh XXX 11/1/96
+    char buf[BUFSIZ];
+
+
+    file = getenv("HOSTALIASES");
+    if (file == NULL || (fp = fopen(file, "r")) == NULL)
+        return -1;
+    buf[sizeof(buf) - 1] = '\0';
+    while (fgets(buf, sizeof(buf), fp)) {
+        for (C1 = buf; *C1 && !isspace(*C1); ++C1);
+        if (!*C1)
+            break;
+        *C1 = '\0';
+        if (!strcasecmp(buf, name)) {
+            while (isspace(*++C1));
+            if (!*C1)
+                break;
+            for (C2 = C1 + 1; *C2 && !isspace(*C2); ++C2);
+            abuf[sizeof(abuf) - 1] = *C2 = '\0';
+            (void)strncpy(abuf, C1, sizeof(abuf) - 1);
+            fclose(fp);
+            return 0;
+        }
+    }
+    fclose(fp);
+    return -1;
+}
+
+int  WINAPI
+res_mkquery(int op, const char  *dname,
+	    int qclass, int type,
+	    const char  *data, int datalen,
+	    const struct rrec  *newrr,
+	    char  *buf, int buflen)
+{
+    return -1;
+}
+
+int  WINAPI
+res_querydomain(const char  *name,
+		const char  *domain,
+		int qclass, int type,
+		u_char  *answer, int anslen)
+{
+    return -1;
+}
+
+int  WINAPI
+res_send(const char  *msg, int msglen,
+	 char  *answer, int anslen)
+{
+	return -1;
+}
+
+int  WINAPI
+res_query(char *name, int qclass, int type, u_char *answer, int anslen)
+{
+    return -1;
+}

Copied: trunk/src/util/wshelper/resource.h (from rev 25272, trunk/src/windows/wshelper/resource.h)
===================================================================
--- trunk/src/util/wshelper/resource.h	                        (rev 0)
+++ trunk/src/util/wshelper/resource.h	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,29 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDS_DEF_HES_RHS                 1
+#define IDS_DEF_HES_LHS                 2
+#define IDS_DEF_HES_CONFIG_FILE         3
+#define IDS_DEF_RESCONF_PATH            4
+#define IDS_DEF_DNS1                    5
+#define IDS_DEF_DNS2                    6
+#define IDS_DEF_DNS3                    7
+#define IDS_TCPIP_PATH_NT               8
+#define IDS_TCPIP_PATH_95               9
+#define IDS_NT_DOMAIN_KEY               10
+#define IDS_NT_NS_KEY                   11
+#define IDS_W95_DOMAIN_KEY              12
+#define IDS_W95_NS_KEY                  13
+#define IDS_TCPIP_PATH_NT_TRANSIENT     14
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        101
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1000
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif

Copied: trunk/src/util/wshelper/resource.rc (from rev 25272, trunk/src/windows/wshelper/resource.rc)
===================================================================
--- trunk/src/util/wshelper/resource.rc	                        (rev 0)
+++ trunk/src/util/wshelper/resource.rc	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,64 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include <afxres.h>
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+    "#include <afxres.h>\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+    "#include ""..\\..\\windows\\version.rc""\r\n"
+    "#include ""string.rc""\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "..\..\windows\version.rc"
+#include "string.rc"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED

Copied: trunk/src/util/wshelper/string.rc (from rev 25272, trunk/src/windows/wshelper/string.rc)
===================================================================
--- trunk/src/util/wshelper/string.rc	                        (rev 0)
+++ trunk/src/util/wshelper/string.rc	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,29 @@
+#ifdef APSTUDIO_INVOKED
+#error this file is not editable by App Studio
+#endif // APSTUDIO_INVOKED
+
+#include <hesiod.h>
+#include <mitwhich.h>
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+    IDS_DEF_HES_RHS             DEF_RHS
+    IDS_DEF_HES_LHS             DEF_LHS
+    IDS_DEF_HES_CONFIG_FILE     HESIOD_CONF
+    IDS_DEF_RESCONF_PATH        _PATH_RESCONF
+    IDS_DEF_DNS1                DNS1
+    IDS_DEF_DNS2                DNS2
+    IDS_DEF_DNS3	        DNS3
+    IDS_TCPIP_PATH_NT           NT_TCP_PATH
+    IDS_TCPIP_PATH_95           W95_TCP_PATH
+    IDS_NT_DOMAIN_KEY           NT_DOMAIN_KEY
+    IDS_NT_NS_KEY               NT_NS_KEY
+    IDS_W95_DOMAIN_KEY          W95_DOMAIN_KEY
+    IDS_W95_NS_KEY              W95_NS_KEY
+    IDS_TCPIP_PATH_NT_TRANSIENT NT_TCP_PATH_TRANS
+END

Copied: trunk/src/util/wshelper/ver.rc.inc (from rev 25272, trunk/src/windows/wshelper/ver.rc.inc)
===================================================================
--- trunk/src/util/wshelper/ver.rc.inc	                        (rev 0)
+++ trunk/src/util/wshelper/ver.rc.inc	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,57 @@
+#ifdef RC_INVOKED
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION    VER_FILEVERSION
+PRODUCTVERSION VER_PRODUCTVERSION
+FILEFLAGSMASK  VER_FILEFLAGSMASK
+FILEFLAGS      VER_FILEFLAGS
+FILEOS         VER_FILEOS
+FILETYPE       VER_FILETYPE
+FILESUBTYPE    VER_FILESUBTYPE
+BEGIN
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x0409, 0x04B0
+    END
+
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904B0"   /* LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP */
+        BEGIN
+#if defined(VER_EXTRA_LABEL) && defined(VER_EXTRA_VALUE)
+            VALUE VER_EXTRA_LABEL,   VER_EXTRA_VALUE
+#endif
+#ifdef VER_COMMENT
+            VALUE "Comment",         VER_COMMENT
+#endif
+#ifdef VER_USERNAME
+            VALUE "Built By",        VER_USERNAME
+#endif
+#ifdef VER_HOSTNAME
+            VALUE "Build Host",      VER_HOSTNAME
+#endif
+#ifdef VER_DATE
+            VALUE "Build Time",      VER_DATE
+#endif
+#ifdef VER_VENDOR
+            VALUE "Modified by Vendor",  VER_VENDOR
+#endif
+            VALUE "CompanyName",     VER_COMPANYNAME_STR
+            VALUE "FileDescription", VER_FILEDESCRIPTION_STR EXPORT_TAG
+            VALUE "FileVersion",     VER_FILEVERSION_STR
+            VALUE "InternalName",    VER_INTERNALNAME_STR
+            VALUE "LegalCopyright",  VER_LEGALCOPYRIGHT_STR
+#ifdef VER_LEGALTRADEMARK_STR
+            VALUE "LegalTrademark",  VER_LEGALTRADEMARK_STR
+#endif
+            VALUE "OriginalFilename",VER_ORIGINALFILENAME_STR
+            VALUE "ProductName",     VER_PRODUCTNAME_STR
+            VALUE "ProductVersion",  VER_PRODUCTVERSION_STR
+#ifdef VER_SPECIALBUILD
+            VALUE "SpecialBuild",    VER_SPECIALBUILD
+#endif
+        END
+    END
+END
+
+#endif

Copied: trunk/src/util/wshelper/wsh-int.h (from rev 25272, trunk/src/windows/wshelper/wsh-int.h)
===================================================================
--- trunk/src/util/wshelper/wsh-int.h	                        (rev 0)
+++ trunk/src/util/wshelper/wsh-int.h	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,5 @@
+void res_init_startup();
+void res_init_cleanup();
+
+void __putshort(register u_short s, register u_char *msgp);
+void __putlong(register u_long l, register u_char *msgp);

Copied: trunk/src/util/wshelper/wshelp32.def (from rev 25272, trunk/src/windows/wshelper/wshelp32.def)
===================================================================
--- trunk/src/util/wshelper/wshelp32.def	                        (rev 0)
+++ trunk/src/util/wshelper/wshelp32.def	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,33 @@
+LIBRARY 	WSHELP32
+
+HEAPSIZE        1024
+EXPORTS
+;		WEP                     @1 RESIDENTNAME
+		res_init                @2
+		res_query               @3
+		res_search              @4
+		res_querydomain         @5
+		res_mkquery             @6
+		res_send                @7
+		dn_comp                 @8
+		rdn_expand              @9
+		rgethostbyname          @10
+		rgethostbyaddr          @11
+		hes_to_bind             @12
+		hes_resolve             @13
+		hes_error               @14
+		hes_getmailhost         @15
+		hes_getservbyname       @16
+		hes_getpwnam            @17
+		res_getopts             @18
+		res_setopts             @19
+		inet_aton               @20
+		gethinfobyname          @21
+		getmxbyname             @22
+		getrecordbyname         @23
+		rrhost                  @24
+		rgetservbyname          @25
+		hes_getpwuid            @26
+		wsh_gethostname
+		wsh_getdomainname
+		hes_free

Copied: trunk/src/util/wshelper/wshelp64.def (from rev 25272, trunk/src/windows/wshelper/wshelp64.def)
===================================================================
--- trunk/src/util/wshelper/wshelp64.def	                        (rev 0)
+++ trunk/src/util/wshelper/wshelp64.def	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,33 @@
+LIBRARY 	WSHELP64
+
+HEAPSIZE        1024
+EXPORTS
+;		WEP                     @1 RESIDENTNAME
+		res_init                @2
+		res_query               @3
+		res_search              @4
+		res_querydomain         @5
+		res_mkquery             @6
+		res_send                @7
+		dn_comp                 @8
+		rdn_expand              @9
+		rgethostbyname          @10
+		rgethostbyaddr          @11
+		hes_to_bind             @12
+		hes_resolve             @13
+		hes_error               @14
+		hes_getmailhost         @15
+		hes_getservbyname       @16
+		hes_getpwnam            @17
+		res_getopts             @18
+		res_setopts             @19
+		inet_aton               @20
+		gethinfobyname          @21
+		getmxbyname             @22
+		getrecordbyname         @23
+		rrhost                  @24
+		rgetservbyname          @25
+		hes_getpwuid            @26
+		wsh_gethostname
+		wsh_getdomainname
+		hes_free

Copied: trunk/src/util/wshelper/wshelper.def (from rev 25272, trunk/src/windows/wshelper/wshelper.def)
===================================================================
--- trunk/src/util/wshelper/wshelper.def	                        (rev 0)
+++ trunk/src/util/wshelper/wshelper.def	2011-09-28 20:57:53 UTC (rev 25273)
@@ -0,0 +1,42 @@
+LIBRARY         WSHELPER
+
+DESCRIPTION     'WINSOCK DNS/Hesiod Resolver Library'
+EXETYPE         WINDOWS
+CODE            LOADONCALL MOVEABLE DISCARDABLE
+DATA            LOADONCALL PRELOAD FIXED SINGLE
+HEAPSIZE        1024
+SEGMENTS        _TEXT PRELOAD FIXED
+EXPORTS
+		WEP                     @1 RESIDENTNAME
+		res_init                @2
+		res_query               @3
+		res_search              @4
+		res_querydomain         @5
+		res_mkquery             @6
+		res_send                @7
+		dn_comp                 @8
+		rdn_expand              @9
+		rgethostbyname          @10
+		rgethostbyaddr          @11
+		hes_to_bind             @12
+		hes_resolve             @13
+		hes_error               @14
+		hes_getmailhost         @15
+		hes_getservbyname       @16
+		hes_getpwnam            @17
+		res_getopts             @18
+		res_setopts             @19
+		inet_aton               @20
+		gethinfobyname          @21
+		getmxbyname             @22
+		getrecordbyname         @23
+		rrhost                  @24
+		rgetservbyname          @25
+		hes_getpwuid            @26
+
+
+IMPORTS
+		kernel.LoadLibraryEx32W
+		kernel.FreeLibrary32W
+		kernel._CallProcEx32W
+		kernel.GetProcAddress32W

Modified: trunk/src/windows/Makefile.in
===================================================================
--- trunk/src/windows/Makefile.in	2011-09-28 20:57:15 UTC (rev 25272)
+++ trunk/src/windows/Makefile.in	2011-09-28 20:57:53 UTC (rev 25273)
@@ -1,3 +1,3 @@
 BUILDTOP=..
 NO_OUTPRE=1
-SUBDIRS= wshelper lib leashdll cns gss gina ms2mit kfwlogon
+SUBDIRS= lib leashdll cns gss gina ms2mit kfwlogon




More information about the cvs-krb5 mailing list