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 +#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 , + * 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 + +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