Index: configure.in
===================================================================
RCS file: /cvsroot/squid/squid/configure.in,v
retrieving revision 1.20
diff -u -p -r1.20 configure.in
--- configure.in	2001/04/14 00:31:40	1.20
+++ configure.in	2001/04/30 11:34:41
@@ -27,18 +27,23 @@ if test "$libexecdir" = '${exec_prefix}/
 fi
 
 dnl use .exe suffix for executables on cygwin32 platform
+dnl this should be expanded to a list of platform sensible support requirements.
+dnl (adding an option like --enable-cygwin-support doesn't make sense :]) - R Collins 2001
 case "$host_os" in
 cygwin|cygwin32|os2)
 	exec_suffix=".exe"
 	cgi_suffix=".exe"
+	WIN32_OBJS="win32.o"
 	;;
 *)
 	exec_suffix=""
 	cgi_suffix=".cgi"
+	WIN32_OBJS=""
 	;;
 esac
 AC_SUBST(exec_suffix)
 AC_SUBST(cgi_suffix)
+AC_SUBST(WIN32_OBJS)
 
 if test -z "$CACHE_HTTP_PORT"; then
 	CACHE_HTTP_PORT="3128"
Index: src/Makefile.in
===================================================================
RCS file: /cvsroot/squid/squid/src/Makefile.in,v
retrieving revision 1.9
diff -u -p -r1.9 Makefile.in
--- src/Makefile.in	2001/04/14 00:31:01	1.9
+++ src/Makefile.in	2001/04/30 11:34:41
@@ -187,6 +187,7 @@ OBJS	 	= \
 		wais.o \
 		wccp.o \
 		whois.o \
+		@WIN32_OBJS@ \
 		$(XTRA_OBJS)
 
 SNMP_OBJS	= \
Index: src/defines.h
===================================================================
RCS file: /cvsroot/squid/squid/src/defines.h,v
retrieving revision 1.11
diff -u -p -r1.11 defines.h
--- src/defines.h	2001/04/20 20:13:52	1.11
+++ src/defines.h	2001/04/30 11:34:42
@@ -292,3 +292,14 @@
 #ifndef O_BINARY
 #define O_BINARY 0
 #endif
+
+/* CygWin & Windows NT Port */
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+#define _WIN_OS_UNKNOWN	0
+#define _WIN_OS_WIN32S	1
+#define _WIN_OS_WIN95	2
+#define _WIN_OS_WIN98	3
+#define _WIN_OS_WINNT	4
+#define _WIN_OS_WIN2K	5
+#define _WIN_OS_STRING_SZ 80
+#endif
Index: src/dns_internal.c
===================================================================
RCS file: /cvsroot/squid/squid/src/dns_internal.c,v
retrieving revision 1.8
diff -u -p -r1.8 dns_internal.c
--- src/dns_internal.c	2001/02/15 06:12:46	1.8
+++ src/dns_internal.c	2001/04/30 11:34:45
@@ -35,6 +35,9 @@
 
 #include "squid.h"
 
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+#include <windows.h>
+#endif
 #ifndef _PATH_RESOLV_CONF
 #define _PATH_RESOLV_CONF "/etc/resolv.conf"
 #endif
@@ -50,7 +53,8 @@ static int RcodeMatrix[MAX_RCODE][MAX_AT
 typedef struct _idns_query idns_query;
 typedef struct _ns ns;
 
-struct _idns_query {
+struct _idns_query
+{
     char buf[512];
     size_t sz;
     unsigned short id;
@@ -63,7 +67,8 @@ struct _idns_query {
     int attempt;
 };
 
-struct _ns {
+struct _ns
+{
     struct sockaddr_in S;
     int nqueries;
     int nreplies;
@@ -81,6 +86,9 @@ static void idnsAddNameserver(const char
 static void idnsFreeNameservers(void);
 static void idnsParseNameservers(void);
 static void idnsParseResolvConf(void);
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+static void idnsParseWIN32Registry(void);
+#endif
 static void idnsSendQuery(idns_query * q);
 static int idnsFromKnownNameserver(struct sockaddr_in *from);
 static idns_query *idnsFindQuery(unsigned short id);
@@ -171,6 +179,148 @@ idnsParseResolvConf(void)
     fclose(fp);
 }
 
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+static void
+idnsParseWIN32Registry(void)
+{
+    char *t;
+    char *token;
+    HKEY hndKey, hndKey2;
+
+    idnsFreeNameservers();
+    switch (WIN32_OS_version) {
+    case _WIN_OS_WINNT:
+	/* get nameservers from the Windows NT registry */
+	if (RegOpenKey(HKEY_LOCAL_MACHINE,
+		"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+		&hndKey) == ERROR_SUCCESS) {
+	    DWORD Type = 0;
+	    DWORD Size = 0;
+	    LONG Result;
+	    Result =
+		RegQueryValueEx(hndKey, "DhcpNameServer", NULL, &Type, NULL,
+		&Size);
+	    if (Result == ERROR_SUCCESS && Size) {
+		t = (unsigned char *) xmalloc(Size);
+		RegQueryValueEx(hndKey, "DhcpNameServer", NULL, &Type, t,
+		    &Size);
+		token = strtok((char *) t, ", ");
+		while (token) {
+		    idnsAddNameserver(token);
+		    debug(78, 1) ("Adding DHCP nameserver %s from Registry\n",
+			token);
+		    token = strtok(NULL, ", ");
+		}
+	    }
+	    Result =
+		RegQueryValueEx(hndKey, "NameServer", NULL, &Type, NULL, &Size);
+	    if (Result == ERROR_SUCCESS && Size) {
+		t = (unsigned char *) xmalloc(Size);
+		RegQueryValueEx(hndKey, "NameServer", NULL, &Type, t, &Size);
+		token = strtok((char *) t, ", ");
+		while (token) {
+		    debug(78, 1) ("Adding nameserver %s from Registry\n",
+			token);
+		    idnsAddNameserver(token);
+		    token = strtok(NULL, ", ");
+		}
+	    }
+	    RegCloseKey(hndKey);
+	}
+	break;
+    case _WIN_OS_WIN2K:
+	/* get nameservers from the Windows 2000 registry */
+	/* search all interfaces for DNS server addresses */
+	if (RegOpenKey(HKEY_LOCAL_MACHINE,
+		"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces",
+		&hndKey) == ERROR_SUCCESS) {
+	    int i;
+	    char keyname[255];
+
+	    for (i = 0; i < 10; i++) {
+		if (RegEnumKey(hndKey, i, (char *) &keyname,
+			255) == ERROR_SUCCESS) {
+		    char newkeyname[255];
+		    strcpy(newkeyname,
+			"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\");
+		    strcat(newkeyname, keyname);
+		    if (RegOpenKey(HKEY_LOCAL_MACHINE, newkeyname,
+			    &hndKey2) == ERROR_SUCCESS) {
+			DWORD Type = 0;
+			DWORD Size = 0;
+			LONG Result;
+			Result =
+			    RegQueryValueEx(hndKey2, "DhcpNameServer", NULL,
+			    &Type, NULL, &Size);
+			if (Result == ERROR_SUCCESS && Size) {
+			    t = (unsigned char *) xmalloc(Size);
+			    RegQueryValueEx(hndKey2, "DhcpNameServer", NULL,
+				&Type, t, &Size);
+			    token = strtok((char *) t, ", ");
+			    while (token) {
+				debug(78, 1)
+				    ("Adding DHCP nameserver %s from Registry\n",
+				    token);
+				idnsAddNameserver(token);
+				token = strtok(NULL, ", ");
+			    }
+			}
+			Result =
+			    RegQueryValueEx(hndKey2, "NameServer", NULL, &Type,
+			    NULL, &Size);
+			if (Result == ERROR_SUCCESS && Size) {
+			    t = (unsigned char *) xmalloc(Size);
+			    RegQueryValueEx(hndKey2, "NameServer", NULL, &Type,
+				t, &Size);
+			    token = strtok((char *) t, ", ");
+			    while (token) {
+				debug(78,
+				    1) ("Adding nameserver %s from Registry\n",
+				    token);
+				idnsAddNameserver(token);
+				token = strtok(NULL, ", ");
+			    }
+			}
+			RegCloseKey(hndKey2);
+		    }
+		}
+	    }
+	    RegCloseKey(hndKey);
+	}
+	break;
+    case _WIN_OS_WIN95:
+    case _WIN_OS_WIN98:
+	/* get nameservers from the Windows 9X registry */
+	if (RegOpenKey(HKEY_LOCAL_MACHINE,
+		"SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP",
+		&hndKey) == ERROR_SUCCESS) {
+	    DWORD Type = 0;
+	    DWORD Size = 0;
+	    LONG Result;
+	    Result =
+		RegQueryValueEx(hndKey, "NameServer", NULL, &Type, NULL, &Size);
+	    if (Result == ERROR_SUCCESS && Size) {
+		t = (unsigned char *) xmalloc(Size);
+		RegQueryValueEx(hndKey, "NameServer", NULL, &Type, t, &Size);
+		token = strtok((char *) t, ", ");
+		while (token) {
+		    debug(78, 1) ("Adding nameserver %s from Registry\n",
+			token);
+		    idnsAddNameserver(token);
+		    token = strtok(NULL, ", ");
+		}
+	    }
+	    RegCloseKey(hndKey);
+	}
+	break;
+    default:
+	debug(78, 1)
+	    ("Failed to read nameserver from Registry: Unknown System Type.\n");
+	return;
+    }
+}
+#endif
+
 static void
 idnsStats(StoreEntry * sentry)
 {
@@ -196,8 +346,7 @@ idnsStats(StoreEntry * sentry)
     for (i = 0; i < nns; i++) {
 	storeAppendPrintf(sentry, "%-15s %9d %9d\n",
 	    inet_ntoa(nameservers[i].S.sin_addr),
-	    nameservers[i].nqueries,
-	    nameservers[i].nreplies);
+	    nameservers[i].nqueries, nameservers[i].nreplies);
     }
     storeAppendPrintf(sentry, "\nRcode Matrix:\n");
     storeAppendPrintf(sentry, "RCODE");
@@ -239,10 +388,7 @@ idnsSendQuery(idns_query * q)
   try_again:
     ns = q->nsends % nns;
     x = comm_udp_sendto(DnsSocket,
-	&nameservers[ns].S,
-	sizeof(nameservers[ns].S),
-	q->buf,
-	q->sz);
+	&nameservers[ns].S, sizeof(nameservers[ns].S), q->buf, q->sz);
     q->nsends++;
     q->sent_t = current_time;
     if (x < 0) {
@@ -294,10 +440,7 @@ idnsGrokReply(const char *buf, size_t sz
     rfc1035_rr *answers = NULL;
     unsigned short rid = 0xFFFF;
     idns_query *q;
-    n = rfc1035AnswersUnpack(buf,
-	sz,
-	&answers,
-	&rid);
+    n = rfc1035AnswersUnpack(buf, sz, &answers, &rid);
     debug(78, 3) ("idnsGrokReply: ID %#hx, %d answers\n", rid, n);
     if (rid == 0xFFFF) {
 	debug(78, 1) ("idnsGrokReply: Unknown error\n");
@@ -370,9 +513,7 @@ idnsRead(int fd, void *data)
 	assert(N);
 	(*N)++;
 	debug(78, 3) ("idnsRead: FD %d: received %d bytes from %s.\n",
-	    fd,
-	    len,
-	    inet_ntoa(from.sin_addr));
+	    fd, len, inet_ntoa(from.sin_addr));
 	ns = idnsFromKnownNameserver(&from);
 	if (ns >= 0) {
 	    nameservers[ns].nreplies++;
@@ -420,19 +561,18 @@ idnsCheckQueue(void *unused)
 	    /* name servers went away; reconfiguring or shutting down */
 	    break;
 	q = n->data;
-	if (tvSubDsec(q->sent_t, current_time) < Config.Timeout.idns_retransmit * (1 << q->nsends % nns))
+	if (tvSubDsec(q->sent_t, current_time) <
+	    Config.Timeout.idns_retransmit * (1 << q->nsends % nns))
 	    break;
-	debug(78, 3) ("idnsCheckQueue: ID %#04x timeout\n",
-	    q->id);
+	debug(78, 3) ("idnsCheckQueue: ID %#04x timeout\n", q->id);
 	p = n->prev;
 	dlinkDelete(&q->lru, &lru_list);
 	if (tvSubDsec(q->start_t, current_time) < Config.Timeout.idns_query) {
 	    idnsSendQuery(q);
 	} else {
 	    int v = cbdataValid(q->callback_data);
-	    debug(78, 1) ("idnsCheckQueue: ID %x: giving up after %d tries and %5.1f seconds\n",
-		(int) q->id, q->nsends,
-		tvSubDsec(q->start_t, current_time));
+	    debug(78, 1) ("idnsCheckQueue: ID %x: giving up after %d tries and %5.1f seconds\n", 
+		(int) q->id, q->nsends, tvSubDsec(q->start_t, current_time));
 	    cbdataUnlock(q->callback_data);
 	    if (v)
 		q->callback(q->callback_data, NULL, 0);
@@ -465,28 +605,32 @@ idnsInit(void)
     static int init = 0;
     if (DnsSocket < 0) {
 	DnsSocket = comm_open(SOCK_DGRAM,
-	    0,
-	    Config.Addrs.udp_outgoing,
-	    0,
-	    COMM_NONBLOCKING,
-	    "DNS Socket");
+	    0, Config.Addrs.udp_outgoing, 0, COMM_NONBLOCKING, "DNS Socket");
 	if (DnsSocket < 0)
 	    fatal("Could not create a DNS socket");
 	debug(78, 1) ("DNS Socket created on FD %d\n", DnsSocket);
     }
     assert(0 == nns);
     idnsParseNameservers();
+#ifndef _SQUID_MSWIN_
     if (0 == nns)
 	idnsParseResolvConf();
+#endif
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
     if (0 == nns)
+	idnsParseWIN32Registry();
+#endif
+    if (0 == nns)
 	fatal("Could not find any nameservers.\n"
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+	    "       Please check your TCP-IP settings or /etc/resolv.conf file\n"
+#else
 	    "       Please check your /etc/resolv.conf file\n"
+#endif
 	    "       or use the 'dns_nameservers' option in squid.conf.");
     if (!init) {
 	memDataInit(MEM_IDNS_QUERY, "idns_query", sizeof(idns_query), 0);
-	cachemgrRegister("idns",
-	    "Internal DNS Statistics",
-	    idnsStats, 0, 1);
+	cachemgrRegister("idns", "Internal DNS Statistics", idnsStats, 0, 1);
 	memset(RcodeMatrix, '\0', sizeof(RcodeMatrix));
 	init++;
     }
@@ -555,20 +699,17 @@ snmp_netIdnsFn(variable_list * Var, snin
 	for (i = 0; i < nns; i++)
 	    n += nameservers[i].nqueries;
 	Answer = snmp_var_new_integer(Var->name, Var->name_length,
-	    n,
-	    SMI_COUNTER32);
+	    n, SMI_COUNTER32);
 	break;
     case DNS_REP:
 	for (i = 0; i < nns; i++)
 	    n += nameservers[i].nreplies;
 	Answer = snmp_var_new_integer(Var->name, Var->name_length,
-	    n,
-	    SMI_COUNTER32);
+	    n, SMI_COUNTER32);
 	break;
     case DNS_SERVERS:
 	Answer = snmp_var_new_integer(Var->name, Var->name_length,
-	    0,
-	    SMI_COUNTER32);
+	    0, SMI_COUNTER32);
 	break;
     default:
 	*ErrP = SNMP_ERR_NOSUCHNAME;
Index: src/globals.h
===================================================================
RCS file: /cvsroot/squid/squid/src/globals.h,v
retrieving revision 1.8
diff -u -p -r1.8 globals.h
--- src/globals.h	2001/04/20 20:13:52	1.8
+++ src/globals.h	2001/04/30 11:34:45
@@ -153,3 +153,7 @@ extern int store_pages_max;	/* 0 */
 extern ssize_t store_maxobjsize;	/* -1 */
 extern RemovalPolicy *mem_policy;
 extern hash_table *proxy_auth_username_cache;	/* NULL */
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+extern unsigned int WIN32_OS_version;	/* 0 */
+extern char WIN32_OS_string[_WIN_OS_STRING_SZ];
+#endif
Index: src/main.c
===================================================================
RCS file: /cvsroot/squid/squid/src/main.c,v
retrieving revision 1.21
diff -u -p -r1.21 main.c
--- src/main.c	2001/04/14 00:31:02	1.21
+++ src/main.c	2001/04/30 11:34:48
@@ -568,11 +568,19 @@ main(int argc, char **argv)
     int n;			/* # of GC'd objects */
     time_t loop_delay;
     mode_t oldmask;
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+    int WIN32_init_err;
+#endif
 
     debug_log = stderr;
     if (FD_SETSIZE < Squid_MaxFD)
 	Squid_MaxFD = FD_SETSIZE;
 
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+    if (WIN32_init_err = WIN32_Subsystem_Init())
+	return WIN32_init_err;
+#endif
+
     /* call mallopt() before anything else */
 #if HAVE_MALLOPT
 #ifdef M_GRAIN
@@ -993,5 +1001,9 @@ SquidShutdown(void *unused)
 	version_string);
     if (debug_log)
 	fclose(debug_log);
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+    WIN32_Exit(0);
+#else
     exit(0);
+#endif
 }
Index: src/protos.h
===================================================================
RCS file: /cvsroot/squid/squid/src/protos.h,v
retrieving revision 1.24
diff -u -p -r1.24 protos.h
--- src/protos.h	2001/04/14 00:31:02	1.24
+++ src/protos.h	2001/04/30 11:34:52
@@ -1303,3 +1303,10 @@ extern StatCounters *snmpStatGet(int);
 
 /* Vary support functions */
 int varyEvaluateMatch(StoreEntry * entry, request_t * req);
+
+/* CygWin & Windows NT Port */ 
+/* win32.c */ 
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+extern int WIN32_Subsystem_Init();
+extern void WIN32_Exit(int);
+#endif
Index: src/win32.c
===================================================================
RCS file: win32.c
diff -N win32.c
--- /dev/null	Mon Dec 11 17:26:27 2000
+++ win32.c	Mon Apr 30 04:34:52 2001
@@ -0,0 +1,92 @@
+/*
+ * $Id$
+ *
+ * * * * * * * * Legal stuff * * * * * * *
+ *
+ * (C) 2001 Guido Serassio <serassio@libero.it>,
+ *   inspired by previous work by Romeo Anghelache & Eric Stern.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *  
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#include "squid.h"
+
+/* This code compiles only CygWin & Windows NT Port */
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+#include <windows.h>
+
+static unsigned int GetOSVersion();
+void WIN32_svcstatusupdate(DWORD);
+
+/* ====================================================================== */
+/* LOCAL FUNCTIONS */
+/* ====================================================================== */
+
+static unsigned int
+GetOSVersion()
+{
+    OSVERSIONINFO osvi;
+
+    memset(&osvi, '\0', sizeof(OSVERSIONINFO));
+    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+    GetVersionEx((OSVERSIONINFO *) & osvi);
+    switch (osvi.dwPlatformId) {
+    case VER_PLATFORM_WIN32_NT:
+	if (osvi.dwMajorVersion <= 4) {
+	    strcpy(WIN32_OS_string, "Windows NT");
+	    return _WIN_OS_WINNT;
+	}
+	if (osvi.dwMajorVersion == 5) {
+	    strcpy(WIN32_OS_string, "Windows 2000");
+	    return _WIN_OS_WIN2K;
+	}
+	break;
+    case VER_PLATFORM_WIN32_WINDOWS:
+	if ((osvi.dwMajorVersion > 4) ||
+	    ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion > 0))) {
+	    strcpy(WIN32_OS_string, "Windows 98");
+	    return _WIN_OS_WIN98;
+	}
+	strcpy(WIN32_OS_string, "Windows 95");
+	return _WIN_OS_WIN95;
+	break;
+    case VER_PLATFORM_WIN32s:
+	strcpy(WIN32_OS_string, "Windows 3.1 with WIN32S");
+	return _WIN_OS_WIN32S;
+	break;
+    default:
+	return _WIN_OS_UNKNOWN;
+    }
+    strcpy(WIN32_OS_string, "Unknown");
+    return _WIN_OS_UNKNOWN;
+}
+
+/* ====================================================================== */
+/* PUBLIC FUNCTIONS */
+/* ====================================================================== */
+
+VOID
+WIN32_Exit(int ExitStatus)
+{
+    exit(0);
+}
+
+int
+WIN32_Subsystem_Init()
+{
+    WIN32_OS_version = GetOSVersion();
+    return 0;
+}
+#endif