---------------------
PatchSet 3715 
Date: 2002/02/27 19:44:03
Author: serassio
Branch: cygwin-svc-2_5
Tag: (none) 
Log:
Imported cygwin-svc source code

Members: 
	acconfig.h:1.13->1.13.4.1 
	acinclude.m4:1.1->1.1.60.1 
	configure.in:1.42.2.5->1.42.2.5.2.1 
	include/config.h:1.5->1.5.14.1 
	lib/rfc1123.c:1.6->1.6.10.1 
	src/acl.c:1.43.2.1->1.43.2.1.2.1 
	src/cache_cf.c:1.38.6.2->1.38.6.2.2.1 
	src/cache_diff.c:1.6->1.6.70.1 
	src/cf_gen.c:1.10->1.10.10.1 
	src/client.c:1.8->1.8.10.1 
	src/debug.c:1.9->1.9.6.1 
	src/defines.h:1.15->1.15.8.1 
	src/globals.h:1.14->1.14.10.1 
	src/main.c:1.28.6.1->1.28.6.1.2.1 
	src/mime.c:1.11->1.11.10.1 
	src/protos.h:1.41.6.3->1.41.6.3.2.1 
	src/squid.h:1.13.6.2->1.13.6.2.2.1 
	src/tools.c:1.19->1.19.10.1 
	src/win32.c:1.5->1.5.10.1 
	src/auth/basic/helpers/Makefile.am:1.2->1.2.36.1 
	src/auth/basic/helpers/win32_locallogon/Makefile.am:1.1->1.1.18.1 
	src/auth/basic/helpers/win32_locallogon/NT_auth.c:1.1->1.1.34.1 
	src/auth/basic/helpers/win32_locallogon/README.txt:1.1->1.1.34.1 
	src/auth/basic/helpers/win32_locallogon/valid.c:1.1->1.1.34.1 
	src/auth/basic/helpers/win32_locallogon/valid.h:1.1->1.1.34.1 
	src/fs/aufs/store_dir_aufs.c:1.23.6.1->1.23.6.1.2.1 
	src/fs/ufs/store_dir_ufs.c:1.21.6.1->1.21.6.1.2.1 

Index: squid/acconfig.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/Attic/acconfig.h,v
retrieving revision 1.13
retrieving revision 1.13.4.1
diff -u -r1.13 -r1.13.4.1
--- squid/acconfig.h	28 Nov 2001 23:30:02 -0000	1.13
+++ squid/acconfig.h	27 Feb 2002 19:44:03 -0000	1.13.4.1
@@ -23,7 +23,7 @@
 #ifndef __CONFIGURE_H__
 #define __CONFIGURE_H__
 @TOP@
-/* $Id: acconfig.h,v 1.13 2001/11/28 23:30:02 squidadm Exp $ */
+/* $Id: acconfig.h,v 1.13.4.1 2002/02/27 19:44:03 serassio Exp $ */
 
 /*
  * configure command line used to configure Squid
@@ -151,6 +151,11 @@
 /* Define if NTLM is allowed to fail gracefully when a helper has problems */
 #undef NTLM_FAIL_OPEN
 
+/*
+ * Define Windows NT & Windows 2000 run service mode
+ */
+#undef USE_WIN32_SERVICE
+
 /********************************
  *  END OF CONFIGURABLE OPTIONS *
  ********************************/
--- /dev/null	Wed Feb 14 00:55:47 2007
+++ squid/acinclude.m4	Wed Feb 14 00:57:21 2007
@@ -0,0 +1,119 @@
+dnl COMPILER WIN32 support ====================================
+# figure out how to run CC with access to the win32 api if present
+# configure that as the CC program, 
+# WIN32 may be present with WINE, under cygwin, or under mingw,
+# or cross compilers targeting those same three targets.
+# as it happens, I can only test cygwin, so extra input here will be appreciated
+# send bug reports to Robert Collins <rbtcollins@hotmail.com>
+#
+# logic: is CC already configured? if not, call AC_PROG_CC.
+# if so - try it. If that doesn't work ,try -mwin32. If that doesn't work, fail
+#
+# 2001-03-15 - Changed from yes/no to true/false -suggested by Lars J Aas<larsa@sim.no>
+# 	* Change true to : - suggest by Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+#	* changed layout on the basis of autoconf mailing list:
+#		there are now two interfaces, a language specific one which sets
+#		or clears WIN32 && WIN32FLAGS as appropriate
+#	* m4 Syntax fixup: Akim Demaille <akim@epita.fr>
+#
+# All faults& bugs are mine - Robert
+
+AC_DEFUN([AC_PROG_CC_WIN32], [
+dnl AC_REQUIRE([AC_PROG_CC])dnl
+AC_MSG_CHECKING([how to access the Win32 API])
+WIN32FLAGS=
+AC_TRY_COMPILE(,[
+#ifndef WIN32
+# ifndef _WIN32
+#  error WIN32 or _WIN32 not defined
+# endif
+#endif], [
+dnl found windows.h with the current config.
+AC_MSG_RESULT([present by default])
+], [
+dnl try -mwin32
+ac_compile_save="$ac_compile"
+dnl we change CC so config.log looks correct
+save_CC="$CC"
+ac_compile="$ac_compile -mwin32"
+CC="$CC -mwin32"
+AC_TRY_COMPILE(,[
+#ifndef WIN32
+# ifndef _WIN32
+#  error WIN32 or _WIN32 not defined
+# endif
+#endif], [
+dnl found windows.h using -mwin32
+AC_MSG_RESULT([found via -mwin32])
+ac_compile="$ac_compile_save"
+CC="$save_CC"
+WIN32FLAGS="-mwin32"
+], [
+ac_compile="$ac_compile_save"
+CC="$save_CC"
+AC_MSG_RESULT([not found])
+])
+])
+
+])
+
+
+# figure out how to run CXX with access to the win32 api if present
+# configure that as the CXX program,
+# WIN32 may be present with WINE, under cygwin, or under mingw,
+# or cross compilers targeting those same three targets.
+# as it happens, I can only test cygwin, so extra input here will be appreciated
+# send bug reports to Robert Collins <rbtcollins@hotmail.com>
+
+AC_DEFUN([AC_PROG_CXX_WIN32], [
+dnl AC_REQUIRE([AC_PROG_CXX])dnl
+AC_MSG_CHECKING([how to access the Win32 API])
+WIN32FLAGS=
+AC_TRY_COMPILE(,[
+#ifndef WIN32
+# ifndef _WIN32
+#  error WIN32 or _WIN32 not defined
+# endif
+#endif], [
+dnl found windows.h with the current config.
+AC_MSG_RESULT([present by default])
+], [
+dnl try -mwin32
+ac_compile_save="$ac_compile"
+dnl we change CC so config.log looks correct
+save_CXX="$CXX"
+ac_compile="$ac_compile -mwin32"
+CXX="$CXX -mwin32"
+AC_TRY_COMPILE(,[
+#ifndef WIN32
+# ifndef _WIN32
+#  error WIN32 or _WIN32 not defined
+# endif
+#endif], [
+dnl found windows.h using -mwin32
+AC_MSG_RESULT([found via -mwin32])
+ac_compile="$ac_compile_save"
+CXX="$save_CXX"
+WIN32FLAGS="-mwin32"
+], [
+ac_compile="$ac_compile_save"
+CXX="$save_CXX"
+AC_MSG_RESULT([not found])
+])
+])
+
+])
+
+
+# high level interface for finding out compiler support for win32.
+AC_DEFUN([AC_API_WIN32], [
+
+AC_LANG_CASE(
+	    [C],	AC_PROG_CC_WIN32 [CFLAGS="$WIN32FLAGS $CFLAGS"
+	CPPFLAGS="$WIN32FLAGS $CPPFLAGS"],
+            [C++],	AC_PROG_CXX_WIN32 [CXXFLAGS="$WIN32FLAGS $CXXFLAGS"
+	CPPFLAGS="$WIN32FLAGS $CPPFLAGS"],
+             [AC_FATAL([No macro support for WIN32 with ] _AC_LANG) ])
+])
+
+dnl end compiler WIN32 support ===========================================
Index: squid/configure.in
===================================================================
RCS file: /cvsroot/squid-sf//squid/configure.in,v
retrieving revision 1.42.2.5
retrieving revision 1.42.2.5.2.1
diff -u -r1.42.2.5 -r1.42.2.5.2.1
--- squid/configure.in	14 Feb 2002 01:17:00 -0000	1.42.2.5
+++ squid/configure.in	27 Feb 2002 19:44:04 -0000	1.42.2.5.2.1
@@ -3,7 +3,7 @@
 dnl
 dnl  Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9)
 dnl
-dnl  $Id: configure.in,v 1.42.2.5 2002/02/14 01:17:00 squidadm Exp $
+dnl  $Id: configure.in,v 1.42.2.5.2.1 2002/02/27 19:44:04 serassio Exp $
 dnl
 dnl
 dnl
@@ -11,7 +11,7 @@
 AC_CONFIG_AUX_DIR(cfgaux)
 AM_INIT_AUTOMAKE(squid, 2.5.PRE4-CVS)
 AM_CONFIG_HEADER(include/autoconf.h)
-AC_REVISION($Revision: 1.42.2.5 $)dnl
+AC_REVISION($Revision: 1.42.2.5.2.1 $)dnl
 AC_PREFIX_DEFAULT(/usr/local/squid)
 AM_MAINTAINER_MODE
 
@@ -66,6 +66,8 @@
 
 AC_DEFINE_UNQUOTED(CONFIG_HOST_TYPE, "$host")
 
+dnl Can the CC program be asked to use the Win32 API?
+AC_API_WIN32
 AC_DEFINE_UNQUOTED(SQUID_CONFIGURE_OPTIONS, "$ac_configure_args")
 
 dnl Gerben Wierda <Gerben_Wierda@RnA.nl>
@@ -789,6 +791,15 @@
   fi
 ])
 
+dnl Enable WIN32 Service compile mode
+AC_ARG_ENABLE(win32-service,
+[  --enable-win32-service  Compile Squid as a WIN32 Service
+                          Works only on Windows NT and Windows 2000 Platforms.],
+[ if test "$enableval" = "yes" ; then
+    echo "Enabling WIN32 run service mode"
+    AC_DEFINE(USE_WIN32_SERVICE)
+  fi
+])
 
 dnl Select auth schemes modules to build
 AC_ARG_ENABLE(auth,
@@ -2089,6 +2100,7 @@
 	src/auth/basic/helpers/NCSA/Makefile \
 	src/auth/basic/helpers/PAM/Makefile \
 	src/auth/basic/helpers/SMB/Makefile \
+	src/auth/basic/helpers/win32_locallogon/Makefile \
 	src/auth/basic/helpers/YP/Makefile \
 	src/auth/basic/helpers/getpwnam/Makefile \
 	src/auth/basic/helpers/multi-domain-NTLM/Makefile \
Index: squid/include/config.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/include/config.h,v
retrieving revision 1.5
retrieving revision 1.5.14.1
diff -u -r1.5 -r1.5.14.1
--- squid/include/config.h	13 Nov 2001 22:19:32 -0000	1.5
+++ squid/include/config.h	27 Feb 2002 19:44:04 -0000	1.5.14.1
@@ -105,7 +105,7 @@
 #define _SQUID_CYGWIN_
 
 #elif defined(WIN32) || defined(WINNT) || defined(__WIN32__) || defined(__WIN32)
-#define _SQUID_MSWIN_
+#define _SQUID_MSWIN_			      /* MS Compilers */
 
 #elif defined(__APPLE__)
 #define _SQUID_APPLE_
Index: squid/lib/rfc1123.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/lib/rfc1123.c,v
retrieving revision 1.6
retrieving revision 1.6.10.1
diff -u -r1.6 -r1.6.10.1
--- squid/lib/rfc1123.c	18 Oct 2001 20:52:10 -0000	1.6
+++ squid/lib/rfc1123.c	27 Feb 2002 19:44:04 -0000	1.6.10.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: rfc1123.c,v 1.6 2001/10/18 20:52:10 squidadm Exp $
+ * $Id: rfc1123.c,v 1.6.10.1 2002/02/27 19:44:04 serassio Exp $
  *
  * DEBUG: 
  * AUTHOR: Harvest Derived
@@ -260,6 +260,7 @@
 #elif defined (_timezone)
 #elif defined(_SQUID_AIX_)
 #elif defined(_SQUID_CYGWIN_)
+#elif defined(_SQUID_MSWIN_)
 #else
 	extern time_t timezone;
 #endif
@@ -269,7 +270,7 @@
 	 */
 	if (tm->tm_isdst > 0)
 	    dst = -3600;
-#if defined ( _timezone) || defined(_SQUID_CYGWIN_)
+#if defined ( _timezone) || defined(_SQUID_CYGWIN_) || defined(_SQUID_MSWIN_)
 	t -= (_timezone + dst);
 #else
 	t -= (timezone + dst);
Index: squid/src/acl.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/acl.c,v
retrieving revision 1.43.2.1
retrieving revision 1.43.2.1.2.1
diff -u -r1.43.2.1 -r1.43.2.1.2.1
--- squid/src/acl.c	13 Jan 2002 03:23:53 -0000	1.43.2.1
+++ squid/src/acl.c	27 Feb 2002 19:44:04 -0000	1.43.2.1.2.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: acl.c,v 1.43.2.1 2002/01/13 03:23:53 squidadm Exp $
+ * $Id: acl.c,v 1.43.2.1.2.1 2002/02/27 19:44:04 serassio Exp $
  *
  * DEBUG: section 28    Access Control
  * AUTHOR: Duane Wessels
@@ -124,7 +124,7 @@
 		debug(28, 0) ("strtokFile: %s not found\n", fn);
 		return (NULL);
 	    }
-#if defined(_SQUID_CYGWIN_)
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
 	    setmode(fileno(aclFile), O_TEXT);
 #endif
 	    aclFromFile = 1;
Index: squid/src/cache_cf.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/cache_cf.c,v
retrieving revision 1.38.6.2
retrieving revision 1.38.6.2.2.1
diff -u -r1.38.6.2 -r1.38.6.2.2.1
--- squid/src/cache_cf.c	13 Jan 2002 03:23:53 -0000	1.38.6.2
+++ squid/src/cache_cf.c	27 Feb 2002 19:44:04 -0000	1.38.6.2.2.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: cache_cf.c,v 1.38.6.2 2002/01/13 03:23:53 squidadm Exp $
+ * $Id: cache_cf.c,v 1.38.6.2.2.1 2002/02/27 19:44:04 serassio Exp $
  *
  * DEBUG: section 3     Configuration File Parsing
  * AUTHOR: Harvest Derived
@@ -242,7 +242,7 @@
     if ((fp = fopen(file_name, "r")) == NULL)
 	fatalf("Unable to open configuration file: %s: %s",
 	    file_name, xstrerror());
-#if defined(_SQUID_CYGWIN_)
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
     setmode(fileno(fp), O_TEXT);
 #endif
     cfg_filename = file_name;
Index: squid/src/cache_diff.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/cache_diff.c,v
retrieving revision 1.6
retrieving revision 1.6.70.1
diff -u -r1.6 -r1.6.70.1
--- squid/src/cache_diff.c	12 Jan 2001 08:20:32 -0000	1.6
+++ squid/src/cache_diff.c	27 Feb 2002 19:44:05 -0000	1.6.70.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: cache_diff.c,v 1.6 2001/01/12 08:20:32 hno Exp $
+ * $Id: cache_diff.c,v 1.6.70.1 2002/02/27 19:44:05 serassio Exp $
  *
  * AUTHOR: Alex Rousskov
  *
@@ -137,7 +137,7 @@
 	fprintf(stderr, "cannot open %s: %s\n", fname, strerror(errno));
 	return 0;
     }
-#if defined(_SQUID_CYGWIN_)
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
     setmode(fileno(file), O_BINARY);
 #endif
     scanned_count = cacheIndexScan(idx, fname, file);
Index: squid/src/cf_gen.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/cf_gen.c,v
retrieving revision 1.10
retrieving revision 1.10.10.1
diff -u -r1.10 -r1.10.10.1
--- squid/src/cf_gen.c	18 Oct 2001 20:52:11 -0000	1.10
+++ squid/src/cf_gen.c	27 Feb 2002 19:44:05 -0000	1.10.10.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: cf_gen.c,v 1.10 2001/10/18 20:52:11 squidadm Exp $
+ * $Id: cf_gen.c,v 1.10.10.1 2002/02/27 19:44:05 serassio Exp $
  *
  * DEBUG: none          Generate squid.conf.default and cf_parser.h
  * AUTHOR: Max Okumoto
@@ -66,7 +66,7 @@
 #if HAVE_ASSERT_H
 #include <assert.h>
 #endif
-#if defined(_SQUID_CYGWIN_)
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
 #include <io.h>
 #endif
 #if HAVE_FCNTL_H
@@ -152,7 +152,7 @@
 	perror(input_filename);
 	exit(1);
     }
-#if defined(_SQUID_CYGWIN_)
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
     setmode(fileno(fp), O_TEXT);
 #endif
     state = sSTART;
@@ -333,7 +333,7 @@
 	perror(output_filename);
 	exit(1);
     }
-#if defined(_SQUID_CYGWIN_)
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
     setmode(fileno(fp), O_TEXT);
 #endif
     fprintf(fp,
@@ -358,7 +358,7 @@
 	perror(conf_filename);
 	exit(1);
     }
-#if defined(_SQUID_CYGWIN_)
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
     setmode(fileno(fp), O_TEXT);
 #endif
     gen_conf(entries, fp);
Index: squid/src/client.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/Attic/client.c,v
retrieving revision 1.8
retrieving revision 1.8.10.1
diff -u -r1.8 -r1.8.10.1
--- squid/src/client.c	18 Oct 2001 20:52:11 -0000	1.8
+++ squid/src/client.c	27 Feb 2002 19:44:05 -0000	1.8.10.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client.c,v 1.8 2001/10/18 20:52:11 squidadm Exp $
+ * $Id: client.c,v 1.8.10.1 2002/02/27 19:44:05 serassio Exp $
  *
  * DEBUG: section 0     WWW Client
  * AUTHOR: Harvest Derived
@@ -200,7 +200,7 @@
 		xstrerror());
 	    exit(-1);
 	}
-#if defined(_SQUID_CYGWIN_)
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
 	setmode(put_fd, O_BINARY);
 #endif
 	fstat(put_fd, &sb);
Index: squid/src/debug.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/debug.c,v
retrieving revision 1.9
retrieving revision 1.9.6.1
diff -u -r1.9 -r1.9.6.1
--- squid/src/debug.c	18 Dec 2001 13:38:47 -0000	1.9
+++ squid/src/debug.c	27 Feb 2002 19:44:05 -0000	1.9.6.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: debug.c,v 1.9 2001/12/18 13:38:47 squidadm Exp $
+ * $Id: debug.c,v 1.9.6.1 2002/02/27 19:44:05 serassio Exp $
  *
  * DEBUG: section 0     Debug Routines
  * AUTHOR: Harvest Derived
@@ -67,7 +67,7 @@
     /* give a chance to context-based debugging to print current context */
     if (!Ctx_Lock)
 	ctx_print();
-#if STDC_HEADERS
+#if STDC_HEADERS    
     va_start(args1, format);
     va_start(args2, format);
     va_start(args3, format);
@@ -177,7 +177,7 @@
 	fflush(stderr);
 	debug_log = stderr;
     }
-#if defined(_SQUID_CYGWIN_)
+#if defined(_SQUID_CYGWIN_)||defined(_SQUID_MSWIN_)
     setmode(fileno(debug_log), O_TEXT);
 #endif
 }
@@ -237,6 +237,14 @@
 	snprintf(to, MAXPATHLEN, "%s.%d", debug_log_file, i);
 	rename(from, to);
     }
+/*
+ * You can't rename open files on Microsoft "operating systems"
+ * so we close before renaming.
+ */ 
+#ifdef _SQUID_MSWIN_
+    if (debug_log != stderr)
+	fclose(debug_log);
+#endif
     /* Rotate the current log to .0 */
     if (Config.Log.rotateNumber > 0) {
 	snprintf(to, MAXPATHLEN, "%s.%d", debug_log_file, 0);
Index: squid/src/defines.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/defines.h,v
retrieving revision 1.15
retrieving revision 1.15.8.1
diff -u -r1.15 -r1.15.8.1
--- squid/src/defines.h	18 Nov 2001 01:15:42 -0000	1.15
+++ squid/src/defines.h	27 Feb 2002 19:44:05 -0000	1.15.8.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: defines.h,v 1.15 2001/11/18 01:15:42 squidadm Exp $
+ * $Id: defines.h,v 1.15.8.1 2002/02/27 19:44:05 serassio Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -296,4 +296,21 @@
 #define O_BINARY 0
 #endif
 
+/* CygWin & Windows NT Port */
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+#define _WIN_HOSTS_FILENAME "\\hosts"
+#define _WIN95_NETWORK_DB_HOSTS "%WINDIR%"
+#define _WIN_SQUID_SERVICE_CONTROL_STOP SERVICE_CONTROL_STOP
+#define _WIN_SQUID_SERVICE_CONTROL_SHUTDOWN SERVICE_CONTROL_SHUTDOWN
+#define _WIN_SQUID_SERVICE_CONTROL_INTERROGATE SERVICE_CONTROL_INTERROGATE
+#define _WIN_SQUID_SERVICE_CONTROL_ROTATE	128
+#define _WIN_SQUID_SERVICE_CONTROL_RECONFIGURE	129
+#define _WIN_SQUID_SERVICE_CONTROL_DEBUG	130
+#define _WIN_SQUID_SERVICE_CONTROL_INTERRUPT 	131
+#define _WIN_SQUID_DEFAULT_SERVICE_NAME		"SquidNT"
+#define _WIN_SQUID_SERVICE_OPTION		"--ntservice"
+#define _WIN_SQUID_RUN_MODE_INTERACTIVE		0
+#define _WIN_SQUID_RUN_MODE_SERVICE		1
+#endif
+
 #endif /* SQUID_DEFINES_H */
Index: squid/src/globals.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/globals.h,v
retrieving revision 1.14
retrieving revision 1.14.10.1
diff -u -r1.14 -r1.14.10.1
--- squid/src/globals.h	18 Oct 2001 20:52:11 -0000	1.14
+++ squid/src/globals.h	27 Feb 2002 19:44:05 -0000	1.14.10.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: globals.h,v 1.14 2001/10/18 20:52:11 squidadm Exp $
+ * $Id: globals.h,v 1.14.10.1 2002/02/27 19:44:05 serassio Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -159,7 +159,11 @@
 extern int incoming_sockets_accepted;
 #if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
 extern unsigned int WIN32_OS_version;	/* 0 */
-extern char *WIN32_OS_string;
+extern char *WIN32_OS_string;    /* NULL */	
+extern char *WIN32_Service_name; /* NULL */
+extern char *WIN32_Command_Line; /* NULL */
+extern char *WIN32_Service_Command_Line; /* NULL */
+extern unsigned int WIN32_run_mode;	/* _WIN_SQUID_RUN_MODE_INTERACTIVE */
 #endif
 
 #endif /* SQUID_GLOBALS_H */
Index: squid/src/main.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/main.c,v
retrieving revision 1.28.6.1
retrieving revision 1.28.6.1.2.1
diff -u -r1.28.6.1 -r1.28.6.1.2.1
--- squid/src/main.c	16 Jan 2002 09:32:28 -0000	1.28.6.1
+++ squid/src/main.c	27 Feb 2002 19:44:05 -0000	1.28.6.1.2.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: main.c,v 1.28.6.1 2002/01/16 09:32:28 squidadm Exp $
+ * $Id: main.c,v 1.28.6.1.2.1 2002/02/27 19:44:05 serassio Exp $
  *
  * DEBUG: section 1     Startup and Main Loop
  * AUTHOR: Harvest Derived
@@ -35,11 +35,26 @@
 
 #include "squid.h"
 
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+#include <windows.h>
+#include <process.h>
+static int opt_install_service = FALSE;
+static int opt_remove_service = FALSE;
+static int opt_signal_service = FALSE;
+static int opt_command_line = FALSE;
+extern void WIN32_svcstatusupdate(DWORD);
+void WINAPI WIN32_svcHandler(DWORD);
+#endif
+
 /* for error reporting from xmalloc and friends */
 extern void (*failure_notify) (const char *);
 
 static int opt_send_signal = -1;
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+static int opt_no_daemon = 1;
+#else
 static int opt_no_daemon = 0;
+#endif
 static int opt_parse_cfg_only = 0;
 static int httpPortNumOverride = 1;
 static int icpPortNumOverride = 1;	/* Want to detect "-u 0" */
@@ -53,8 +68,6 @@
 
 static void mainRotate(void);
 static void mainReconfigure(void);
-static SIGHDLR rotate_logs;
-static SIGHDLR reconfigure;
 #if ALARM_UPDATES_TIME
 static SIGHDLR time_tick;
 #endif
@@ -83,15 +96,27 @@
 usage(void)
 {
     fprintf(stderr,
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+	"Usage: %s [-dhirsvzCDFRVYX] [-f config-file] [-[au] port] [-k signal] [-n name] [-O CommandLine]\n"
+#else
 	"Usage: %s [-dhsvzCDFNRVYX] [-f config-file] [-[au] port] [-k signal]\n"
+#endif
 	"       -a port   Specify HTTP port number (default: %d).\n"
 	"       -d level  Write debugging to stderr also.\n"
 	"       -f file   Use given config-file instead of\n"
 	"                 %s\n"
 	"       -h        Print help message.\n"
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+	"       -i        Installs as a Windows Service (see -n option).\n"
+#endif
 	"       -k reconfigure|rotate|shutdown|interrupt|kill|debug|check|parse\n"
 	"                 Parse configuration file, then send signal to \n"
 	"                 running copy (except -k parse) and exit.\n"
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+	"       -n name   Specify Windows Service name to use for service operations\n"
+	"                 default is: " _WIN_SQUID_DEFAULT_SERVICE_NAME ".\n"
+	"       -r        Removes a Windows Service (see -n option).\n"
+#endif
 	"       -s        Enable logging to syslog.\n"
 	"       -u port   Specify ICP port number (default: %d), disable with 0.\n"
 	"       -v        Print version.\n"
@@ -99,7 +124,12 @@
 	"       -C        Do not catch fatal signals.\n"
 	"       -D        Disable initial DNS tests.\n"
 	"       -F        Don't serve any requests until store is rebuilt.\n"
+#if !(defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)))
 	"       -N        No daemon mode.\n"
+#else
+	"       -O options\n"
+       	"                 Set Windows Service Command line options in Registry.\n"
+#endif
 	"       -R        Do not set REUSEADDR on port.\n"
 	"       -S        Double-check swap during rebuild.\n"
 	"       -V        Virtual host httpd-accelerator.\n"
@@ -115,7 +145,11 @@
     extern char *optarg;
     int c;
 
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+    while ((c = getopt(argc, argv, "CDFO:RSVYXa:d:f:hik:m::n:rsu:vz?")) != -1) {
+#else
     while ((c = getopt(argc, argv, "CDFNRSVYXa:d:f:hk:m::su:vz?")) != -1) {
+#endif
 	switch (c) {
 	case 'C':
 	    opt_catch_signals = 0;
@@ -126,9 +160,16 @@
 	case 'F':
 	    opt_foreground_rebuild = 1;
 	    break;
+#if !(defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)))
 	case 'N':
 	    opt_no_daemon = 1;
 	    break;
+#else
+	case 'O':
+	    opt_command_line = 1;
+	    WIN32_Command_Line = xstrdup(optarg);
+	    break;
+#endif
 	case 'R':
 	    opt_reuseaddr = 0;
 	    break;
@@ -158,6 +199,11 @@
 	case 'h':
 	    usage();
 	    break;
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+	case 'i':
+	    opt_install_service = TRUE;
+	    break;
+#endif
 	case 'k':
 	    if ((int) strlen(optarg) < 1)
 		usage();
@@ -205,6 +251,16 @@
 		fatal("Need to configure --enable-xmalloc-debug-trace to use -m option");
 #endif
 	    }
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+	case 'n':
+	    xfree(WIN32_Service_name);
+	    WIN32_Service_name = xstrdup(optarg);
+	    opt_signal_service = TRUE;
+	    break;
+	case 'r':
+	    opt_remove_service = TRUE;
+	    break;
+#endif
 	case 's':
 	    opt_syslog_enable = 1;
 	    break;
@@ -215,6 +271,9 @@
 	    break;
 	case 'v':
 	    printf("Squid Cache: Version %s\nconfigure options: %s\n", version_string, SQUID_CONFIGURE_OPTIONS);
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+	    printf("Compiled as Windows System Service.\n");
+#endif
 	    exit(0);
 	    /* NOTREACHED */
 	case 'z':
@@ -229,7 +288,7 @@
 }
 
 /* ARGSUSED */
-static void
+void
 rotate_logs(int sig)
 {
     do_rotate = 1;
@@ -252,7 +311,7 @@
 #endif
 
 /* ARGSUSED */
-static void
+void
 reconfigure(int sig)
 {
     do_reconfigure = 1;
@@ -409,9 +468,9 @@
 setEffectiveUser(void)
 {
     leave_suid();		/* Run as non privilegied user */
-#ifdef _SQUID_OS2_
+#if defined(_SQUID_OS2_) || defined(_SQUID_MSWIN_)
     return;
-#endif
+#else
     if (geteuid() == 0) {
 	debug(0, 0) ("Squid is not safe to run as root!  If you must\n");
 	debug(0, 0) ("start Squid as root, then you must configure\n");
@@ -419,6 +478,7 @@
 	debug(0, 0) ("'cache_effective_user' option in the config file.\n");
 	fatal("Don't run Squid as root, set 'cache_effective_user'!");
     }
+#endif
 }
 
 static void
@@ -472,6 +532,14 @@
     debug(1, 0) ("Starting Squid Cache version %s for %s...\n",
 	version_string,
 	CONFIG_HOST_TYPE);
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+    if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
+	debug(1, 0) ("Running as %s Windows System Service on %s\n", WIN32_Service_name, WIN32_OS_string);
+	debug(1, 0) ("Service command line is: %s\n", WIN32_Service_Command_Line);
+    }
+    else
+	debug(1, 0) ("Running on %s\n",WIN32_OS_string);
+#endif
     debug(1, 1) ("Process ID %d\n", (int) getpid());
     debug(1, 1) ("With %d file descriptors available\n", Squid_MaxFD);
 
@@ -563,24 +631,35 @@
     configured_once = 1;
 }
 
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+/* When USE_WIN32_SERVICE is defined, the main function is placed in win32.c */
+void WINAPI
+SquidMain(int argc, char **argv)
+#else
 int
 main(int argc, char **argv)
+#endif
 {
     int errcount = 0;
     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;
+#ifdef USE_WIN32_SERVICE
+    if (WIN32_Subsystem_Init(&argc, &argv))
+	return;
+#else
+    {
+	int WIN32_init_err;	
+	if ((WIN32_init_err = WIN32_Subsystem_Init()))
+	    return WIN32_init_err;
+    }
+#endif
 #endif
 
     /* call mallopt() before anything else */
@@ -621,8 +700,26 @@
     squid_start = current_time;
     failure_notify = fatal_dump;
 
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+    WIN32_svcstatusupdate(SERVICE_START_PENDING);
+#endif
     mainParseOptions(argc, argv);
 
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+    if (opt_install_service) {
+	WIN32_InstallService();
+	return;
+    }
+    if (opt_remove_service) {
+	WIN32_RemoveService();
+	return;
+    }
+    if (opt_command_line) {
+	WIN32_SetServiceCommandLine();
+	return;
+    }
+#endif
+
     /* parse configuration file
      * note: in "normal" case this used to be called from mainInitialize() */
     {
@@ -641,7 +738,11 @@
 	parse_err = parseConfigFile(ConfigFile);
 
 	if (opt_parse_cfg_only)
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+	    return;
+#else
 	    return parse_err;
+#endif
     }
     if (-1 == opt_send_signal)
 	if (checkRunningPid())
@@ -672,7 +773,11 @@
 	setEffectiveUser();
 	debug(0, 0) ("Creating Swap Directories\n");
 	storeCreateSwapDirectories();
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+	return;
+#else
 	return 0;
+#endif
     }
     if (!opt_no_daemon)
 	watch_child(argv);
@@ -692,8 +797,15 @@
 	fd_open(1, FD_LOG, "stdout");
 	fd_open(2, FD_LOG, "stderr");
     }
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+    WIN32_svcstatusupdate(SERVICE_START_PENDING);
+#endif
     mainInitialize();
 
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+    WIN32_svcstatusupdate(SERVICE_RUNNING);
+#endif
+
     /* main loop */
     for (;;) {
 	if (do_reconfigure) {
@@ -711,6 +823,9 @@
 	    do_shutdown = 0;
 	    shutting_down = 1;
 	    serverConnectionsClose();
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+	    WIN32_svcstatusupdate(SERVICE_STOP_PENDING);
+#endif
 #if USE_DNSSERVERS
 	    dnsShutdown();
 #else
@@ -747,7 +862,11 @@
 	}
     }
     /* NOTREACHED */
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+    return;
+#else
     return 0;
+#endif
 }
 
 static void
@@ -757,6 +876,11 @@
     debug_log = stderr;
     pid = readPidFile();
     if (pid > 1) {
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+	if (opt_signal_service)
+	    WIN32_sendSignal(opt_send_signal);
+	else {
+#endif
 	if (kill(pid, opt_send_signal) &&
 	/* ignore permissions if just running check */
 	    !(opt_send_signal == 0 && errno == EPERM)) {
@@ -765,6 +889,9 @@
 		opt_send_signal, (int) pid, xstrerror());
 	    exit(1);
 	}
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+	}
+#endif
     } else {
 	fprintf(stderr, "%s: ERROR: No running copy\n", appname);
 	exit(1);
Index: squid/src/mime.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/mime.c,v
retrieving revision 1.11
retrieving revision 1.11.10.1
diff -u -r1.11 -r1.11.10.1
--- squid/src/mime.c	13 Nov 2001 22:19:33 -0000	1.11
+++ squid/src/mime.c	27 Feb 2002 19:44:05 -0000	1.11.10.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: mime.c,v 1.11 2001/11/13 22:19:33 squidadm Exp $
+ * $Id: mime.c,v 1.11.10.1 2002/02/27 19:44:05 serassio Exp $
  *
  * DEBUG: section 25    MIME Parsing
  * AUTHOR: Harvest Derived
@@ -297,7 +297,7 @@
 	debug(50, 1) ("mimeInit: %s: %s\n", filename, xstrerror());
 	return;
     }
-#if defined (_SQUID_CYGWIN_)
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
     setmode(fileno(fp), O_TEXT);
 #endif
     mimeFreeMemory();
Index: squid/src/protos.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/protos.h,v
retrieving revision 1.41.6.3
retrieving revision 1.41.6.3.2.1
diff -u -r1.41.6.3 -r1.41.6.3.2.1
--- squid/src/protos.h	18 Feb 2002 15:01:19 -0000	1.41.6.3
+++ squid/src/protos.h	27 Feb 2002 19:44:05 -0000	1.41.6.3.2.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: protos.h,v 1.41.6.3 2002/02/18 15:01:19 squidadm Exp $
+ * $Id: protos.h,v 1.41.6.3.2.1 2002/02/27 19:44:05 serassio Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -787,6 +787,8 @@
 
 extern void serverConnectionsClose(void);
 extern void shut_down(int);
+extern void rotate_logs(int);
+extern void reconfigure(int);
 
 
 extern void start_announce(void *unused);
@@ -1324,8 +1326,17 @@
 /* CygWin & Windows NT Port */
 /* win32.c */
 #if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+#ifdef USE_WIN32_SERVICE
+extern int WIN32_Subsystem_Init(int *, char ***);
+#else
 extern int WIN32_Subsystem_Init(void);
+#endif
+extern void WIN32_sendSignal(int);
+extern void WIN32_Abort(int);
 extern void WIN32_Exit(void);
+extern void WIN32_SetServiceCommandLine(void);
+extern void WIN32_InstallService(void);
+extern void WIN32_RemoveService(void);
 #endif
 
 #endif /* SQUID_PROTOS_H */
Index: squid/src/squid.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/squid.h,v
retrieving revision 1.13.6.2
retrieving revision 1.13.6.2.2.1
diff -u -r1.13.6.2 -r1.13.6.2.2.1
--- squid/src/squid.h	8 Jan 2002 05:19:18 -0000	1.13.6.2
+++ squid/src/squid.h	27 Feb 2002 19:44:05 -0000	1.13.6.2.2.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: squid.h,v 1.13.6.2 2002/01/08 05:19:18 squidadm Exp $
+ * $Id: squid.h,v 1.13.6.2.2.1 2002/02/27 19:44:05 serassio Exp $
  *
  * AUTHOR: Duane Wessels
  *
@@ -211,7 +211,7 @@
 #if HAVE_LIMITS_H
 #include <limits.h>
 #endif
-#if defined(_SQUID_CYGWIN_)
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
 #include <io.h>
 #endif
 
Index: squid/src/tools.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/tools.c,v
retrieving revision 1.19
retrieving revision 1.19.10.1
diff -u -r1.19 -r1.19.10.1
--- squid/src/tools.c	18 Nov 2001 01:15:42 -0000	1.19
+++ squid/src/tools.c	27 Feb 2002 19:44:05 -0000	1.19.10.1
@@ -1,6 +1,6 @@
 
 /*
- * $Id: tools.c,v 1.19 2001/11/18 01:15:42 squidadm Exp $
+ * $Id: tools.c,v 1.19.10.1 2002/02/27 19:44:05 serassio Exp $
  *
  * DEBUG: section 21    Misc Functions
  * AUTHOR: Harvest Derived
@@ -924,6 +924,9 @@
 xrename(const char *from, const char *to)
 {
     debug(21, 2) ("xrename: renaming %s to %s\n", from, to);
+#ifdef _SQUID_MSWIN_
+    remove(to);
+#endif
     if (0 == rename(from, to))
 	return 0;
     debug(21, errno == ENOENT ? 2 : 1) ("xrename: Cannot rename %s to %s: %s\n",
@@ -966,9 +969,6 @@
     char buf2[512];
     char *nt = buf;
     char *lt = buf;
-#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
-    char *systemroot = NULL;
-#endif
     if (NULL == Config.etcHostsPath)
 	return;
     if (0 == strcmp(Config.etcHostsPath, "none"))
Index: squid/src/win32.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/win32.c,v
retrieving revision 1.5
retrieving revision 1.5.10.1
diff -u -r1.5 -r1.5.10.1
--- squid/src/win32.c	18 Nov 2001 01:15:42 -0000	1.5
+++ squid/src/win32.c	27 Feb 2002 19:44:05 -0000	1.5.10.1
@@ -22,6 +22,9 @@
  *
  */
 
+#ifndef WIN32_C
+#define WIN32_C
+
 #include "squid.h"
 
 /* This code compiles only CygWin & Windows NT Port */
@@ -29,11 +32,173 @@
 #include <windows.h>
 
 static unsigned int GetOSVersion();
+void WIN32_svcstatusupdate(DWORD);
+void WINAPI WIN32_svcHandler(DWORD);
+static int WIN32_StoreKey(const char *, DWORD, unsigned char *, int);
+static int WIN32_create_key(void);
+static void WIN32_build_argv (char *);
+void WINAPI SquidMain(DWORD, char **);
+
+/* The following code section is part of an EXPERIMENTAL native */
+/* Windows NT/2000 Squid port - Compiles only on MS Visual C++  */
+#if defined(_SQUID_MSWIN_)
+static int Win32SockInit(void);
+static void Win32SockCleanup(void);
+#endif /* End native Windows NT EXPERIMENTAL PORT */
+
+static SERVICE_STATUS svcStatus;
+static SERVICE_STATUS_HANDLE svcHandle;
+static int WIN32_argc;
+static char ** WIN32_argv;
+static char * WIN32_module_name;
+
+#define VENDOR   "GNU"
+#if defined(_SQUID_MSWIN_)
+#define SOFTWARENAME "SquidNT"
+#else
+#define SOFTWARENAME "Squid"
+#endif
+#define WIN32_VERSION  "2.5"
+#define COMMANDLINE "CommandLine"
+#define CONFIGFILE  "ConfigFile"
+#undef ChangeServiceConfig2
+typedef BOOL (WINAPI * PFChangeServiceConfig2) (SC_HANDLE, DWORD, LPVOID);
+#ifdef UNICODE
+#define CHANGESERVICECONFIG2 "ChangeServiceConfig2W"
+#else
+#define CHANGESERVICECONFIG2 "ChangeServiceConfig2A"
+#endif
+static SC_ACTION Squid_SCAction[] = { { SC_ACTION_RESTART, 60000 } };
+static SERVICE_DESCRIPTION Squid_ServiceDescription = { SOFTWARENAME " " VERSION " WWW Proxy Server" };
+static SERVICE_FAILURE_ACTIONS Squid_ServiceFailureActions = { 0, NULL, NULL, 1, Squid_SCAction };
+static char REGKEY[256]="SOFTWARE\\"VENDOR"\\"SOFTWARENAME"\\"WIN32_VERSION"\\";
+static char *keys[] = { 
+    "SOFTWARE",	    /* key[0] */
+    VENDOR,	    /* key[1] */
+    SOFTWARENAME,   /* key[2] */
+    WIN32_VERSION,  /* key[3] */
+    NULL,	    /* key[4] */
+    NULL	    /* key[5] */
+};
 
 /* ====================================================================== */
 /* LOCAL FUNCTIONS */
 /* ====================================================================== */
 
+static int
+WIN32_create_key(void)
+{
+    int index;
+    HKEY hKey;
+    HKEY hKeyNext;
+    int retval;
+    long rv;
+
+    hKey = HKEY_LOCAL_MACHINE;
+    index = 0;
+    retval = 0;
+
+    /* Walk the tree, creating at each stage if necessary */
+    while (keys[index]) {
+	unsigned long result;
+	rv = RegCreateKeyEx(hKey, keys[index],	/* subkey */
+	    0,			/* reserved */
+	    NULL,		/* class */
+	    REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKeyNext, &result);
+	if (rv != ERROR_SUCCESS) {
+	    debug(1, 1) ("RegCreateKeyEx(%s),%d\n", keys[index], (int) rv);
+	    retval = -4;
+	}
+	/* Close the old key */
+	rv = RegCloseKey(hKey);
+	if (rv != ERROR_SUCCESS) {
+	    debug(1, 1) ("RegCloseKey %d\n", (int) rv);
+	    if (retval == 0) {
+		/* Keep error status from RegCreateKeyEx, if any */
+		retval = -4;
+	    }
+	}
+	if (retval) {
+	    break;
+	}
+	hKey = hKeyNext;
+	index++;
+    }
+    if (keys[index] == NULL) {
+	/* Close the final key we opened, if we walked the entire
+	 * tree
+	 */
+	rv = RegCloseKey(hKey);
+	if (rv != ERROR_SUCCESS) {
+	    debug(1, 1) ("RegCloseKey %d\n", (int) rv);
+	    if (retval == 0) {
+		/* Keep error status from RegCreateKeyEx, if any */
+		retval = -4;
+	    }
+	}
+    }
+    return retval;
+}
+
+static int
+WIN32_StoreKey(const char *key, DWORD type, unsigned char *value,
+    int value_size)
+{
+    long rv;
+    HKEY hKey;
+    int retval;
+
+    rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY, 0, KEY_WRITE, &hKey);
+    if (rv == ERROR_FILE_NOT_FOUND) {
+	/* Key could not be opened -- try to create it 
+	 */
+	if (WIN32_create_key() < 0) {
+	    /* Creation failed (error already reported) */
+	    return -4;
+	}
+	/* Now it has been created we should be able to open it
+	 */
+	rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY, 0, KEY_WRITE, &hKey);
+	if (rv == ERROR_FILE_NOT_FOUND) {
+	    debug(1, 1) ("Registry does not contain key %s after creation",
+		REGKEY);
+	    return -1;
+	}
+    }
+    if (rv != ERROR_SUCCESS) {
+	debug(1, 1) ("RegOpenKeyEx HKLM\\%s, %d\n", REGKEY, (int) rv);
+	return -4;
+    }
+    /* Now set the value and data */
+    rv = RegSetValueEx(hKey, key,	/* value key name */
+	0,			/* reserved */
+	type,			/* type */
+	value,			/* value data */
+	(DWORD) value_size);	/* for size of "value" */
+    retval = 0;			/* Return value */
+    if (rv != ERROR_SUCCESS) {
+	debug(1, 1) ("RegQueryValueEx(key %s),%d\n", key, (int) rv);
+	retval = -4;
+    } else {
+	debug(1, 1) ("Registry stored HKLM\\%s\\%s value %s\n",
+	    REGKEY,
+	    key,
+	    type == REG_SZ ? value : (unsigned char *) "(not displayable)");
+    }
+    /* Make sure we close the key even if there was an error storing
+     * the data
+     */
+    rv = RegCloseKey(hKey);
+    if (rv != ERROR_SUCCESS) {
+	debug(1, 1) ("RegCloseKey HKLM\\%s, %d\n", REGKEY, (int) rv);
+	if (retval == 0) {
+	    /* Keep error status from RegQueryValueEx, if any */
+	    retval = -4;
+	}
+    }
+    return retval;
+}
+
 static unsigned int
 GetOSVersion()
 {
@@ -83,24 +248,498 @@
     return _WIN_OS_UNKNOWN;
 }
 
+/* Build argv, argc from string passed from Windows.  */
+static void WIN32_build_argv(char *cmd)
+{
+    int argvlen = 0;
+    char *word;
+
+    WIN32_argc = 1;
+    WIN32_argv = (char **) xmalloc ((WIN32_argc+1) * sizeof (char *));
+    WIN32_argv[0]=xstrdup(WIN32_module_name);    
+/* Scan command line until there is nothing left. */
+    while (*cmd) {
+	/* Ignore spaces */
+	if (xisspace(*cmd)) {
+	    cmd++;
+	    continue;
+	}
+	/* Found the beginning of an argument. */
+	word = cmd;
+	while (*cmd) {
+	    cmd++;		/* Skip over this character */
+	    if (xisspace(*cmd))	/* End of argument if space */
+		break;
+	}
+	if (*cmd)
+	    *cmd++ = '\0';		/* Terminate `word' */
+	/* See if we need to allocate more space for argv */
+	if (WIN32_argc >= argvlen) {
+	    argvlen = WIN32_argc + 1;
+	    WIN32_argv = (char **) xrealloc (WIN32_argv, (1 + argvlen) * sizeof (char *));
+	}
+	/* Add word to argv file. */
+	WIN32_argv[WIN32_argc++] = word;
+    }
+    WIN32_argv[WIN32_argc] = NULL;
+}
+
 /* ====================================================================== */
 /* PUBLIC FUNCTIONS */
 /* ====================================================================== */
 
 void
+WIN32_Abort(int sig)
+{
+#ifdef USE_WIN32_SERVICE
+    svcStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
+    svcStatus.dwServiceSpecificExitCode = 1;
+#endif
+    WIN32_Exit();
+}
+
+void
 WIN32_Exit()
 {
+#ifdef _SQUID_MSWIN_
+    Win32SockCleanup();
+#endif
+#ifdef USE_WIN32_SERVICE
+    svcStatus.dwCurrentState = SERVICE_STOPPED;
+    SetServiceStatus(svcHandle, &svcStatus);
+#endif
     _exit(0);
 }
 
-int
-WIN32_Subsystem_Init()
+#ifdef USE_WIN32_SERVICE
+int WIN32_Subsystem_Init(int * argc, char *** argv)
+#else
+int WIN32_Subsystem_Init()
+#endif
 {
     WIN32_OS_version = GetOSVersion();
     if ((WIN32_OS_version == _WIN_OS_UNKNOWN) || (WIN32_OS_version == _WIN_OS_WIN32S))
 	return 1;
     if (atexit(WIN32_Exit) != 0)
 	return 1;
+#ifdef USE_WIN32_SERVICE
+    if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
+	char path[512];
+	HKEY hndKey;
+	if (signal(SIGABRT, WIN32_Abort) == SIG_ERR)
+	    return 1;
+	/* Register the service Handler function */
+	svcHandle =
+	    RegisterServiceCtrlHandler(WIN32_Service_name,
+	    WIN32_svcHandler);
+	if (svcHandle == 0)
+	    return 1;
+	/* Set Service Staus to SERVICE_START_PENDING */
+	svcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+	svcStatus.dwCurrentState = SERVICE_START_PENDING;
+	svcStatus.dwControlsAccepted =
+	    SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
+	svcStatus.dwWin32ExitCode = 0;
+	svcStatus.dwServiceSpecificExitCode = 0;
+	svcStatus.dwCheckPoint = 0;
+	svcStatus.dwWaitHint = 10000;
+	SetServiceStatus(svcHandle, &svcStatus);
+	/* Set Process work dir to directory cointaining squid.exe */
+	GetModuleFileName(NULL, path, 512);
+	WIN32_module_name=xstrdup(path);
+	path[strlen(path) - 10] = '\0';
+	if (SetCurrentDirectory(path) == 0)
+	    return 1;
+	safe_free(ConfigFile);
+	/* get config file from Windows Registry */
+	if (RegOpenKey(HKEY_LOCAL_MACHINE, REGKEY, &hndKey) == ERROR_SUCCESS) {
+	    DWORD Type = 0;
+	    DWORD Size = 0;
+	    LONG Result;
+	    Result =
+		RegQueryValueEx(hndKey, CONFIGFILE, NULL, &Type, NULL, &Size);
+	    if (Result == ERROR_SUCCESS && Size) {
+		ConfigFile = xmalloc(Size);
+		RegQueryValueEx(hndKey, CONFIGFILE, NULL, &Type, ConfigFile,
+		    &Size);
+	    } else
+		ConfigFile = xstrdup(DefaultConfigFile);
+	    Size = 0;
+	    Type = 0;
+	    Result =
+		RegQueryValueEx(hndKey, COMMANDLINE, NULL, &Type, NULL, &Size);
+	    if (Result == ERROR_SUCCESS && Size) {
+		WIN32_Service_Command_Line = xmalloc(Size);
+		RegQueryValueEx(hndKey, COMMANDLINE, NULL, &Type, WIN32_Service_Command_Line,
+		    &Size);
+	    } else
+		WIN32_Service_Command_Line = xstrdup("");
+	    RegCloseKey(hndKey);
+	} else {
+	    ConfigFile = xstrdup(DefaultConfigFile);
+	    WIN32_Service_Command_Line = xstrdup("");
+	}
+	WIN32_build_argv(WIN32_Service_Command_Line);
+	*argc = WIN32_argc;
+	*argv = WIN32_argv;
+    }
+#endif
+#ifdef _SQUID_MSWIN_
+    Win32SockInit();
+#endif
+    return 0;
+}
+
+#ifdef USE_WIN32_SERVICE
+void
+WIN32_svcstatusupdate(DWORD svcstate)
+{
+    if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
+	svcStatus.dwCheckPoint++;
+	svcStatus.dwCurrentState = svcstate;
+	SetServiceStatus(svcHandle, &svcStatus);
+    }
+}
+
+VOID WINAPI
+WIN32_svcHandler(DWORD Opcode)
+{
+    DWORD status;
+
+    switch (Opcode) {
+    case _WIN_SQUID_SERVICE_CONTROL_STOP:
+    case _WIN_SQUID_SERVICE_CONTROL_SHUTDOWN:
+/* Do whatever it takes to stop here. */
+	svcStatus.dwWin32ExitCode = 0;
+	svcStatus.dwCurrentState = SERVICE_STOP_PENDING;
+	svcStatus.dwCheckPoint = 0;
+	svcStatus.dwWaitHint = 10000;
+	shut_down(SIGTERM);
+	if (!SetServiceStatus(svcHandle, &svcStatus)) {
+	    status = GetLastError();
+	    debug(1, 1) (" SetServiceStatus error  %ld\n", status);
+	}
+	debug(1, 1) ("Leaving Squid service \n");
+	return;
+    case _WIN_SQUID_SERVICE_CONTROL_INTERROGATE:
+/* Fall through to send current status. */
+	if (!SetServiceStatus(svcHandle, &svcStatus)) {
+	    status = GetLastError();
+	    debug(1, 1) (" SetServiceStatus error  %ld\n", status);
+	}
+	break;
+    case _WIN_SQUID_SERVICE_CONTROL_ROTATE:
+	rotate_logs(SIGUSR1);
+	break;
+    case _WIN_SQUID_SERVICE_CONTROL_RECONFIGURE:
+	reconfigure(SIGHUP);
+	break;
+    case _WIN_SQUID_SERVICE_CONTROL_DEBUG:
+	sigusr2_handle(SIGUSR2);
+	break;
+    case _WIN_SQUID_SERVICE_CONTROL_INTERRUPT:
+/* Do whatever it takes to stop here. */
+	svcStatus.dwWin32ExitCode = 0;
+	svcStatus.dwCurrentState = SERVICE_STOP_PENDING;
+	svcStatus.dwCheckPoint = 0;
+	svcStatus.dwWaitHint = 10000;
+	shut_down(SIGINT);
+	if (!SetServiceStatus(svcHandle, &svcStatus)) {
+	    status = GetLastError();
+	    debug(1, 1) (" SetServiceStatus error  %ld\n", status);
+	}
+	debug(1, 1) ("Leaving Squid service \n");
+	break;
+    default:
+	debug(1, 1) ("Unrecognized opcode %ld\n", Opcode);
+    }
+    return;
+}
+
+void
+WIN32_RemoveService()
+{
+    SC_HANDLE schService;
+    SC_HANDLE schSCManager;
+
+    if (!WIN32_Service_name)
+	WIN32_Service_name = xstrdup(_WIN_SQUID_DEFAULT_SERVICE_NAME);
+    strcat(REGKEY, WIN32_Service_name);
+    keys[4] = WIN32_Service_name;
+    schSCManager = OpenSCManager(NULL,	/* machine (NULL == local)    */
+	NULL,			/* database (NULL == default) */
+	SC_MANAGER_ALL_ACCESS	/* access required            */
+	);
+    if (!schSCManager)
+	debug(1, 1) ("OpenSCManager failed");
+    else {
+	schService = OpenService(schSCManager, WIN32_Service_name, SERVICE_ALL_ACCESS);
+	if (schService == NULL)
+	    debug(1, 1) ("OpenService failed");
+	/* Could not open the service */
+	else {
+	    /* try to stop the service */
+	    if (ControlService(schService, _WIN_SQUID_SERVICE_CONTROL_STOP,
+		    &svcStatus)) {
+		sleep(1);
+		while (QueryServiceStatus(schService, &svcStatus)) {
+		    if (svcStatus.dwCurrentState == SERVICE_STOP_PENDING)
+			sleep(1);
+		    else
+			break;
+		}
+	    }
+	    /* now remove the service */
+	    if (DeleteService(schService) == 0)
+		fprintf(stderr,"DeleteService failed.\n");
+	    else
+		printf("Service %s deleted successfully.\n",
+		    WIN32_Service_name);
+	    CloseServiceHandle(schService);
+	}
+	CloseServiceHandle(schSCManager);
+    }
+}
+
+void
+WIN32_SetServiceCommandLine()
+{
+    if (!WIN32_Service_name)
+	WIN32_Service_name = xstrdup(_WIN_SQUID_DEFAULT_SERVICE_NAME);
+    strcat(REGKEY, WIN32_Service_name);
+    keys[4] = WIN32_Service_name;
+    /* Now store the Service Command Line in the registry */
+    WIN32_StoreKey(COMMANDLINE, REG_SZ, (unsigned char *) WIN32_Command_Line, strlen(WIN32_Command_Line) + 1);
+}
+
+void
+WIN32_InstallService()
+{
+    SC_HANDLE schService;
+    SC_HANDLE schSCManager;
+    char ServicePath[512];
+    char szPath[512];
+    int lenpath;
+    
+    if (!WIN32_Service_name)
+	WIN32_Service_name = xstrdup(_WIN_SQUID_DEFAULT_SERVICE_NAME);
+    strcat(REGKEY, WIN32_Service_name);
+    keys[4] = WIN32_Service_name;
+    if ((lenpath = GetModuleFileName(NULL, ServicePath, 512)) == 0) {
+	debug(1, 1) ("Can't get executable path");
+	exit(1);
+    }
+    snprintf(szPath, sizeof(szPath), "%s %s:%s", ServicePath, _WIN_SQUID_SERVICE_OPTION, WIN32_Service_name);
+    schSCManager = OpenSCManager(NULL,	/* machine (NULL == local)    */
+	NULL,			/* database (NULL == default) */
+	SC_MANAGER_ALL_ACCESS	/* access required            */
+	);
+    if (!schSCManager) {    
+	debug(1, 1) ("OpenSCManager failed");
+	exit(1);
+    }
+    else {
+	schService = CreateService(schSCManager,    /* SCManager database     */
+	    WIN32_Service_name,			    /* name of service        */
+	    WIN32_Service_name,			    /* name to display        */
+	    SERVICE_ALL_ACCESS,			    /* desired access         */
+	    SERVICE_WIN32_OWN_PROCESS,		    /* service type           */
+	    SERVICE_AUTO_START,			    /* start type             */
+	    SERVICE_ERROR_NORMAL,		    /* error control type     */
+	    (const char *) szPath,		    /* service's binary       */
+	    NULL,				    /* no load ordering group */
+	    NULL,				    /* no tag identifier      */
+	    "Tcpip\0AFD\0",			    /* dependencies           */
+	    NULL,				    /* LocalSystem account    */
+	    NULL);				    /* no password            */
+	if (schService) {
+	    if ((WIN32_OS_version == _WIN_OS_WIN2K) || (WIN32_OS_version == _WIN_OS_WINXP))
+	    {
+		HMODULE ADVAPI32Handle;
+		PFChangeServiceConfig2 ChangeServiceConfig2;
+		DWORD dwInfoLevel = SERVICE_CONFIG_DESCRIPTION;
+
+		ADVAPI32Handle = GetModuleHandle("advapi32");
+		ChangeServiceConfig2 = (PFChangeServiceConfig2) GetProcAddress(ADVAPI32Handle, CHANGESERVICECONFIG2);
+		ChangeServiceConfig2(schService, dwInfoLevel, &Squid_ServiceDescription);
+		dwInfoLevel = SERVICE_CONFIG_FAILURE_ACTIONS;
+		ChangeServiceConfig2(schService, dwInfoLevel, &Squid_ServiceFailureActions);
+	    } 
+	    CloseServiceHandle(schService);
+	    /* Now store the config file location in the registry */
+	    if (!ConfigFile)
+		ConfigFile = xstrdup(DefaultConfigFile);
+	    WIN32_StoreKey(CONFIGFILE, REG_SZ, (unsigned char *) ConfigFile, strlen(ConfigFile) + 1);
+	    printf("Squid Cache version %s for %s\n", version_string,
+		CONFIG_HOST_TYPE);
+	    printf("installed successfully as %s Windows System Service.\n",
+		WIN32_Service_name);
+	    printf
+		("To run, start it from the Services Applet of Control Panel.\n");
+	    printf("Don't forget to edit squid.conf before starting it.\n\n");
+	} else {
+	    debug(1, 1) ("CreateService failed");
+	    exit(1);
+	}
+	CloseServiceHandle(schSCManager);
+    }
+}
+
+void
+WIN32_sendSignal(int WIN32_signal)
+{
+    SERVICE_STATUS ssStatus;
+    DWORD fdwAccess, fdwControl;
+    SC_HANDLE schService;
+    SC_HANDLE schSCManager;
+
+    if (!WIN32_Service_name)
+	WIN32_Service_name = xstrdup(_WIN_SQUID_DEFAULT_SERVICE_NAME);
+    schSCManager = OpenSCManager(NULL,	/* machine (NULL == local)    */
+	NULL,			/* database (NULL == default) */
+	SC_MANAGER_ALL_ACCESS	/* access required            */
+	);
+    if (!schSCManager) {
+	debug(1, 1) ("OpenSCManager failed");
+	exit(1);
+    }
+    /* The required service object access depends on the control. */
+    switch (WIN32_signal) {
+    case 0:			/* SIGNULL */
+	fdwAccess = SERVICE_INTERROGATE;
+	fdwControl = _WIN_SQUID_SERVICE_CONTROL_INTERROGATE;
+	break;
+    case SIGUSR1:
+	fdwAccess = SERVICE_USER_DEFINED_CONTROL;
+	fdwControl = _WIN_SQUID_SERVICE_CONTROL_ROTATE;
+	break;
+    case SIGUSR2:
+	fdwAccess = SERVICE_USER_DEFINED_CONTROL;
+	fdwControl = _WIN_SQUID_SERVICE_CONTROL_DEBUG;
+	break;
+    case SIGHUP:
+	fdwAccess = SERVICE_USER_DEFINED_CONTROL;
+	fdwControl = _WIN_SQUID_SERVICE_CONTROL_RECONFIGURE;
+	break;
+    case SIGTERM:
+	fdwAccess = SERVICE_STOP;
+	fdwControl = _WIN_SQUID_SERVICE_CONTROL_STOP;
+	break;
+    case SIGINT:
+    case SIGKILL:
+	fdwAccess = SERVICE_USER_DEFINED_CONTROL;
+	fdwControl = _WIN_SQUID_SERVICE_CONTROL_INTERRUPT;
+	break;
+    default:
+	exit(1);
+    }
+    /* Open a handle to the service. */
+    schService = OpenService(schSCManager,	/* SCManager database */
+	WIN32_Service_name,	/* name of service    */
+	fdwAccess);		/* specify access     */
+    if (schService == NULL) {
+	fprintf(stderr, "%s: ERROR: Could not open Service %s\n", appname,
+	    WIN32_Service_name);
+	exit(1);
+    } else {
+	/* Send a control value to the service. */
+	if (!ControlService(schService,	/* handle of service      */
+		fdwControl,	/* control value to send  */
+		&ssStatus)) {	/* address of status info */
+	    fprintf(stderr, "%s: ERROR: Could not Control Service %s\n",
+		appname, WIN32_Service_name);
+	    exit(1);
+	} else {
+	    /* Print the service status. */
+	    printf("\nStatus of %s Service:\n", WIN32_Service_name);
+	    printf("  Service Type: 0x%lx\n", ssStatus.dwServiceType);
+	    printf("  Current State: 0x%lx\n", ssStatus.dwCurrentState);
+	    printf("  Controls Accepted: 0x%lx\n", ssStatus.dwControlsAccepted);
+	    printf("  Exit Code: %ld\n", ssStatus.dwWin32ExitCode);
+	    printf("  Service Specific Exit Code: %ld\n",
+		ssStatus.dwServiceSpecificExitCode);
+	    printf("  Check Point: %ld\n", ssStatus.dwCheckPoint);
+	    printf("  Wait Hint: %ld\n", ssStatus.dwWaitHint);
+	}
+	CloseServiceHandle(schService);
+    }
+    CloseServiceHandle(schSCManager);
+}
+
+int main(int argc, char **argv)
+{
+    SERVICE_TABLE_ENTRY DispatchTable[] = {
+	{NULL, SquidMain},
+	{NULL, NULL}
+    };
+    char *c;
+    
+    if ((argc == 2) && strstr(argv[1], _WIN_SQUID_SERVICE_OPTION)){
+	WIN32_run_mode = _WIN_SQUID_RUN_MODE_SERVICE;
+	if (!(c=strchr(argv[1],':'))){
+	    fprintf(stderr, "Bad Service Parameter: %s\n", argv[1]);
+	    return 1;
+	}
+	WIN32_Service_name = xstrdup(c+1);
+	DispatchTable[0].lpServiceName=WIN32_Service_name;
+	strcat(REGKEY, WIN32_Service_name);
+	keys[4] = WIN32_Service_name;
+    	if (!StartServiceCtrlDispatcher(DispatchTable)) {
+	    fprintf(stderr, "StartServiceCtrlDispatcher error = %ld\n",
+		GetLastError());
+	    return 1;
+	}
+    } else {
+    	WIN32_run_mode = _WIN_SQUID_RUN_MODE_INTERACTIVE;
+	SquidMain(argc, argv);
+    }
     return 0;
 }
 #endif
+
+/* The following code section is part of an EXPERIMENTAL native */
+/* Windows NT/2000 Squid port - Compiles only on MS Visual C++  */
+
+#if defined(_SQUID_MSWIN_)
+static int s_iInitCount = 0;
+
+static int Win32SockInit(void)
+{
+    int iVersionRequested;
+    WSADATA wsaData;
+    int err;
+
+    if (s_iInitCount > 0) {
+	s_iInitCount++;
+	return (0);
+    }
+    else if (s_iInitCount < 0)
+	return (s_iInitCount);
+    /* s_iInitCount == 0. Do the initailization */
+    iVersionRequested = MAKEWORD(2, 0);
+    err = WSAStartup((WORD) iVersionRequested, &wsaData);
+    if (err) {
+	s_iInitCount = -1;
+	return (s_iInitCount);
+    }
+    if (LOBYTE(wsaData.wVersion) != 2 ||
+	HIBYTE(wsaData.wVersion) != 0) {
+	s_iInitCount = -2;
+	WSACleanup();
+	return (s_iInitCount);
+    }
+    debug(1,1)("Windows sockets initialised");
+    s_iInitCount++;
+    return (s_iInitCount);
+}
+
+static void Win32SockCleanup(void)
+{
+    if (--s_iInitCount == 0)
+	WSACleanup();
+    return;
+}
+#endif /* End native Windows NT EXPERIMENTAL PORT */
+#endif
+
+#endif /* WIN32_C */
Index: squid/src/auth/basic/helpers/Makefile.am
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/auth/basic/helpers/Attic/Makefile.am,v
retrieving revision 1.2
retrieving revision 1.2.36.1
diff -u -r1.2 -r1.2.36.1
--- squid/src/auth/basic/helpers/Makefile.am	1 Sep 2001 11:46:49 -0000	1.2
+++ squid/src/auth/basic/helpers/Makefile.am	27 Feb 2002 19:44:05 -0000	1.2.36.1
@@ -3,5 +3,5 @@
 #  $Id$
 #
 
-DIST_SUBDIRS	= getpwnam LDAP MSNT multi-domain-NTLM NCSA PAM SMB YP
+DIST_SUBDIRS	= getpwnam LDAP MSNT multi-domain-NTLM NCSA PAM SMB win32_locallogon YP
 SUBDIRS		= @BASIC_AUTH_HELPERS@
--- /dev/null	Wed Feb 14 00:55:47 2007
+++ squid/src/auth/basic/helpers/win32_locallogon/Makefile.am	Wed Feb 14 00:57:22 2007
@@ -0,0 +1,17 @@
+#
+#  Makefile for the Squid Object Cache server
+#
+#  $Id$
+#
+#  Uncomment and customize the following to suit your needs:
+#
+
+
+libexec_PROGRAMS = nt_auth
+
+nt_auth_SOURCES = NT_auth.c valid.c
+
+LDADD	= -lnetapi32
+
+INCLUDES      = -I. -I$(top_builddir)/include -I$(top_srcdir)/include \
+		-I$(top_srcdir)/src/
--- /dev/null	Wed Feb 14 00:55:47 2007
+++ squid/src/auth/basic/helpers/win32_locallogon/NT_auth.c	Wed Feb 14 00:57:22 2007
@@ -0,0 +1,161 @@
+/*
+  NT_auth -  Version 1.11
+
+  Modified to act as a Squid authenticator module.
+  Can run as dll on NT native port.
+  Removed all Pike stuff.
+  Returns OK for a successful authentication, or ERR upon error.
+
+  Guido Serassio, Torino - Italy
+  Sun Jun 17 14:34:26 CST 2001
+
+  Uses code from -
+    Antonino Iannella 2000
+    Andrew Tridgell 1997
+    Richard Sharpe 1996
+    Bill Welliver 1999
+
+  Released under GNU Public License
+
+   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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "squid.h"
+
+/* Check if we try to compile on a Windows Platform */
+#if defined(_SQUID_CYGWIN_) || defined(_SQUID_MSWIN_)
+
+#include "valid.h"
+
+/* Main program for simple authentication.
+   Scans and checks for Squid input, and attempts to validate the user.
+*/
+
+#if defined (_SQUID_CYGWIN_)
+
+static char NTGroup[256];
+int
+main(int argc, char **argv)
+
+#else defined (_SQUID_MSWIN_)
+
+typedef struct
+{
+    void *data;
+    acl_proxy_auth_user *auth_user;
+    RH *handler;
+}
+authenticateStateData;
+static char *NTGroup = NULL;
+BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason,
+    LPVOID reserved /* Not used. */ );
+
+__declspec(dllexport)
+     int Authenticate(char *username, char *password,
+    authenticateStateData * data, HLPCB callback)
+#endif
+{
+#if defined(_SQUID_CYGWIN_)
+    char wstr[256];
+    char username[256];
+    char password[256];
+    char *p;
+
+    if (argc != 2) {
+	fprintf(stderr, "Usage: NT_auth <NT Group>\n");
+	exit(1);
+    }
+    strcpy(NTGroup, argv[1]);
+    while (1) {
+	/* Read whole line from standard input. Terminate on break. */
+	if (fgets(wstr, 255, stdin) == NULL)
+	    break;
+	if ((p = strchr(wstr, '\n')) != NULL)
+	    *p = '\0';		/* strip \n */
+	if ((p = strchr(wstr, '\r')) != NULL)
+	    *p = '\0';		/* strip \r */
+	/* Clear any current settings */
+	username[0] = '\0';
+	password[0] = '\0';
+	sscanf(wstr, "%s %s", username, password);	/* Extract parameters */
+#endif
+	/* Check for invalid or blank entries */
+	if ((username[0] == '\0') || (password[0] == '\0')) {
+#if defined(_SQUID_CYGWIN_)
+	    puts("ERR");
+	    fflush(stdout);
+	    continue;
+#else
+	    (callback) (data, "ERR");
+	    return 0;
+#endif
+	}
+	if (Valid_User(username, password, NTGroup) == NTV_NO_ERROR)
+#if defined(_SQUID_CYGWIN_)
+	    puts("OK");
+#else
+	    (callback) (data, "OK");
+#endif
+	else
+#if defined(_SQUID_CYGWIN_)
+	    puts("ERR");
+	fflush(stdout);
+    }
+#else
+	    (callback) (data, "ERR");
+#endif
+    return 0;
+}
+
+/* Valid_User return codes -
+   0 - User authenticated successfully.
+   1 - Server error.
+   2 - Protocol error.
+   3 - Logon error; Incorrect password or username given.
+*/
+
+#ifndef _SQUID_CYGWIN_
+
+__declspec(dllexport)
+     int Init(char *Group)
+{
+    if (NTGroup)
+	xfree(NTGroup);
+    NTGroup = xstrdup(Group);
+    return 0;
+}
+BOOL APIENTRY
+DllMain(HINSTANCE hInst /* Library instance handle. */ ,
+    DWORD reason /* Reason this function is being called. */ ,
+    LPVOID reserved /* Not used. */ )
+{
+    switch (reason) {
+    case DLL_PROCESS_ATTACH:
+	break;
+    case DLL_PROCESS_DETACH:
+	break;
+    case DLL_THREAD_ATTACH:
+	break;
+    case DLL_THREAD_DETACH:
+	break;
+    }
+    return TRUE;
+}
+#endif
+#else  /* NON Windows Platform !!! */
+
+#error NON WINDOWS PLATFORM
+
+#endif
--- /dev/null	Wed Feb 14 00:55:47 2007
+++ squid/src/auth/basic/helpers/win32_locallogon/README.txt	Wed Feb 14 00:57:22 2007
@@ -0,0 +1,77 @@
+This is a simple authentication module for the Squid proxy server running on Windows NT
+compiled with CygWin to authenticate users on an NT domain in native WIN32 mode.
+
+Usage is simple. It accepts a username and password on standard input
+and will return OK if the username/password is valid for the domain/machine,
+or ERR if there was some problem.
+It's possible to authenticate against NT trusted domains specifyng the username 
+in the domain\username Microsoft notation. 
+
+This is released under the GNU General Public License and
+is available from http://www.serassio.it.
+
+Allowing Users -
+
+Users that are allowed to access the web proxy must have the Windows NT
+User Rights "logon from the network" and must be included in the NT LOCAL User Group 
+specified in the Authenticator's command line. 
+This can be accomplished creating a local user group on the NT machine, grant the privilege,
+and adding users to it.
+
+The squid process must have the NT User Rights "Act as part of the operating system",
+this is true if squid runs as a service with LocalSystem Account.
+
+Installation -
+
+Type 'make', then 'make install', then 'make clean'.
+
+The default is to install 'nt_auth' into /usr/local/squid/bin.
+
+Refer to Squid documentation for the required changes to squid.conf.
+You will need to set the following line to enable the authenticator:
+
+authenticate_program /usr/local/squid/bin/NT_auth <yourNTgroup>
+
+You will need to set the following lines to enable authentication for
+your access list -
+
+  acl <yourACL> proxy_auth REQUIRED
+  http_access allow <yourACL>
+
+You will need to specify the absolute path to NT_auth in the 
+authenticate_program directive, and check the authenticate_children
+and authenticate_ttl.
+
+Compilation issues -
+
+The Makefile assumes that GCC is in the current PATH.
+NT_auth compile ONLY on CygWin Environment or MS VC++.
+
+Note: Under MS VC++ this package compile as a dll, an work only with my release 
+of native NT Squid 2.3 STABLE 5 port.
+
+Testing -
+
+I strongly urge that NT_auth is tested prior to being used in a 
+production environment. It may behave differently on different platforms.
+To test it, run it from the command line. Enter username and password
+pairs separated by a space. Press ENTER to get an OK or ERR message.
+Make sure pressing <CTRL><D> behaves the same as a carriage return.
+Make sure pressing <CTRL><C> aborts the program.
+
+NOTE: the NT user running the NT_auth module, must have the NT User Rights
+"Act as part of the operating system".
+
+Test that entering no details does not result in an OK or ERR message.
+Test that entering an invalid username and password results in an ERR message.
+Note that if NT guest user access is allowed on the PDC, an OK message
+may be returned instead of ERR.
+Test that entering an valid username and password results in an OK message.
+Test that entering a guest username and password returns the correct
+response for the site's access policy.
+
+Contact details -
+
+To contact the maintainer of this package, email Guido Serassio
+on serassio@interfree.it.
+The latest version may be found on http://www.serassio.it/SquidNT.htm.
--- /dev/null	Wed Feb 14 00:55:47 2007
+++ squid/src/auth/basic/helpers/win32_locallogon/valid.c	Wed Feb 14 00:57:22 2007
@@ -0,0 +1,108 @@
+#include "squid.h"
+
+/* Check if we try to compile on a Windows Platform */
+#if defined(_SQUID_CYGWIN_) || defined(_SQUID_MSWIN_)
+
+#include <assert.h>
+#if defined(_SQUID_CYGWIN_)
+#include <wchar.h>
+#endif
+#include <windows.h>
+#include <lm.h>
+#include "valid.h"
+
+int
+Valid_User(char *UserName, char *Password, char *Group)
+{
+    HANDLE hToken = INVALID_HANDLE_VALUE;
+    int result = NTV_LOGON_ERROR;
+    int error;
+    char NTDomain[256];
+    char *domain_qualify;
+    char DomainUser[256];
+    WCHAR wszUserName[256];	// Unicode user name
+    WCHAR wszGroup[256];	// Unicode Group
+
+    LPLOCALGROUP_USERS_INFO_0 pBuf = NULL;
+    LPLOCALGROUP_USERS_INFO_0 pTmpBuf;
+    DWORD dwLevel = 0;
+    DWORD dwFlags = LG_INCLUDE_INDIRECT;
+    DWORD dwPrefMaxLen = -1;
+    DWORD dwEntriesRead = 0;
+    DWORD dwTotalEntries = 0;
+    NET_API_STATUS nStatus;
+    DWORD i;
+    DWORD dwTotalCount = 0;
+
+/* Convert ANSI User Name and Group to Unicode */
+
+    MultiByteToWideChar(CP_ACP, 0, UserName,
+	strlen(UserName) + 1, wszUserName,
+	sizeof(wszUserName) / sizeof(wszUserName[0]));
+    MultiByteToWideChar(CP_ACP, 0, Group,
+	strlen(Group) + 1, wszGroup, sizeof(wszGroup) / sizeof(wszGroup[0]));
+    strcpy(NTDomain, UserName);
+    if ((domain_qualify = strchr(NTDomain, '\\')) == NULL) {
+	strcpy(DomainUser, NTDomain);
+	strcpy(NTDomain, ".");
+    } else {
+	strcpy(DomainUser, domain_qualify + 1);
+	domain_qualify[0] = '\0';
+    }
+    /* Log the client on to the local computer. */
+    if (!LogonUser(DomainUser,
+	    NTDomain,
+	    Password,
+	    LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &hToken)) {
+	result = NTV_LOGON_ERROR;
+	error = GetLastError();
+    } else {
+	/*
+	 * Call the NetUserGetLocalGroups function 
+	 * specifying information level 0.
+	 * 
+	 * The LG_INCLUDE_INDIRECT flag specifies that the 
+	 * function should also return the names of the local 
+	 * groups in which the user is indirectly a member.
+	 */
+	nStatus = NetUserGetLocalGroups(NULL,
+	    wszUserName,
+	    dwLevel,
+	    dwFlags,
+	    (LPBYTE *) & pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries);
+	/*
+	 * If the call succeeds,
+	 */
+	if (nStatus == NERR_Success) {
+	    if ((pTmpBuf = pBuf) != NULL) {
+		for (i = 0; i < dwEntriesRead; i++) {
+		    assert(pTmpBuf != NULL);
+		    if (pTmpBuf == NULL) {
+			result = NTV_SERVER_ERROR;
+			break;
+		    }
+		    if (wcscmp(pTmpBuf->lgrui0_name, wszGroup) == 0) {
+			result = NTV_NO_ERROR;
+			break;
+		    }
+		    pTmpBuf++;
+		    dwTotalCount++;
+		}
+	    }
+	} else
+	    result = NTV_SERVER_ERROR;
+	/*
+	 * Free the allocated memory.
+	 */
+	if (pBuf != NULL)
+	    NetApiBufferFree(pBuf);
+    }
+    if (hToken != INVALID_HANDLE_VALUE)
+	CloseHandle(hToken);
+    return result;
+}
+#else  /* NON Windows Platform !!! */
+
+#error NON WINDOWS PLATFORM
+
+#endif
--- /dev/null	Wed Feb 14 00:55:47 2007
+++ squid/src/auth/basic/helpers/win32_locallogon/valid.h	Wed Feb 14 00:57:22 2007
@@ -0,0 +1,16 @@
+#ifndef _VALID_H_
+#define _VALID_H_
+/* SMB User verification function */
+
+#define NTV_NO_ERROR 0
+#define NTV_SERVER_ERROR 1
+#define NTV_PROTOCOL_ERROR 2
+#define NTV_LOGON_ERROR 3
+
+#ifndef LOGON32_LOGON_NETWORK
+#define LOGON32_LOGON_NETWORK       3
+#endif
+
+int Valid_User(char *, char *, char *);
+
+#endif
Index: squid/src/fs/aufs/store_dir_aufs.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/fs/aufs/store_dir_aufs.c,v
retrieving revision 1.23.6.1
retrieving revision 1.23.6.1.2.1
diff -u -r1.23.6.1 -r1.23.6.1.2.1
--- squid/src/fs/aufs/store_dir_aufs.c	20 Feb 2002 02:49:04 -0000	1.23.6.1
+++ squid/src/fs/aufs/store_dir_aufs.c	27 Feb 2002 19:44:06 -0000	1.23.6.1.2.1
@@ -917,7 +917,7 @@
 	debug(50, 0) ("%s: %s\n", swaplog_path, xstrerror());
 	fatal("Failed to open swap log for reading");
     }
-#if defined(_SQUID_CYGWIN_)
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
     setmode(fileno(fp), O_BINARY);
 #endif
     memset(&clean_sb, '\0', sizeof(struct stat));
Index: squid/src/fs/ufs/store_dir_ufs.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/fs/ufs/store_dir_ufs.c,v
retrieving revision 1.21.6.1
retrieving revision 1.21.6.1.2.1
diff -u -r1.21.6.1 -r1.21.6.1.2.1
--- squid/src/fs/ufs/store_dir_ufs.c	20 Feb 2002 02:49:04 -0000	1.21.6.1
+++ squid/src/fs/ufs/store_dir_ufs.c	27 Feb 2002 19:44:06 -0000	1.21.6.1.2.1
@@ -860,7 +860,7 @@
     char *new_path = xstrdup(storeUfsDirSwapLogFile(sd, ".new"));
     int fd;
     file_close(ufsinfo->swaplog_fd);
-#if defined (_SQUID_OS2_) || defined (_SQUID_CYGWIN_)
+#if defined (_SQUID_OS2_) || defined (_SQUID_CYGWIN_) || defined (_SQUID_MSWIN_)
     if (unlink(swaplog_path) < 0) {
 	debug(50, 0) ("%s: %s\n", swaplog_path, xstrerror());
 	fatal("storeUfsDirCloseTmpSwapLog: unlink failed");
@@ -915,7 +915,7 @@
 	debug(50, 0) ("%s: %s\n", swaplog_path, xstrerror());
 	fatal("Failed to open swap log for reading");
     }
-#if defined(_SQUID_CYGWIN_)
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
     setmode(fileno(fp), O_BINARY);
 #endif
     memset(&clean_sb, '\0', sizeof(struct stat));
@@ -967,6 +967,9 @@
     state->outbuf = xcalloc(CLEAN_BUF_SZ, 1);
     state->outbuf_offset = 0;
     state->walker = sd->repl->WalkInit(sd->repl);
+#if !(defined(_SQUID_OS2_) || defined (_SQUID_CYGWIN_)) || defined (_SQUID_MSWIN_)
+    unlink(state->new);
+#endif
     unlink(state->cln);
     debug(20, 3) ("storeDirWriteCleanLogs: opened %s, FD %d\n",
 	state->new, state->fd);
@@ -1060,7 +1063,7 @@
     fd = state->fd;
     /* rename */
     if (state->fd >= 0) {
-#if defined(_SQUID_OS2_) || defined (_SQUID_CYGWIN_)
+#if defined(_SQUID_OS2_) || defined (_SQUID_CYGWIN_) || defined (_SQUID_MSWIN_)
 	file_close(state->fd);
 	state->fd = -1;
 	if (unlink(state->cur) < 0)
