---------------------
PatchSet 2537 
Date: 2001/06/14 20:36:15
Author: serassio
Branch: nt-2_3
Tag: (none) 
Log:
Backport of revised Windows NT code from 2.5 DEVEL branch

Members: 
	include/autoconf.h:1.1.2.2->1.1.2.3 
	include/autoconf.h.in:1.1.1.3.4.2.2.1->1.1.1.3.4.2.2.2 
	include/config.h:1.1.2.2->1.1.2.3 
	include/config.h.in:1.1.1.3.4.1.2.2->1.1.1.3.4.1.2.3 
	include/getopt.h:1.1->1.1.2.1 
	lib/win32lib.c:1.1->1.1.2.1 
	src/access_log.c:1.1.1.3.4.1.2.1->1.1.1.3.4.1.2.2 
	src/asn.c:1.1.1.3.4.2.2.1->1.1.1.3.4.2.2.2 
	src/cache_cf.c:1.1.1.3.4.4.2.2->1.1.1.3.4.4.2.3 
	src/defines.h:1.1.1.3.4.2.2.1->1.1.1.3.4.2.2.2 
	src/disk.c:1.1.1.3.4.1.2.2->1.1.1.3.4.1.2.3 
	src/dns_internal.c:1.1.1.1.4.6.2.1->1.1.1.1.4.6.2.2 
	src/globals.h:1.1.1.3.4.2.2.2->1.1.1.3.4.2.2.3 
	src/main.c:1.1.1.3.4.2.2.3->1.1.1.3.4.2.2.4 
	src/protos.h:1.1.1.3.4.1.2.3->1.1.1.3.4.1.2.4 
	src/readdir.c:1.1.2.1->1.1.2.2(DEAD) 
	src/squid.h:1.1.1.3.4.1.2.2->1.1.1.3.4.1.2.3 
	src/store.c:1.1.1.3.4.5.2.2->1.1.1.3.4.5.2.3 
	src/store_dir.c:1.1.1.3.4.2.2.2->1.1.1.3.4.2.2.3 
	src/store_dir_ufs.c:1.1.1.1.4.1.2.2->1.1.1.1.4.1.2.3 
	src/string-arrays.c:1.1.2.1->1.1.2.2(DEAD) 
	src/structs.h:1.1.1.3.4.2.2.2->1.1.1.3.4.2.2.3 
	src/tools.c:1.1.1.3.4.1.2.3->1.1.1.3.4.1.2.4 
	src/typedefs.h:1.1.1.3.4.1.2.2->1.1.1.3.4.1.2.3 
	src/url.c:1.1.1.3.4.4.2.1->1.1.1.3.4.4.2.2 
	src/useragent.c:1.1.1.3.4.1.2.2->1.1.1.3.4.1.2.3 
	src/win32.c:1.1.2.2->1.1.2.3 

Index: squid/include/autoconf.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/include/Attic/autoconf.h,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -r1.1.2.2 -r1.1.2.3
--- squid/include/autoconf.h	25 Mar 2001 17:49:42 -0000	1.1.2.2
+++ squid/include/autoconf.h	14 Jun 2001 20:36:15 -0000	1.1.2.3
@@ -100,7 +100,6 @@
  * directory.
  */
 #undef USE_USERAGENT_LOG
-//#define USE_USERAGENT_LOG 1
 
 /*
  * A dangerous feature which causes Squid to kill its parent process
@@ -116,7 +115,6 @@
  * Define to enable WCCP
  */
 #undef USE_WCCP
-#define USE_WCCP 1
 
 /*
  * Squid frequently calls gettimeofday() for accurate timestamping.
@@ -145,13 +143,16 @@
  * code is still semi-experimental. 
  */
 #undef USE_CACHE_DIGESTS
-//#define USE_CACHE_DIGESTS 1
 
 /*
  * Cache Array Routing Protocol
  */
 #undef USE_CARP
-#define USE_CARP 1
+
+/*
+ * Define Windows NT & Windows 2000 run service mode
+ */
+#define USE_WIN32_SERVICE 1
 
 /* Define if struct tm has tm_gmtoff member */
 #undef HAVE_TM_GMTOFF
@@ -165,7 +166,7 @@
 
 /* Maximum number of open filedescriptors */
 #undef SQUID_MAXFD
-//#define SQUID_MAXFD 2048
+#define SQUID_MAXFD 2048
 
 /* UDP send buffer size */
 #undef SQUID_UDP_SO_SNDBUF
@@ -204,6 +205,7 @@
 
 /* Define if we should use GNU regex */
 #undef USE_GNUREGEX
+#define USE_GNUREGEX 1
 
 /* signed size_t, grr */
 #undef ssize_t
@@ -219,6 +221,9 @@
 /* Define if you have struct rusage */
 #undef HAVE_STRUCT_RUSAGE
 
+/* Define if you have PSAPI.DLL on Windows systems */
+#define HAVE_WIN32_PSAPI 1
+
 /*
  * This makes warnings go away.  If you have socklen_t defined in your
  * /usr/include files, then this should remain undef'd.  Otherwise it
@@ -276,7 +281,6 @@
  * the dnsserver processes instead.
  */
 #undef USE_DNSSERVERS
-#define USE_DNSSERVERS 1
 /*
  * we check for the existance of struct mallinfo
  */
@@ -334,6 +338,7 @@
 
 /* Define if you have the getrusage function.  */
 #undef HAVE_GETRUSAGE
+#define HAVE_GETRUSAGE 1
 
 /* Define if you have the getspnam function.  */
 #undef HAVE_GETSPNAM
@@ -491,6 +496,7 @@
 
 /* Define if you have the <getopt.h> header file.  */
 #undef HAVE_GETOPT_H
+#define HAVE_GETOPT_H 1
 
 /* Define if you have the <gnumalloc.h> header file.  */
 #undef HAVE_GNUMALLOC_H
Index: squid/include/autoconf.h.in
===================================================================
RCS file: /cvsroot/squid-sf//squid/include/Attic/autoconf.h.in,v
retrieving revision 1.1.1.3.4.2.2.1
retrieving revision 1.1.1.3.4.2.2.2
diff -u -r1.1.1.3.4.2.2.1 -r1.1.1.3.4.2.2.2
--- squid/include/autoconf.h.in	6 Jan 2001 12:51:32 -0000	1.1.1.3.4.2.2.1
+++ squid/include/autoconf.h.in	14 Jun 2001 20:36:15 -0000	1.1.1.3.4.2.2.2
@@ -144,6 +144,11 @@
  */
 #undef USE_CARP
 
+/*
+ * Define Windows NT & Windows 2000 run service mode
+ */
+#define USE_WIN32_SERVICE 1
+
 /* Define if struct tm has tm_gmtoff member */
 #undef HAVE_TM_GMTOFF
 
@@ -202,6 +207,9 @@
 /* Define if you have struct rusage */
 #undef HAVE_STRUCT_RUSAGE
 
+/* Define if you have PSAPI.DLL on Windows systems */
+#define HAVE_WIN32_PSAPI 1
+
 /*
  * This makes warnings go away.  If you have socklen_t defined in your
  * /usr/include files, then this should remain undef'd.  Otherwise it
Index: squid/include/config.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/include/config.h,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -r1.1.2.2 -r1.1.2.3
--- squid/include/config.h	25 Mar 2001 17:49:42 -0000	1.1.2.2
+++ squid/include/config.h	14 Jun 2001 20:36:15 -0000	1.1.2.3
@@ -103,16 +103,24 @@
 #elif defined(WIN32) || defined(WINNT) || defined(__WIN32__) || defined(__WIN32)
 #define _SQUID_MSWIN_
 
-#define SQUID_MAXFD 128
+/* Some tricks for MS Compilers */
+#define alloca _alloca
+#define chdir _chdir
+#define getcwd _getcwd
+#define getpid _getpid
+#define mkdir _mkdir
+#define setmode _setmode
+#define snprintf _snprintf
+#define vsnprintf _vsnprintf
+#define O_BYNARY _O_BINARY
+#define O_TEXT _O_TEXT
+#define S_IRWXO 007
+#define	S_ISDIR(m) (((m) & _S_IFDIR) == _S_IFDIR)
+
 #include <stddef.h>
-#define FD_SETSIZE 128
 #include <ws2spi.h>
-#include <sys/timeb.h>
-#include <malloc.h>
-#include "GNUregex.h"
 #include "readdir.h"
 
-extern int Win32SockInit(void);
 #define SQUIDHOSTNAMELEN 128
 typedef char *caddr_t;
 #undef FD_CLOSE
@@ -127,16 +135,8 @@
 #define ETIMEDOUT WSAETIMEDOUT
 #define uid_t int
 #define gid_t int
-#define xstrdup _strdup
-#define snprintf _snprintf
-#define chdir _chdir
-#define getcwd _getcwd
 #define strcasecmp _stricmp
 #define strncasecmp _strnicmp
-#define vsnprintf _vsnprintf
-#define getpid _getpid
-#define mkdir _mkdir
-#define	S_ISDIR(m)	(((m) & _S_IFDIR) == _S_IFDIR)
 
 #if defined (COMM_C) || defined (COMM_SELECT_C)
 #define recv(x,y,z) recv(x,y,z,0)
@@ -175,16 +175,6 @@
 #define commSetSelect(x,y,z,u,v) commSetSelectS(x,y,z,u,v)
 #endif
 
-
-#define	SIGHUP	1	/* hangup */
-#define	SIGKILL	9	/* kill (cannot be caught or ignored) */
-#define	SIGBUS	10	/* bus error */
-#define	SIGPIPE	13	/* write on a pipe with no one to read it */
-#define	SIGCHLD	20	/* to parent on child stop or exit */
-#define SIGUSR1 30	/* user defined signal 1 */
-#define SIGUSR2 31	/* user defined signal 2 */
-extern void gettimeofday( struct timeval * ,void *);
-
 #elif defined(__APPLE__)
 #define _SQUID_APPLE_
 
Index: squid/include/config.h.in
===================================================================
RCS file: /cvsroot/squid-sf//squid/include/Attic/config.h.in,v
retrieving revision 1.1.1.3.4.1.2.2
retrieving revision 1.1.1.3.4.1.2.3
diff -u -r1.1.1.3.4.1.2.2 -r1.1.1.3.4.1.2.3
--- squid/include/config.h.in	25 Mar 2001 17:49:42 -0000	1.1.1.3.4.1.2.2
+++ squid/include/config.h.in	14 Jun 2001 20:36:15 -0000	1.1.1.3.4.1.2.3
@@ -1,5 +1,5 @@
 /*
- * $Id: config.h.in,v 1.1.1.3.4.1.2.2 2001/03/25 17:49:42 serassio Exp $
+ * $Id: config.h.in,v 1.1.1.3.4.1.2.3 2001/06/14 20:36:15 serassio Exp $
  *
  * AUTHOR: Duane Wessels
  *
@@ -103,6 +103,20 @@
 #elif defined(WIN32) || defined(WINNT) || defined(__WIN32__) || defined(__WIN32)
 #define _SQUID_MSWIN_
 
+/* Some tricks for MS Compilers */
+#define alloca _alloca
+#define chdir _chdir
+#define getcwd _getcwd
+#define getpid _getpid
+#define mkdir _mkdir
+#define setmode _setmode
+#define snprintf _snprintf
+#define vsnprintf _vsnprintf
+#define O_BYNARY _O_BINARY
+#define O_TEXT _O_TEXT
+#define S_IRWXO 007
+#define	S_ISDIR(m) (((m) & _S_IFDIR) == _S_IFDIR)
+
 #elif defined(__APPLE__)
 #define _SQUID_APPLE_
 
--- /dev/null	Wed Feb 14 00:52:54 2007
+++ squid/include/getopt.h	Wed Feb 14 00:53:42 2007
@@ -0,0 +1,73 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+#ifndef GETOPT_H
+#define GETOPT_H
+
+#ifdef WIN32
+
+extern char *optarg;
+extern int optreset;
+extern int optind;
+extern int opterr;
+extern int optopt;
+int getopt(int argc, char* const *argv, const char *optstr);
+
+#endif /* WIN32 */
+
+#endif /* GETOPT_H */
--- /dev/null	Wed Feb 14 00:52:54 2007
+++ squid/lib/win32lib.c	Wed Feb 14 00:53:42 2007
@@ -0,0 +1,351 @@
+/*
+ * $Id: win32lib.c,v 1.1.2.1 2001/06/14 20:36:15 serassio Exp $
+ *
+ * * * * * * * * 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"
+
+/* 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_)
+#include <stdio.h>
+#include <windows.h>
+#include <process.h>
+#undef free
+#undef malloc
+#include <string.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <sys/timeb.h>
+#include <assert.h>
+
+#define OPTERRCOLON (1)
+#define OPTERRNF (2)
+#define OPTERRARG (3)
+
+char *optarg;
+int optreset = 0;
+int optind = 1;
+int opterr = 1;
+int optopt;
+
+int chroot (const char *dirname)
+{
+	if (SetCurrentDirectory(dirname))
+		return 0;
+	else
+		return GetLastError();
+}
+
+int kill(pid_t pid, int sig)
+{
+   	HANDLE hProcess;
+
+	if (sig == 0) {
+		if ((hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
+		    PROCESS_VM_READ,
+		    FALSE, pid)) == NULL)
+				return -1;
+		else {
+        	CloseHandle(hProcess);
+			return 0;
+		}
+	}
+	else return 0;
+}
+
+void gettimeofday( struct timeval * pcur_time,void * tz){
+	struct _timeb current;
+	_ftime(&current);
+	pcur_time->tv_sec=current.time;
+	pcur_time->tv_usec=current.millitm * 1000;
+}
+
+int statfs(const char *path, struct statfs *sfs)
+{
+    char drive[4];
+    DWORD spc, bps, freec, totalc;
+    DWORD vsn, maxlen, flags;
+
+    if (!sfs)
+    {
+		errno=EINVAL;
+		return -1;
+    }
+
+    strncpy(drive,path,2);
+	drive[2]='\0';
+	strcat(drive,"\\");
+
+	if (!GetDiskFreeSpace(drive, &spc, &bps, &freec, &totalc))
+    {
+      errno=ENOENT;
+      return -1;
+    }
+    if (!GetVolumeInformation(drive, NULL, 0, &vsn, &maxlen, &flags, NULL, 0))
+    {
+      errno=ENOENT;
+      return -1;
+    }
+    sfs->f_type = flags;
+    sfs->f_bsize = spc*bps;
+    sfs->f_blocks = totalc;
+    sfs->f_bfree = sfs->f_bavail = freec;
+    sfs->f_files = -1;
+    sfs->f_ffree = -1;
+    sfs->f_fsid = vsn;
+    sfs->f_namelen = maxlen;
+    return 0;
+}
+
+
+static int
+optiserr(int argc, char * const *argv, int oint, const char *optstr,
+         int optchr, int err)
+{
+    if(opterr)
+    {
+        fprintf(stderr, "Error in argument %d, char %d: ", oint, optchr+1);
+        switch(err)
+        {
+        case OPTERRCOLON:
+            fprintf(stderr, ": in flags\n");
+            break;
+        case OPTERRNF:
+            fprintf(stderr, "option not found %c\n", argv[oint][optchr]);
+            break;
+        case OPTERRARG:
+            fprintf(stderr, "no argument for option %c\n", argv[oint][optchr]);
+            break;
+        default:
+            fprintf(stderr, "unknown\n");
+            break;
+        }
+    }
+    optopt = argv[oint][optchr];
+    return('?');
+}
+    
+
+int
+getopt(int argc, char* const *argv, const char *optstr)
+{
+    static int optchr = 0;
+    static int dash = 0; /* have already seen the - */
+
+    char *cp;
+
+    if (optreset)
+        optreset = optchr = dash = 0;
+    if(optind >= argc)
+        return(EOF);
+    if(!dash && (argv[optind][0] !=  '-'))
+        return(EOF);
+    if(!dash && (argv[optind][0] ==  '-') && !argv[optind][1])
+    {
+        /*
+         * use to specify stdin. Need to let pgm process this and
+         * the following args
+         */
+        return(EOF);
+    }
+    if((argv[optind][0] == '-') && (argv[optind][1] == '-'))
+    {
+        /* -- indicates end of args */
+        optind++;
+        return(EOF);
+    }
+    if(!dash)
+    {
+        assert((argv[optind][0] == '-') && argv[optind][1]);
+        dash = 1;
+        optchr = 1;
+    }
+
+    /* Check if the guy tries to do a -: kind of flag */
+    assert(dash);
+    if(argv[optind][optchr] == ':')
+    {
+        dash = 0;
+        optind++;
+        return(optiserr(argc, argv, optind-1, optstr, optchr, OPTERRCOLON));
+    }
+    if(!(cp = strchr(optstr, argv[optind][optchr])))
+    {
+        int errind = optind;
+        int errchr = optchr;
+
+        if(!argv[optind][optchr+1])
+        {
+            dash = 0;
+            optind++;
+        }
+        else
+            optchr++;
+        return(optiserr(argc, argv, errind, optstr, errchr, OPTERRNF));
+    }
+    if(cp[1] == ':')
+    {
+        dash = 0;
+        optind++;
+        if(optind == argc)
+            return(optiserr(argc, argv, optind-1, optstr, optchr, OPTERRARG));
+        optarg = argv[optind++];
+        return(*cp);
+    }
+    else
+    {
+        if(!argv[optind][optchr+1])
+        {
+            dash = 0;
+            optind++;
+        }
+        else
+            optchr++;
+        return(*cp);
+    }
+    assert(0);
+    return(0);
+}
+
+#ifdef TESTGETOPT
+int
+ main (int argc, char **argv)
+ {
+      int c;
+      extern char *optarg;
+      extern int optind;
+      int aflg = 0;
+      int bflg = 0;
+      int errflg = 0;
+      char *ofile = NULL;
+
+      while ((c = getopt(argc, argv, "abo:")) != EOF)
+           switch (c) {
+           case 'a':
+                if (bflg)
+                     errflg++;
+                else
+                     aflg++;
+                break;
+           case 'b':
+                if (aflg)
+                     errflg++;
+                else
+                     bflg++;
+                break;
+           case 'o':
+                ofile = optarg;
+                (void)printf("ofile = %s\n", ofile);
+                break;
+           case '?':
+                errflg++;
+           }
+      if (errflg) {
+           (void)fprintf(stderr,
+                "usage: cmd [-a|-b] [-o <filename>] files...\n");
+           exit (2);
+      }
+      for ( ; optind < argc; optind++)
+           (void)printf("%s\n", argv[optind]);
+      return 0;
+ }
+
+#endif /* TESTGETOPT */
+
+
+
+/**********************************************************************
+ * Implement dirent-style opendir/readdir/closedir on Window 95/NT
+ *
+ * Functions defined are opendir(), readdir() and closedir() with the
+ * same prototypes as the normal dirent.h implementation.
+ *
+ * Does not implement telldir(), seekdir(), rewinddir() or scandir(). 
+ * The dirent struct is compatible with Unix, except that d_ino is 
+ * always 1 and d_off is made up as we go along.
+ *
+ * The DIR typedef is not compatible with Unix.
+ **********************************************************************/
+
+DIR * opendir(const char *dir)
+{
+    DIR *dp;
+    char *filespec;
+    long handle;
+    int index;
+
+    filespec = (char *) malloc(strlen(dir) + 2 + 1);
+    strcpy(filespec, dir);
+    index = strlen(filespec) - 1;
+    if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\'))
+        filespec[index] = '\0';
+    strcat(filespec, "/*");
+
+    dp = (DIR *)malloc(sizeof(DIR));
+    dp->offset = 0;
+    dp->finished = 0;
+    dp->dir = _strdup(dir);
+
+    if ((handle = _findfirst(filespec, &(dp->fileinfo))) < 0) {
+        if (errno == ENOENT)
+            dp->finished = 1;
+        else
+        return NULL;
+    }
+
+    dp->handle = handle;
+    free(filespec);
+
+    return dp;
+}
+
+struct dirent * readdir(DIR *dp)
+{
+    if (!dp || dp->finished) return NULL;
+
+    if (dp->offset != 0) {
+        if (_findnext(dp->handle, &(dp->fileinfo)) < 0) {
+            dp->finished = 1;
+            return NULL;
+        }
+    }
+    dp->offset++;
+
+    strncpy(dp->dent.d_name, dp->fileinfo.name, _MAX_FNAME);
+    dp->dent.d_ino = 1;
+    dp->dent.d_reclen = strlen(dp->dent.d_name);
+    dp->dent.d_off = dp->offset;
+
+    return &(dp->dent);
+}
+
+int closedir(DIR *dp)
+{
+    if (!dp) return 0;
+    _findclose(dp->handle);
+    if (dp->dir) free(dp->dir);
+    if (dp) free(dp);
+
+    return 0;
+}
+
+#endif
Index: squid/src/access_log.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/access_log.c,v
retrieving revision 1.1.1.3.4.1.2.1
retrieving revision 1.1.1.3.4.1.2.2
diff -u -r1.1.1.3.4.1.2.1 -r1.1.1.3.4.1.2.2
--- squid/src/access_log.c	6 Jan 2001 12:40:11 -0000	1.1.1.3.4.1.2.1
+++ squid/src/access_log.c	14 Jun 2001 20:36:15 -0000	1.1.1.3.4.1.2.2
@@ -1,7 +1,7 @@
 
 
 /*
- * $Id: access_log.c,v 1.1.1.3.4.1.2.1 2001/01/06 12:40:11 hno Exp $
+ * $Id: access_log.c,v 1.1.1.3.4.1.2.2 2001/06/14 20:36:15 serassio Exp $
  *
  * DEBUG: section 46    Access Log
  * AUTHOR: Duane Wessels
Index: squid/src/asn.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/asn.c,v
retrieving revision 1.1.1.3.4.2.2.1
retrieving revision 1.1.1.3.4.2.2.2
diff -u -r1.1.1.3.4.2.2.1 -r1.1.1.3.4.2.2.2
--- squid/src/asn.c	6 Jan 2001 12:40:12 -0000	1.1.1.3.4.2.2.1
+++ squid/src/asn.c	14 Jun 2001 20:36:15 -0000	1.1.1.3.4.2.2.2
@@ -1,5 +1,5 @@
 /*
- * $Id: asn.c,v 1.1.1.3.4.2.2.1 2001/01/06 12:40:12 hno Exp $
+ * $Id: asn.c,v 1.1.1.3.4.2.2.2 2001/06/14 20:36:15 serassio Exp $
  *
  * DEBUG: section 53    AS Number handling
  * AUTHOR: Duane Wessels, Kostas Anagnostakis
@@ -407,7 +407,9 @@
 mask_len(int mask)
 {
     int len = 32;
-    while ((mask & 1) == 0) {
+    if (mask == 0)
+		return 0;
+	while ((mask & 1) == 0) {
 	len--;
 	mask >>= 1;
     }
Index: squid/src/cache_cf.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/cache_cf.c,v
retrieving revision 1.1.1.3.4.4.2.2
retrieving revision 1.1.1.3.4.4.2.3
diff -u -r1.1.1.3.4.4.2.2 -r1.1.1.3.4.4.2.3
--- squid/src/cache_cf.c	3 Jun 2001 19:41:47 -0000	1.1.1.3.4.4.2.2
+++ squid/src/cache_cf.c	14 Jun 2001 20:36:15 -0000	1.1.1.3.4.4.2.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: cache_cf.c,v 1.1.1.3.4.4.2.2 2001/06/03 19:41:47 serassio Exp $
+ * $Id: cache_cf.c,v 1.1.1.3.4.4.2.3 2001/06/14 20:36:15 serassio Exp $
  *
  * DEBUG: section 3     Configuration File Parsing
  * AUTHOR: Harvest Derived
Index: squid/src/defines.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/defines.h,v
retrieving revision 1.1.1.3.4.2.2.1
retrieving revision 1.1.1.3.4.2.2.2
diff -u -r1.1.1.3.4.2.2.1 -r1.1.1.3.4.2.2.2
--- squid/src/defines.h	6 Jan 2001 12:40:13 -0000	1.1.1.3.4.2.2.1
+++ squid/src/defines.h	14 Jun 2001 20:36:15 -0000	1.1.1.3.4.2.2.2
@@ -1,6 +1,6 @@
 
 /*
- * $Id: defines.h,v 1.1.1.3.4.2.2.1 2001/01/06 12:40:13 hno Exp $
+ * $Id: defines.h,v 1.1.1.3.4.2.2.2 2001/06/14 20:36:15 serassio Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -287,3 +287,33 @@
 #define NUMTHREADS 16
 #endif
 #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_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		"SquidNT2.3"
+#define _WIN_SQUID_SERVICE_OPTION		"--ntservice"
+#define _WIN_SQUID_RUN_MODE_INTERACTIVE		0
+#define _WIN_SQUID_RUN_MODE_SERVICE		1
+#ifdef _SQUID_MSWIN_
+#define	SIGHUP	1	/* hangup */
+#define	SIGKILL	9	/* kill (cannot be caught or ignored) */
+#define	SIGBUS	10	/* bus error */
+#define	SIGPIPE	13	/* write on a pipe with no one to read it */
+#define	SIGCHLD	20	/* to parent on child stop or exit */
+#define SIGUSR1 30	/* user defined signal 1 */
+#define SIGUSR2 31	/* user defined signal 2 */
+#endif
+#endif
Index: squid/src/disk.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/disk.c,v
retrieving revision 1.1.1.3.4.1.2.2
retrieving revision 1.1.1.3.4.1.2.3
diff -u -r1.1.1.3.4.1.2.2 -r1.1.1.3.4.1.2.3
--- squid/src/disk.c	25 Mar 2001 16:42:23 -0000	1.1.1.3.4.1.2.2
+++ squid/src/disk.c	14 Jun 2001 20:36:15 -0000	1.1.1.3.4.1.2.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: disk.c,v 1.1.1.3.4.1.2.2 2001/03/25 16:42:23 serassio Exp $
+ * $Id: disk.c,v 1.1.1.3.4.1.2.3 2001/06/14 20:36:15 serassio Exp $
  *
  * DEBUG: section 6     Disk I/O Routines
  * AUTHOR: Harvest Derived
@@ -70,8 +70,12 @@
 #ifdef _SQUID_MSWIN_ 
 	mode |= _O_BINARY;
     errno = 0;
-    if (mode & O_WRONLY)
-		strcpy(fmode,"a+b");
+    if (mode & O_WRONLY) {
+		if (mode & O_TRUNC)
+		    strcpy(fmode,"wb");
+		else
+    		strcpy(fmode,"a+b");
+	}
 	else
 		strcpy(fmode,"rb");
 	fbuf=fopen(path,fmode);
Index: squid/src/dns_internal.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/dns_internal.c,v
retrieving revision 1.1.1.1.4.6.2.1
retrieving revision 1.1.1.1.4.6.2.2
diff -u -r1.1.1.1.4.6.2.1 -r1.1.1.1.4.6.2.2
--- squid/src/dns_internal.c	6 Jan 2001 12:40:13 -0000	1.1.1.1.4.6.2.1
+++ squid/src/dns_internal.c	14 Jun 2001 20:36:15 -0000	1.1.1.1.4.6.2.2
@@ -1,6 +1,6 @@
 
 /*
- * $Id: dns_internal.c,v 1.1.1.1.4.6.2.1 2001/01/06 12:40:13 hno Exp $
+ * $Id: dns_internal.c,v 1.1.1.1.4.6.2.2 2001/06/14 20:36:15 serassio Exp $
  *
  * DEBUG: section 78    DNS lookups; interacts with lib/rfc1035.c
  * AUTHOR: Duane Wessels
@@ -36,6 +36,9 @@
 #define DNS_INTERNAL_C
 
 #include "squid.h"
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+#include <windows.h>
+#endif
 
 #if !USE_DNSSERVERS
 
@@ -85,6 +88,9 @@
 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);
@@ -144,78 +150,9 @@
 static void
 idnsParseResolvConf(void)
 {
-#ifndef _SQUID_MSWIN_
     FILE *fp;
     char buf[512];
-#endif
-	char *t;
-#ifdef _SQUID_MSWIN_
-    char *token;
-	HKEY hndKey,hndKey2;
-	
-	idnsFreeNameservers();
-	// get nameservers from the 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);
-		    	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);
-	}
-	// might be windows 2000 - search all interfaces for DNS server addresses
-	// what a goddamn PITA
-  	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,"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);
-	}
-#else 
+    char *t;
     fp = fopen(_PATH_RESOLV_CONF, "r");
     if (fp == NULL) {
 	debug(78, 1) ("%s: %s\n", _PATH_RESOLV_CONF, xstrerror());
@@ -234,9 +171,150 @@
 	idnsAddNameserver(t);
     }
     fclose(fp);
-#endif
 }
 
+#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)
 {
@@ -508,7 +586,7 @@
     if (DnsSocket < 0) {
 	DnsSocket = comm_open(SOCK_DGRAM,
 #ifdef _SQUID_MSWIN_
-		IPPROTO_UDP,
+	    IPPROTO_UDP,
 #else
 	    0,
 #endif
@@ -522,11 +600,21 @@
     }
     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);
Index: squid/src/globals.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/globals.h,v
retrieving revision 1.1.1.3.4.2.2.2
retrieving revision 1.1.1.3.4.2.2.3
diff -u -r1.1.1.3.4.2.2.2 -r1.1.1.3.4.2.2.3
--- squid/src/globals.h	25 Mar 2001 16:42:23 -0000	1.1.1.3.4.2.2.2
+++ squid/src/globals.h	14 Jun 2001 20:36:16 -0000	1.1.1.3.4.2.2.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: globals.h,v 1.1.1.3.4.2.2.2 2001/03/25 16:42:23 serassio Exp $
+ * $Id: globals.h,v 1.1.1.3.4.2.2.3 2001/06/14 20:36:16 serassio Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -157,3 +157,9 @@
 extern request_flags null_request_flags;
 extern int store_open_disk_fd;	/* 0 */
 extern const char *SwapDirType[];
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+extern unsigned int WIN32_OS_version;	/* 0 */
+extern char *WIN32_OS_string;
+extern char *WIN32_Service_name; /* NULL */
+extern unsigned int WIN32_run_mode;	/* _WIN_SQUID_RUN_MODE_INTERACTIVE */
+#endif
Index: squid/src/main.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/main.c,v
retrieving revision 1.1.1.3.4.2.2.3
retrieving revision 1.1.1.3.4.2.2.4
diff -u -r1.1.1.3.4.2.2.3 -r1.1.1.3.4.2.2.4
--- squid/src/main.c	3 Jun 2001 19:41:48 -0000	1.1.1.3.4.2.2.3
+++ squid/src/main.c	14 Jun 2001 20:36:16 -0000	1.1.1.3.4.2.2.4
@@ -1,11 +1,11 @@
 
 /*
- * $Id: main.c,v 1.1.1.3.4.2.2.3 2001/06/03 19:41:48 serassio Exp $
+ * $Id: main.c,v 1.1.1.3.4.2.2.4 2001/06/14 20:36:16 serassio Exp $
  *
  * DEBUG: section 1     Startup and Main Loop
  * AUTHOR: Harvest Derived
  *
- * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
  * ----------------------------------------------------------
  *
  *  Squid is the result of efforts by numerous individuals from the
@@ -35,11 +35,28 @@
 
 #include "squid.h"
 
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+#include <windows.h>
+#include <process.h>
+#ifdef _SQUID_MSWIN_
+#include <direct.h>
+#endif
+static int opt_install_service = FALSE;
+static int opt_remove_service = FALSE;
+static int opt_signal_service = 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 +70,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
@@ -73,22 +88,6 @@
 static void mainSetCwd(void);
 static int checkRunningPid(void);
 
-#ifdef _SQUID_MSWIN_
-#include <direct.h>
-#include <process.h>
-extern void Win32SockCleanup(void);
-static BOOL opt_install_service=FALSE;
-static BOOL opt_remove_service=FALSE;
-static BOOL opt_config_file=FALSE;
-static BOOL eventrunning=FALSE;
-static SERVICE_STATUS svcStatus;
-static SERVICE_STATUS_HANDLE svcHandle;
-#ifndef _DEBUG
-#define SERVICE
-#endif
-#else
-static void watch_child(char **);
-#endif
 #if TEST_ACCESS
 #include "test_access.c"
 #endif
@@ -97,36 +96,33 @@
 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]\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"
-#ifdef SERVICE
-    "       -f file   Set Windows NT Registry to use given config-file instead of\n"
-	"                 %s\n"
-#else
-	"       -f file   Use given config-file instead of\n"
-	"                 %s\n"
-#endif
 	"       -h        Print help message.\n"
-#ifdef SERVICE
-	"       -i        Installs the " SQUID_SERVICE_NAME " service.\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"
-#ifdef SERVICE
-	"       -r        Removes the " SQUID_SERVICE_NAME " service.\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
-#ifndef _SQUID_MSWIN_
 	"       -s        Enable logging to syslog.\n"
-#endif
 	"       -u port   Specify ICP port number (default: %d), disable with 0.\n"
 	"       -v        Print version.\n"
 	"       -z        Create swap directories\n"
 	"       -C        Do not catch fatal signals.\n"
 	"       -D        Disable initial DNS tests.\n"
 	"       -F        Don't serve any requests until store is rebuilt.\n"
-#ifndef _SQUID_MSWIN_
+#if !(defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)))
 	"       -N        No daemon mode.\n"
 #endif
 	"       -R        Do not set REUSEADDR on port.\n"
@@ -141,18 +137,12 @@
 mainParseOptions(int argc, char *argv[])
 {
 
-#ifdef _SQUID_MSWIN_
-	char *optarg;
-	char c;
-	int i=1;
-
-	while (i<argc){
-		optarg=argv[i],c=optarg[1],	optarg=argv[++i];
-		if (i<argc && strchr(optarg,'-')==NULL) i++;
-#else
     extern char *optarg;
     int c;
 
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+    while ((c = getopt(argc, argv, "CDFRSVYXa: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) {
@@ -165,7 +155,7 @@
 	case 'F':
 	    opt_foreground_rebuild = 1;
 	    break;
-#ifndef _SQUID_MSWIN_
+#if !(defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)))
 	case 'N':
 	    opt_no_daemon = 1;
 	    break;
@@ -193,18 +183,15 @@
 	    opt_debug_stderr = atoi(optarg);
 	    break;
 	case 'f':
-#ifdef SERVICE
-		opt_config_file=TRUE;
-#endif
-		xfree(ConfigFile);
+	    xfree(ConfigFile);
 	    ConfigFile = xstrdup(optarg);
 	    break;
 	case 'h':
 	    usage();
 	    break;
-#ifdef SERVICE
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
 	case 'i':
-	    opt_install_service=TRUE;
+	    opt_install_service = TRUE;
 	    break;
 #endif
 	case 'k':
@@ -254,16 +241,19 @@
 		fatal("Need to configure --enable-xmalloc-debug-trace to use -m option");
 #endif
 	    }
-#ifdef SERVICE
+#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
-#ifndef _SQUID_MSWIN_
 	case 's':
 	    opt_syslog_enable = 1;
 	    break;
-#endif
 	case 'u':
 	    icpPortNumOverride = atoi(optarg);
 	    if (icpPortNumOverride < 0)
@@ -271,6 +261,9 @@
 	    break;
 	case 'v':
 	    printf("Squid Cache: Version %s\n", version_string);
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+	    printf("Compiled as Windows System Service.\n");
+#endif
 	    exit(0);
 	    /* NOTREACHED */
 	case 'z':
@@ -285,7 +278,7 @@
 }
 
 /* ARGSUSED */
-static void
+void
 rotate_logs(int sig)
 {
     do_rotate = 1;
@@ -310,7 +303,7 @@
 #endif
 
 /* ARGSUSED */
-static void
+void
 reconfigure(int sig)
 {
     do_reconfigure = 1;
@@ -451,11 +444,10 @@
 static void
 setEffectiveUser(void)
 {
-#ifndef _SQUID_MSWIN_
     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");
@@ -463,7 +455,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 
+#endif
 }
 
 static void
@@ -498,11 +490,9 @@
 mainInitialize(void)
 {
     /* chroot if configured to run inside chroot */
-#ifndef _SQUID_MSWIN_
     if (Config.chroot_dir && chroot(Config.chroot_dir)) {
 	fatal("failed to chroot");
     }
-#endif
     if (opt_catch_signals) {
 	squid_signal(SIGSEGV, death, SA_NODEFER | SA_RESETHAND);
 	squid_signal(SIGBUS, death, SA_NODEFER | SA_RESETHAND);
@@ -516,16 +506,21 @@
 	Config.Sockaddr.http->s.sin_port = htons(httpPortNumOverride);
     if (icpPortNumOverride != 1)
 	Config.Port.icp = (u_short) icpPortNumOverride;
-#ifndef _DEBUG
+
     _db_init(Config.Log.log, Config.debugOptions);
     fd_open(fileno(debug_log), FD_LOG, Config.Log.log);
-#endif
 #if MEM_GEN_TRACE
     log_trace_init("/tmp/squid.alloc");
 #endif
     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);
+    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);
 
@@ -615,68 +610,9 @@
     configured_once = 1;
 }
 
-#ifdef SERVICE
-VOID WINAPI svcHandler (DWORD Opcode) 
-{ 
-    DWORD status; 
- 
-    switch(Opcode) 
-    { 
-        case SERVICE_CONTROL_STOP: 
-        case 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 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 SQUID_SERVICE_CONTROL_ROTATE:
-			rotate_logs(SIGUSR1);
-			break;
-		 case SQUID_SERVICE_CONTROL_RECONFIGURE:
-			reconfigure(SIGHUP);
-			break;
-		 case SQUID_SERVICE_CONTROL_DEBUG:
-			sigusr2_handle(SIGUSR2);
-			break;
-        case 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; 
-} 
-
+#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(DWORD argc, char **argv)
-
 #else
 int
 main(int argc, char **argv)
@@ -687,56 +623,24 @@
     time_t loop_delay;
     mode_t oldmask;
 	
-#ifdef SERVICE
-	TCHAR path[512];
-    HKEY hndKey;
-#endif
-	debug_log=stderr;
-#ifdef SERVICE
-	if (argc==1)
-	{
-		svcHandle=RegisterServiceCtrlHandler( SQUID_SERVICE_NAME, svcHandler); 
-		if(svcHandle==0) return;
-	}
-    GetModuleFileName(NULL, path, 512);
-	_strset(path+strlen(path)-9,0);
-	if (SetCurrentDirectory(path)==0) return;
-    xfree(ConfigFile);
-
-/* get config file from Windows Registry */
-	
-  	if (RegOpenKey(HKEY_LOCAL_MACHINE,"SOFTWARE\\GNU\\SquidNT\\2.3Stable4",&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);
- 	 	RegCloseKey(hndKey);
-	} else {
-		ConfigFile = xstrdup(DefaultConfigFile);
-	}
-
-	if (argc==1){
-    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); 
-	}
-#endif
-#ifndef _SQUID_MSWIN_ 
+    debug_log=stderr;
     if (FD_SETSIZE < Squid_MaxFD)
 	Squid_MaxFD = FD_SETSIZE;
+
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+#ifdef USE_WIN32_SERVICE
+    if (WIN32_Subsystem_Init())
+	return;
+/*    opt_no_daemon=(WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) ? 0 : 1; */
 #else
-	Squid_MaxFD = 20*SQUID_MAXFD;
+    {
+	int WIN32_init_err;	
+	if ((WIN32_init_err = WIN32_Subsystem_Init()))
+	    return WIN32_init_err;
+    }
 #endif
+#endif
+
    /* call mallopt() before anything else */
 #if HAVE_MALLOPT
 #ifdef M_GRAIN
@@ -759,11 +663,9 @@
      * set.  Unfortunately, there is no way to get the current
      * umask value without setting it.
      */
-#ifndef _SQUID_MSWIN_
     oldmask = umask(S_IRWXO);
     if (oldmask)
 	umask(oldmask);
-#endif
 
     memset(&local_addr, '\0', sizeof(struct in_addr));
     safe_inet_addr(localhost, &local_addr);
@@ -777,28 +679,20 @@
     squid_start = current_time;
     failure_notify = fatal_dump;
 
-#ifdef SERVICE
-	if (argc==1){
-	svcStatus.dwCheckPoint++; 
-	SetServiceStatus( svcHandle,&svcStatus); 
-	}
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+    WIN32_svcstatusupdate(SERVICE_START_PENDING);
 #endif
     mainParseOptions(argc, argv);
 
-#ifdef SERVICE
-	if(opt_install_service) {
-		InstallService();
-		if (!opt_config_file)
-			return;
-	}
-	if(opt_config_file) {
-	    store_key("ConfigFile", REG_SZ,(unsigned char*) ConfigFile, strlen(ConfigFile)+1);
-		return;
-	}
-	if(opt_remove_service) {
-		RemoveService();
-		return;
-	}
+#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;
+    }
 #endif
     /* parse configuration file
      * note: in "normal" case this used to be called from mainInitialize() */
@@ -813,23 +707,18 @@
 #endif
 	memInit();		/* memInit is required for config parsing */
 	eventInit();		/* eventInit() is required for config parsing */
-#ifdef _SQUID_MSWIN_
-	Win32SockInit();
-#endif
 	parse_err = parseConfigFile(ConfigFile);
 
 	if (opt_parse_cfg_only)
-#ifdef SERVICE	    
-		return ;
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+	    return;
 #else
-		return parse_err;
+	    return parse_err;
 #endif
     }
-#ifndef _SQUID_MSWIN_
     if (-1 == opt_send_signal)
 	if (checkRunningPid())
 	    exit(1);
-#endif
 
 #if TEST_ACCESS
     comm_init();
@@ -842,31 +731,26 @@
     /* send signal to running copy and exit */
     if (opt_send_signal != -1) {
 	/* chroot if configured to run inside chroot */
-#ifndef _SQUID_MSWIN_
 	if (Config.chroot_dir && chroot(Config.chroot_dir)) {
 	    fatal("failed to chroot");
 	}
-#endif
 	sendSignal();
 	/* NOTREACHED */
     }
     if (opt_create_swap_dirs) {
-#ifndef _SQUID_MSWIN_
 	/* chroot if configured to run inside chroot */
 	if (Config.chroot_dir && chroot(Config.chroot_dir)) {
 	    fatal("failed to chroot");
 	}
 	setEffectiveUser();
-#endif
 	debug(0, 0) ("Creating Swap Directories\n");
 	storeCreateSwapDirectories();
-#ifndef SERVICE
-	return 0;
-#else
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
 	return;
+#else
+	return 0;
 #endif
     }
-#ifndef _SQUID_MSWIN_
     if (!opt_no_daemon)
 	watch_child(argv);
     setMaxFD();
@@ -874,41 +758,24 @@
     if (opt_catch_signals)
 	for (n = Squid_MaxFD; n > 2; n--)
 	    close(n);
-#endif
 
     /* init comm module */
     comm_init();
     comm_select_init();
 
-#ifndef SERVICE
     if (opt_no_daemon) {
 	/* we have to init fdstat here. */
 	fd_open(0, FD_LOG, "stdin");
 	fd_open(1, FD_LOG, "stdout");
 	fd_open(2, FD_LOG, "stderr");
     }
-#else	
-	svcStatus.dwCheckPoint++; 
-	SetServiceStatus( svcHandle,&svcStatus); 
-#endif
-#ifdef _SQUID_MSWIN_
-#ifdef _DEBUG
-	for (n=0;n<MAX_DEBUG_SECTIONS;n++)
-		debugLevels[n]=1;
-#endif
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+    WIN32_svcstatusupdate(SERVICE_START_PENDING);
 #endif
 	mainInitialize();
 	
-#ifdef _SQUID_MSWIN_
-#ifdef SERVICE	
-	svcStatus.dwCheckPoint++; 
-	svcStatus.dwCurrentState=SERVICE_RUNNING; 
-	SetServiceStatus( svcHandle,&svcStatus); 
-#endif
-#ifdef _DEBUG
-	for (n=0;n<MAX_DEBUG_SECTIONS;n++)
-		debugLevels[n]=1;
-#endif
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+    WIN32_svcstatusupdate(SERVICE_RUNNING);
 #endif
 
     /* main loop */
@@ -928,9 +795,8 @@
 	    do_shutdown = 0;
 	    shutting_down = 1;
 	    serverConnectionsClose();
-#ifdef SERVICE
-		svcStatus.dwCheckPoint++; 
-		SetServiceStatus( svcHandle,&svcStatus); 
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+	    WIN32_svcstatusupdate(SERVICE_STOP_PENDING);
 #endif
 	    dnsShutdown();
 #if !USE_DNSSERVERS
@@ -940,17 +806,7 @@
 	    authenticateShutdown();
 	    eventAdd("SquidShutdown", SquidShutdown, NULL, (double) (wait + 1), 1);
 	}
-#ifdef _DEBUG
-	for (n=0;n<MAX_DEBUG_SECTIONS;n++)
-		debugLevels[n]=1;
-#endif
 	eventRun();
-
-#ifdef _DEBUG
-	for (n=0;n<MAX_DEBUG_SECTIONS;n++)
-		debugLevels[n]=3;
-	debugLevels[5]=5;
-#endif
 	if ((loop_delay = eventNextTime()) < 0)
 	    loop_delay = 0;
 #if HAVE_POLL
@@ -978,28 +834,25 @@
 	}
     }
     /* NOTREACHED */
-#ifndef SERVICE
-    return 0;
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+    return;
 #else
-	return;
+    return 0;
 #endif
 }
 
 static void
 sendSignal(void)
 {
-
     pid_t pid;
-#ifdef _SQUID_MSWIN_
-    SERVICE_STATUS ssStatus; 
-    DWORD fdwAccess, fdwControl; 
-    SC_HANDLE   schService;
-    SC_HANDLE   schSCManager;
-#endif
     debug_log = stderr;
     pid = readPidFile();
     if (pid > 1) {
-#ifndef _SQUID_MSWIN_
+#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)) {
@@ -1008,84 +861,8 @@
 		opt_send_signal, (int) pid, xstrerror());
 	    exit(1);
 	}
-#else
-	    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 (opt_send_signal) 
-		{ 
-			case 0: // SIGNULL
-				fdwAccess = SERVICE_INTERROGATE; 
-				fdwControl = SERVICE_CONTROL_INTERROGATE;
-				break; 
-			case SIGUSR1: 
-				fdwAccess = SERVICE_USER_DEFINED_CONTROL; 
-				fdwControl = SQUID_SERVICE_CONTROL_ROTATE;
-				break; 
-			case SIGUSR2: 
-				fdwAccess = SERVICE_USER_DEFINED_CONTROL; 
-				fdwControl = SQUID_SERVICE_CONTROL_DEBUG;
-				break; 
-			case SIGHUP: 
-				fdwAccess = SERVICE_USER_DEFINED_CONTROL; 
-				fdwControl = SQUID_SERVICE_CONTROL_RECONFIGURE;
-				break; 
-			case SIGTERM: 
-				fdwAccess = SERVICE_STOP; 
-				fdwControl = SERVICE_CONTROL_STOP;
-				break; 
-			case SIGINT: 
-			case SIGKILL: 
-				fdwAccess = SERVICE_USER_DEFINED_CONTROL; 
-				fdwControl = SQUID_SERVICE_CONTROL_INTERRUPT;
-				break; 
-			default:
-				exit(1);
-		} 
- 		// Open a handle to the service. 
- 		schService = OpenService( 
-			schSCManager,        // SCManager database 
-			SQUID_SERVICE_NAME,  // name of service 
-			fdwAccess);          // specify access 
-		if (schService == NULL)
-		{
-			fprintf(stderr, "%s: ERROR: Could not open Service %s\n", appname, SQUID_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, SQUID_SERVICE_NAME);
-				exit(1);
-			}
-			else
-			{
-				// Print the service status. 
- 				printf("\nStatus of %s Service:\n", SQUID_SERVICE_NAME);
-				printf("  Service Type: 0x%x\n", ssStatus.dwServiceType); 
-				printf("  Current State: 0x%x\n", ssStatus.dwCurrentState); 
-				printf("  Controls Accepted: 0x%x\n", ssStatus.dwControlsAccepted); 
-				printf("  Exit Code: %d\n", ssStatus.dwWin32ExitCode); 
-				printf("  Service Specific Exit Code: %d\n", ssStatus.dwServiceSpecificExitCode); 
-				printf("  Check Point: %d\n", ssStatus.dwCheckPoint); 
-				printf("  Wait Hint: %d\n", ssStatus.dwWaitHint); 
-			}
-			CloseServiceHandle(schService);
-		}
-		CloseServiceHandle(schSCManager);
+#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+	}
 #endif
     } else {
 	fprintf(stderr, "%s: ERROR: No running copy\n", appname);
@@ -1095,7 +872,6 @@
     exit(0);
 }
 
-#ifndef _SQUID_MSWIN_
 static int
 checkRunningPid(void)
 {
@@ -1113,6 +889,7 @@
 static void
 watch_child(char *argv[])
 {
+#ifndef _SQUID_MSWIN_
     char *prog;
     int failcount = 0;
     time_t start;
@@ -1188,18 +965,12 @@
 	sleep(3);
     }
     /* NOTREACHED */
-}
 #endif
+}
 
 static void
 SquidShutdown(void *unused)
 {
-#ifdef SERVICE
-	const char a[2][20]={"squid","stopped"};
-
-	svcStatus.dwCheckPoint++; 
-	SetServiceStatus( svcHandle,&svcStatus); 
-#endif
     debug(1, 1) ("Shutting down...\n");
     if (Config.pidFilename && strcmp(Config.pidFilename, "none")) {
 	enter_suid();
@@ -1270,42 +1041,9 @@
 	version_string);
     if (debug_log)
 	fclose(debug_log);
-#ifdef _SQUID_MSWIN_
-	ServiceExit(0);
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+    WIN32_Exit(0);
 #else
-	exit(0);
-#endif
-}
-
-#ifdef SERVICE
-#include<conio.h>
-int main(int argc, char **argv) {
-	SERVICE_TABLE_ENTRY   DispatchTable[] =     { 
-        { SQUID_SERVICE_NAME, SquidMain     }, 
-        { NULL,              NULL                }     
-	};  
-	if (argc>1) SquidMain(argc, argv);
-	else
-		if (!StartServiceCtrlDispatcher( DispatchTable))     
-        _cprintf(" StartServiceCtrlDispatcher error = %d\n", GetLastError());     
-}
-#endif
-
-#ifdef _SQUID_MSWIN_
-
-VOID ServiceExit(int ExitStatus)
-{
-	Win32SockCleanup();
-#ifdef SERVICE
-	if (ExitStatus)
-	{
-		svcStatus.dwWin32ExitCode=ERROR_SERVICE_SPECIFIC_ERROR;
-		svcStatus.dwServiceSpecificExitCode=1;
-	}
-	svcStatus.dwCurrentState=SERVICE_STOPPED; 
-	SetServiceStatus( svcHandle,&svcStatus); 
-//	ReportEvent(RegisterEventSource(NULL,NULL),EVENTLOG_INFORMATION_TYPE,0,1,NULL,1,0,(const char**)a,NULL);
-#endif
     exit(0);
-}
 #endif
+}
Index: squid/src/protos.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/protos.h,v
retrieving revision 1.1.1.3.4.1.2.3
retrieving revision 1.1.1.3.4.1.2.4
diff -u -r1.1.1.3.4.1.2.3 -r1.1.1.3.4.1.2.4
--- squid/src/protos.h	3 Jun 2001 19:41:48 -0000	1.1.1.3.4.1.2.3
+++ squid/src/protos.h	14 Jun 2001 20:36:16 -0000	1.1.1.3.4.1.2.4
@@ -1,6 +1,6 @@
 
 /*
- * $Id: protos.h,v 1.1.1.3.4.1.2.3 2001/06/03 19:41:48 serassio Exp $
+ * $Id: protos.h,v 1.1.1.3.4.1.2.4 2001/06/14 20:36:16 serassio Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -714,6 +714,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);
@@ -957,6 +959,8 @@
 extern void storeDirOpenSwapLogs(void);
 extern void storeDirSwapLog(const StoreEntry *, int op);
 extern void storeDirUpdateSwapSize(int fn, size_t size, int sign);
+extern int storeDirGetBlkSize(const char *path, int *blksize);
+extern int storeDirGetUFSStats(const char *, int *, int *, int *, int *);
 
 /*
  * store_dir_ufs.c
@@ -1223,11 +1227,20 @@
 extern int gethostname(char *, int);
 #endif
 
+/* CygWin & Windows NT Port */ 
+/* win32.c */ 
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+extern int WIN32_Subsystem_Init();
+extern void WIN32_sendSignal(int);
+extern void WIN32_Exit(int);
+extern void WIN32_InstallService(void);
+extern void WIN32_RemoveService(void);
+/* win32lib.c */
 #ifdef _SQUID_MSWIN_
-/* win32.c */
-VOID ServiceExit(int);
-void InstallService(void);
-void RemoveService(void);
-extern int store_key(const char *, DWORD, unsigned char *, int);
+extern int chroot (const char *);
+extern int kill(pid_t, int);
+extern void gettimeofday(struct timeval * ,void *);
+int statfs(const char *, struct statfs *);
+#endif
 #endif
 
--- squid/src/readdir.c	Wed Feb 14 00:53:43 2007
+++ /dev/null	Wed Feb 14 00:52:54 2007
@@ -1,81 +0,0 @@
-
-#include <malloc.h>
-#include <string.h>
-#include <errno.h>
-#define strdup _strdup
-#include "readdir.h"
-
-/**********************************************************************
- * Implement dirent-style opendir/readdir/closedir on Window 95/NT
- *
- * Functions defined are opendir(), readdir() and closedir() with the
- * same prototypes as the normal dirent.h implementation.
- *
- * Does not implement telldir(), seekdir(), rewinddir() or scandir(). 
- * The dirent struct is compatible with Unix, except that d_ino is 
- * always 1 and d_off is made up as we go along.
- *
- * The DIR typedef is not compatible with Unix.
- **********************************************************************/
-
-DIR * opendir(const char *dir)
-{
-    DIR *dp;
-    char *filespec;
-    long handle;
-    int index;
-
-    filespec = malloc(strlen(dir) + 2 + 1);
-    strcpy(filespec, dir);
-    index = strlen(filespec) - 1;
-    if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\'))
-        filespec[index] = '\0';
-    strcat(filespec, "/*");
-
-    dp = (DIR *)malloc(sizeof(DIR));
-    dp->offset = 0;
-    dp->finished = 0;
-    dp->dir = strdup(dir);
-
-    if ((handle = _findfirst(filespec, &(dp->fileinfo))) < 0) {
-        if (errno == ENOENT)
-            dp->finished = 1;
-        else
-        return NULL;
-    }
-
-    dp->handle = handle;
-    free(filespec);
-
-    return dp;
-}
-
-struct dirent * readdir(DIR *dp)
-{
-    if (!dp || dp->finished) return NULL;
-
-    if (dp->offset != 0) {
-        if (_findnext(dp->handle, &(dp->fileinfo)) < 0) {
-            dp->finished = 1;
-            return NULL;
-        }
-    }
-    dp->offset++;
-
-    strncpy(dp->dent.d_name, dp->fileinfo.name, _MAX_FNAME);
-    dp->dent.d_ino = 1;
-    dp->dent.d_reclen = strlen(dp->dent.d_name);
-    dp->dent.d_off = dp->offset;
-
-    return &(dp->dent);
-}
-
-int closedir(DIR *dp)
-{
-    if (!dp) return 0;
-    _findclose(dp->handle);
-    if (dp->dir) free(dp->dir);
-    if (dp) free(dp);
-
-    return 0;
-}
Index: squid/src/squid.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/squid.h,v
retrieving revision 1.1.1.3.4.1.2.2
retrieving revision 1.1.1.3.4.1.2.3
diff -u -r1.1.1.3.4.1.2.2 -r1.1.1.3.4.1.2.3
--- squid/src/squid.h	3 Jun 2001 19:41:48 -0000	1.1.1.3.4.1.2.2
+++ squid/src/squid.h	14 Jun 2001 20:36:16 -0000	1.1.1.3.4.1.2.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: squid.h,v 1.1.1.3.4.1.2.2 2001/06/03 19:41:48 serassio Exp $
+ * $Id: squid.h,v 1.1.1.3.4.1.2.3 2001/06/14 20:36:16 serassio Exp $
  *
  * AUTHOR: Duane Wessels
  *
@@ -435,14 +435,4 @@
 #define SWAP_DIR_SHIFT 24
 #define SWAP_FILE_MASK 0x00FFFFFF
 
-#ifdef _SQUID_MSWIN_
-/* Some tricks for MS Compilers */
-#define SQUID_SERVICE_CONTROL_ROTATE		128
-#define SQUID_SERVICE_CONTROL_RECONFIGURE	129
-#define SQUID_SERVICE_CONTROL_DEBUG			130
-#define SQUID_SERVICE_CONTROL_INTERRUPT     131
-#define SQUID_SERVICE_NAME			"SquidNT2.3Stable4 beta"
-#include "psapi.h"
-#endif
-
 #endif /* SQUID_H */
Index: squid/src/store.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/store.c,v
retrieving revision 1.1.1.3.4.5.2.2
retrieving revision 1.1.1.3.4.5.2.3
diff -u -r1.1.1.3.4.5.2.2 -r1.1.1.3.4.5.2.3
--- squid/src/store.c	3 Jun 2001 19:41:48 -0000	1.1.1.3.4.5.2.2
+++ squid/src/store.c	14 Jun 2001 20:36:16 -0000	1.1.1.3.4.5.2.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store.c,v 1.1.1.3.4.5.2.2 2001/06/03 19:41:48 serassio Exp $
+ * $Id: store.c,v 1.1.1.3.4.5.2.3 2001/06/14 20:36:16 serassio Exp $
  *
  * DEBUG: section 20    Storage Manager
  * AUTHOR: Harvest Derived
Index: squid/src/store_dir.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/store_dir.c,v
retrieving revision 1.1.1.3.4.2.2.2
retrieving revision 1.1.1.3.4.2.2.3
diff -u -r1.1.1.3.4.2.2.2 -r1.1.1.3.4.2.2.3
--- squid/src/store_dir.c	3 Jun 2001 19:41:49 -0000	1.1.1.3.4.2.2.2
+++ squid/src/store_dir.c	14 Jun 2001 20:36:16 -0000	1.1.1.3.4.2.2.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_dir.c,v 1.1.1.3.4.2.2.2 2001/06/03 19:41:49 serassio Exp $
+ * $Id: store_dir.c,v 1.1.1.3.4.2.2.3 2001/06/14 20:36:16 serassio Exp $
  *
  * DEBUG: section 47    Store Directory Routines
  * AUTHOR: Duane Wessels
@@ -35,6 +35,11 @@
 #define STORE_DIR_C
 #include "squid.h"
 
+/* Windows uses sys/vfs.h */
+#if HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#endif
+
 const char *SwapDirType[] =
 {
     "ufs",
@@ -278,8 +283,10 @@
 void
 storeDirUpdateSwapSize(int fn, size_t size, int sign)
 {
-    int dirn = (fn >> SWAP_DIR_SHIFT) % Config.cacheSwap.n_configured;
-    int k = ((size + 1023) >> 10) * sign;
+	int dirn = (fn >> SWAP_DIR_SHIFT) % Config.cacheSwap.n_configured;
+    SwapDir *sd = &Config.cacheSwap.swapDirs[dirn];
+	int blks = (size + sd->fs.blksize - 1) / sd->fs.blksize;
+	int k = (blks * sd->fs.blksize >> 10) * sign;
     Config.cacheSwap.swapDirs[dirn].cur_size += k;
     store_swap_size += k;
     if (sign > 0)
@@ -453,4 +460,55 @@
     return n;
 }
 #undef CLEAN_BUF_SZ
+
+int
+storeDirGetBlkSize(const char *path, int *blksize)
+{
+#if HAVE_STATVFS
+    struct statvfs sfs;
+    if (statvfs(path, &sfs)) {
+	debug(50, 1) ("%s: %s\n", path, xstrerror());
+	return 1;
+    }
+    *blksize = (int) sfs.f_frsize;
+#else
+    struct statfs sfs;
+    if (statfs(path, &sfs)) {
+	debug(50, 1) ("%s: %s\n", path, xstrerror());
+	return 1;
+    }
+    *blksize = (int) sfs.f_bsize;
+#endif
+    return 0;
+}
+
+#define fsbtoblk(num, fsbs, bs) \
+    (((fsbs) != 0 && (fsbs) < (bs)) ? \
+            (num) / ((bs) / (fsbs)) : (num) * ((fsbs) / (bs)))
+int
+storeDirGetUFSStats(const char *path, int *totl_kb, int *free_kb, int *totl_in, int *free_in)
+{
+#if HAVE_STATVFS
+    struct statvfs sfs;
+    if (statvfs(path, &sfs)) {
+	debug(50, 1) ("%s: %s\n", path, xstrerror());
+	return 1;
+    }
+    *totl_kb = (int) fsbtoblk(sfs.f_blocks, sfs.f_frsize, 1024);
+    *free_kb = (int) fsbtoblk(sfs.f_bfree, sfs.f_frsize, 1024);
+    *totl_in = (int) sfs.f_files;
+    *free_in = (int) sfs.f_ffree;
+#else
+    struct statfs sfs;
+    if (statfs(path, &sfs)) {
+	debug(50, 1) ("%s: %s\n", path, xstrerror());
+	return 1;
+    }
+    *totl_kb = (int) fsbtoblk(sfs.f_blocks, sfs.f_bsize, 1024);
+    *free_kb = (int) fsbtoblk(sfs.f_bfree, sfs.f_bsize, 1024);
+    *totl_in = (int) sfs.f_files;
+    *free_in = (int) sfs.f_ffree;
+#endif
+    return 0;
+}
 #undef STORE_DIR_C
\ No newline at end of file
Index: squid/src/store_dir_ufs.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/Attic/store_dir_ufs.c,v
retrieving revision 1.1.1.1.4.1.2.2
retrieving revision 1.1.1.1.4.1.2.3
diff -u -r1.1.1.1.4.1.2.2 -r1.1.1.1.4.1.2.3
--- squid/src/store_dir_ufs.c	3 Jun 2001 19:41:49 -0000	1.1.1.1.4.1.2.2
+++ squid/src/store_dir_ufs.c	14 Jun 2001 20:36:16 -0000	1.1.1.1.4.1.2.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_dir_ufs.c,v 1.1.1.1.4.1.2.2 2001/06/03 19:41:49 serassio Exp $
+ * $Id: store_dir_ufs.c,v 1.1.1.1.4.1.2.3 2001/06/14 20:36:16 serassio Exp $
  *
  * DEBUG: section 47    Store Directory Routines
  * AUTHOR: Duane Wessels
@@ -264,6 +264,7 @@
     if (!started_clean_event) {
 	eventAdd("storeDirClean", storeUfsDirCleanEvent, NULL, 15.0, 1);
 	started_clean_event = 1;
+    (void) storeDirGetBlkSize(sd->path, &sd->fs.blksize);
     }
 }
 
@@ -790,6 +791,7 @@
     }
     sd->u.ufs.swaplog_fd = fd;
     /* open a read-only stream of the old log */
+    fp = fopen(swaplog_path, "r");
     if (fp == NULL) {
 	debug(50, 0) ("%s: %s\n", swaplog_path, xstrerror());
 	fatal("Failed to open swap log for reading");
@@ -1157,14 +1159,19 @@
 {
     int i;
     SwapDir *SD;
-#if HAVE_STATVFS
-    struct statvfs sfs;
-#endif
+    int totl_kb = 0;
+    int free_kb = 0;
+    int totl_in = 0;
+    int free_in = 0;
+    int x;
+
     for (i = 0; i < Config.cacheSwap.n_configured; i++) {
 	SD = &Config.cacheSwap.swapDirs[i];
 	storeAppendPrintf(sentry, "\n");
 	storeAppendPrintf(sentry, "Store Directory #%d: %s\n", i, SD->path);
-	storeAppendPrintf(sentry, "First level subdirectories: %d\n", SD->u.ufs.l1);
+	storeAppendPrintf(sentry, "FS Block Size %d Bytes\n",
+	    SD->fs.blksize);
+    storeAppendPrintf(sentry, "First level subdirectories: %d\n", SD->u.ufs.l1);
 	storeAppendPrintf(sentry, "Second level subdirectories: %d\n", SD->u.ufs.l2);
 	storeAppendPrintf(sentry, "Maximum Size: %d KB\n", SD->max_size);
 	storeAppendPrintf(sentry, "Current Size: %d KB\n", SD->cur_size);
@@ -1173,20 +1180,17 @@
 	storeAppendPrintf(sentry, "Filemap bits in use: %d of %d (%d%%)\n",
 	    SD->map->n_files_in_map, SD->map->max_n_files,
 	    percent(SD->map->n_files_in_map, SD->map->max_n_files));
-#if HAVE_STATVFS
-#define fsbtoblk(num, fsbs, bs) \
-        (((fsbs) != 0 && (fsbs) < (bs)) ? \
-                (num) / ((bs) / (fsbs)) : (num) * ((fsbs) / (bs)))
-	if (!statvfs(SD->path, &sfs)) {
-	    storeAppendPrintf(sentry, "Filesystem Space in use: %d/%d KB (%d%%)\n",
-		fsbtoblk((sfs.f_blocks - sfs.f_bfree), sfs.f_frsize, 1024),
-		fsbtoblk(sfs.f_blocks, sfs.f_frsize, 1024),
-		percent(sfs.f_blocks - sfs.f_bfree, sfs.f_blocks));
-	    storeAppendPrintf(sentry, "Filesystem Inodes in use: %d/%d (%d%%)\n",
-		sfs.f_files - sfs.f_ffree, sfs.f_files,
-		percent(sfs.f_files - sfs.f_ffree, sfs.f_files));
-	}
-#endif
+    x = storeDirGetUFSStats(SD->path, &totl_kb, &free_kb, &totl_in, &free_in);
+    if (0 == x) {
+	storeAppendPrintf(sentry, "Filesystem Space in use: %d/%d KB (%d%%)\n",
+	    totl_kb - free_kb,
+	    totl_kb,
+	    percent(totl_kb - free_kb, totl_kb));
+	storeAppendPrintf(sentry, "Filesystem Inodes in use: %d/%d (%d%%)\n",
+	    totl_in - free_in,
+	    totl_in,
+	    percent(totl_in - free_in, totl_in));
+    }
 	storeAppendPrintf(sentry, "Flags:");
 	if (SD->flags.selected)
 	    storeAppendPrintf(sentry, " SELECTED");
--- squid/src/string-arrays.c	Wed Feb 14 00:53:43 2007
+++ /dev/null	Wed Feb 14 00:52:54 2007
@@ -1,80 +0,0 @@
-const char *err_type_str[] = 
-{
-	"ERR_NONE",
-	"ERR_READ_TIMEOUT",
-	"ERR_LIFETIME_EXP",
-	"ERR_READ_ERROR",
-	"ERR_WRITE_ERROR",
-	"ERR_SHUTTING_DOWN",
-	"ERR_CONNECT_FAIL",
-	"ERR_INVALID_REQ",
-	"ERR_UNSUP_REQ",
-	"ERR_INVALID_URL",
-	"ERR_SOCKET_FAILURE",
-	"ERR_DNS_FAIL",
-	"ERR_CANNOT_FORWARD",
-	"ERR_FORWARDING_DENIED",
-	"ERR_NO_RELAY",
-	"ERR_ZERO_SIZE_OBJECT",
-	"ERR_FTP_DISABLED",
-	"ERR_FTP_FAILURE",
-	"ERR_URN_RESOLVE",
-	"ERR_ACCESS_DENIED",
-	"ERR_CACHE_ACCESS_DENIED",
-	"ERR_CACHE_MGR_ACCESS_DENIED",
-	"ERR_SQUID_SIGNATURE",
-	"ERR_FTP_PUT_CREATED",
-	"ERR_FTP_PUT_MODIFIED",
-	"ERR_FTP_PUT_ERROR",
-	"ERR_FTP_NOT_FOUND",
-	"ERR_FTP_FORBIDDEN",
-	"ERR_FTP_UNAVAILABLE",
-	"ERR_ONLY_IF_CACHED_MISS",
-	"ERR_TOO_BIG",
-	"ERR_MAX"
-};
-
-const char *lookup_t_str[] = 
-{
-	"LOOKUP_NONE",
-	"LOOKUP_HIT",
-	"LOOKUP_MISS"
-};
-
-const char *icp_opcode_str[] = 
-{
-	"ICP_INVALID",
-	"ICP_QUERY",
-	"ICP_HIT",
-	"ICP_MISS",
-	"ICP_ERR",
-	"ICP_SEND",
-	"ICP_SENDA",
-	"ICP_DATABEG",
-	"ICP_DATA",
-	"ICP_DATAEND",
-	"ICP_SECHO",
-	"ICP_DECHO",
-	"ICP_NOTIFY",
-	"ICP_INVALIDATE",
-	"ICP_DELETE",
-	"ICP_UNUSED15",
-	"ICP_UNUSED16",
-	"ICP_UNUSED17",
-	"ICP_UNUSED18",
-	"ICP_UNUSED19",
-	"ICP_UNUSED20",
-	"ICP_MISS_NOFETCH",
-	"ICP_DENIED",
-	"ICP_HIT_OBJ",
-	"ICP_END"
-};
-
-const char *swap_log_op_str[] = 
-{
-	"SWAP_LOG_NOP",
-	"SWAP_LOG_ADD",
-	"SWAP_LOG_DEL",
-	"SWAP_LOG_MAX"
-};
-
Index: squid/src/structs.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/structs.h,v
retrieving revision 1.1.1.3.4.2.2.2
retrieving revision 1.1.1.3.4.2.2.3
diff -u -r1.1.1.3.4.2.2.2 -r1.1.1.3.4.2.2.3
--- squid/src/structs.h	3 Jun 2001 19:41:49 -0000	1.1.1.3.4.2.2.2
+++ squid/src/structs.h	14 Jun 2001 20:36:16 -0000	1.1.1.3.4.2.2.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: structs.h,v 1.1.1.3.4.2.2.2 2001/06/03 19:41:49 serassio Exp $
+ * $Id: structs.h,v 1.1.1.3.4.2.2.3 2001/06/14 20:36:16 serassio Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -601,6 +601,18 @@
     CommWriteStateData *rwstate;	/* State data for comm_write */
 };
 
+struct statfs {
+   long    f_type;     /* type of filesystem (see below) */
+   long    f_bsize;    /* optimal transfer block size */
+   long    f_blocks;   /* total data blocks in file system */
+   long    f_bfree;    /* free blocks in fs */
+   long    f_bavail;   /* free blocks avail to non-superuser */
+   long    f_files;    /* total file nodes in file system */
+   long    f_ffree;    /* free file nodes in fs */
+   long    f_fsid;     /* file system id */
+   long    f_namelen;  /* maximum length of filenames */
+   long    f_spare[6]; /* spare for later */
+};
 #endif
 
 
@@ -1394,6 +1406,9 @@
 	    void *state;
 	} clean;
     } log;
+    struct {
+	int blksize;
+    } fs;
     union {
 	struct {
 	    int l1;
Index: squid/src/tools.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/tools.c,v
retrieving revision 1.1.1.3.4.1.2.3
retrieving revision 1.1.1.3.4.1.2.4
diff -u -r1.1.1.3.4.1.2.3 -r1.1.1.3.4.1.2.4
--- squid/src/tools.c	3 Jun 2001 19:41:49 -0000	1.1.1.3.4.1.2.3
+++ squid/src/tools.c	14 Jun 2001 20:36:16 -0000	1.1.1.3.4.1.2.4
@@ -1,6 +1,6 @@
 
 /*
- * $Id: tools.c,v 1.1.1.3.4.1.2.3 2001/06/03 19:41:49 serassio Exp $
+ * $Id: tools.c,v 1.1.1.3.4.1.2.4 2001/06/14 20:36:16 serassio Exp $
  *
  * DEBUG: section 21    Misc Functions
  * AUTHOR: Harvest Derived
@@ -34,10 +34,15 @@
  */
 
 #include "squid.h"
-#ifdef _SQUID_MSWIN_
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+#include <windows.h>
+#include <psapi.h>
 #include <process.h>
+#ifdef _SQUID_MSWIN_
 #include <sys/timeb.h>
 #endif
+#endif
+
 #define DEAD_MSG "\
 The Squid Cache (version %s) died.\n\
 \n\
@@ -176,41 +181,49 @@
 void
 squid_getrusage(struct rusage *r)
 {
-#ifdef _SQUID_MSWIN_
-    HANDLE hProcess;
-    PROCESS_MEMORY_COUNTERS pmc;
-	FILETIME ftCreate, ftExit, ftKernel, ftUser;
-#endif
     memset(r, '\0', sizeof(struct rusage));
-#ifdef _SQUID_MSWIN_
-    hProcess = OpenProcess(  PROCESS_QUERY_INFORMATION |
-                                    PROCESS_VM_READ,
-                                    FALSE, GetCurrentProcessId() );
-
-    if ( GetProcessTimes( hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser))
-	{
-        LONGLONG tUser64 = *(LONGLONG *)&ftUser;
-        LONGLONG tKernel64 = *(LONGLONG *)&ftKernel;
-		r->ru_utime.tv_usec =(DWORD)(tUser64 / 10);
-		r->ru_stime.tv_usec =(DWORD)(tKernel64 / 10);
-	}
-
-    if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
-    {
-		r->ru_maxrss=(DWORD)(pmc.WorkingSetSize /1024);
-		r->ru_majflt=pmc.PageFaultCount;
-	}
-	CloseHandle( hProcess );
-#else
-#if HAVE_GETRUSAGE && defined(RUSAGE_SELF)
+#if (HAVE_GETRUSAGE && defined(RUSAGE_SELF)) || defined(_SQUID_MSWIN_)
 #ifdef _SQUID_SOLARIS_
     /* Solaris 2.5 has getrusage() permission bug -- Arjan de Vet */
     enter_suid();
 #endif
+#ifndef _SQUID_MSWIN_
     getrusage(RUSAGE_SELF, r);
+#endif
 #ifdef _SQUID_SOLARIS_
     leave_suid();
 #endif
+#if HAVE_WIN32_PSAPI && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))
+    if ((WIN32_OS_version == _WIN_OS_WINNT) || (WIN32_OS_version == _WIN_OS_WIN2K))
+    {
+    	/* On Windows NT/2000 call PSAPI.DLL for process Memory */
+    	/* informations -- Guido Serassio                       */
+    	HANDLE hProcess;
+    	PROCESS_MEMORY_COUNTERS pmc;
+	hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
+	    PROCESS_VM_READ,
+	    FALSE, GetCurrentProcessId());
+#if defined (_SQUID_MSWIN_)
+	{
+	/* Microsoft Visual C++ doesn't have getrusage function,  */
+	/* so we get process CPU time information from PSAPI.DLL. */
+	    FILETIME ftCreate, ftExit, ftKernel, ftUser;
+	    if (GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser))
+	    {
+	    	LONGLONG tUser64 = *(LONGLONG *)&ftUser;
+		LONGLONG tKernel64 = *(LONGLONG *)&ftKernel;
+		r->ru_utime.tv_usec =(DWORD)(tUser64 / 10);
+		r->ru_stime.tv_usec =(DWORD)(tKernel64 / 10);
+	    }
+	}
+#endif
+	if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
+	{
+	    r->ru_maxrss=(DWORD)(pmc.WorkingSetSize /1024);
+	    r->ru_majflt=pmc.PageFaultCount;
+	}
+	CloseHandle( hProcess );
+    }
 #endif
 #endif
 }
@@ -378,8 +391,8 @@
     if (0 == store_dirs_rebuilding)
 	storeDirWriteCleanLogs(0);
     fatal_common(message);
-#ifdef _SQUID_MSWIN_
-		ServiceExit(shutting_down ? 0 : 1);
+#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)
+    WIN32_Exit(shutting_down ? 0 : 1);
 #else
     exit(shutting_down ? 0 : 1);
 #endif
@@ -569,8 +582,8 @@
 void
 enter_suid(void)
 {
-#ifndef _SQUID_MSWIN_
     debug(21, 3) ("enter_suid: PID %d taking root priveleges\n", getpid());
+#ifndef _SQUID_MSWIN_
 #if HAVE_SETRESUID
     setresuid(-1, 0, -1);
 #else
@@ -721,15 +734,6 @@
 #endif /* RLIMIT_VMEM */
 }
 
-#ifdef _SQUID_MSWIN_
-void gettimeofday( struct timeval * pcur_time,void * tz){
-	struct _timeb current;
-	_ftime(&current);
-	pcur_time->tv_sec=current.time;
-	pcur_time->tv_usec=current.millitm * 1000;
-}
-#endif
-
 time_t
 getCurrentTime(void)
 {
Index: squid/src/typedefs.h
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/typedefs.h,v
retrieving revision 1.1.1.3.4.1.2.2
retrieving revision 1.1.1.3.4.1.2.3
diff -u -r1.1.1.3.4.1.2.2 -r1.1.1.3.4.1.2.3
--- squid/src/typedefs.h	3 Jun 2001 19:41:49 -0000	1.1.1.3.4.1.2.2
+++ squid/src/typedefs.h	14 Jun 2001 20:36:16 -0000	1.1.1.3.4.1.2.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: typedefs.h,v 1.1.1.3.4.1.2.2 2001/06/03 19:41:49 serassio Exp $
+ * $Id: typedefs.h,v 1.1.1.3.4.1.2.3 2001/06/14 20:36:16 serassio Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
Index: squid/src/url.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/url.c,v
retrieving revision 1.1.1.3.4.4.2.1
retrieving revision 1.1.1.3.4.4.2.2
diff -u -r1.1.1.3.4.4.2.1 -r1.1.1.3.4.4.2.2
--- squid/src/url.c	6 Jan 2001 12:40:17 -0000	1.1.1.3.4.4.2.1
+++ squid/src/url.c	14 Jun 2001 20:36:16 -0000	1.1.1.3.4.4.2.2
@@ -1,6 +1,6 @@
 
 /*
- * $Id: url.c,v 1.1.1.3.4.4.2.1 2001/01/06 12:40:17 hno Exp $
+ * $Id: url.c,v 1.1.1.3.4.4.2.2 2001/06/14 20:36:16 serassio Exp $
  *
  * DEBUG: section 23    URL Parsing
  * AUTHOR: Duane Wessels
@@ -278,7 +278,7 @@
 	host[l] = '\0';
     /* remove duplicate dots */
     while ((t = strstr(host, "..")))
-	xmemmove(t, t + 1, strlen(t));
+	    xmemmove(t, t + 1, strlen(t));
     if (Config.appendDomain && !strchr(host, '.'))
 	strncat(host, Config.appendDomain, SQUIDHOSTNAMELEN);
     if (port == 0) {
Index: squid/src/useragent.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/useragent.c,v
retrieving revision 1.1.1.3.4.1.2.2
retrieving revision 1.1.1.3.4.1.2.3
diff -u -r1.1.1.3.4.1.2.2 -r1.1.1.3.4.1.2.3
--- squid/src/useragent.c	3 Jun 2001 19:41:49 -0000	1.1.1.3.4.1.2.2
+++ squid/src/useragent.c	14 Jun 2001 20:36:16 -0000	1.1.1.3.4.1.2.3
@@ -1,6 +1,6 @@
 
 /*
- * $Id: useragent.c,v 1.1.1.3.4.1.2.2 2001/06/03 19:41:49 serassio Exp $
+ * $Id: useragent.c,v 1.1.1.3.4.1.2.3 2001/06/14 20:36:16 serassio Exp $
  *
  * DEBUG: section 40    User-Agent logging
  * AUTHOR: Joe Ramey <ramey@csc.ti.com>
Index: squid/src/win32.c
===================================================================
RCS file: /cvsroot/squid-sf//squid/src/win32.c,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -r1.1.2.2 -r1.1.2.3
--- squid/src/win32.c	25 Mar 2001 16:42:23 -0000	1.1.2.2
+++ squid/src/win32.c	14 Jun 2001 20:36:16 -0000	1.1.2.3
@@ -1,18 +1,65 @@
+/*
+ * $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"
 
-static int s_iInitCount = 0;
+/* 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);
+void WINAPI WIN32_svcHandler(DWORD);
+static int WIN32_StoreKey(const char *, DWORD, unsigned char *, int);
+static int WIN32_create_key(void);
+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;
+
 #define VENDOR   "GNU"
+#if defined(_SQUID_MSWIN_)
 #define SOFTWARE "SquidNT"
-#define VERSION  "2.3Stable4"
+#else
+#define SOFTWARE "Squid"
+#endif
+#define VERSION  "2.3-STABLE-4"
 #define REGKEY "SOFTWARE\\" VENDOR "\\" SOFTWARE "\\" VERSION
-TCHAR servname[512]=SQUID_SERVICE_NAME;
 
-SERVICE_STATUS svcStatus;
+/* ====================================================================== */
+/* LOCAL FUNCTIONS */
+/* ====================================================================== */
 
-int create_key(void)
+static int
+WIN32_create_key(void)
 {
-    static char *keys[] = 
-    { "SOFTWARE",
+    static char *keys[] = { "SOFTWARE",
 	VENDOR,
 	SOFTWARE,
 	VERSION,
@@ -31,225 +78,505 @@
     /* 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);
+	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],rv);
+	    debug(1, 1) ("RegCreateKeyEx(%s),%d\n", keys[index], rv);
 	    retval = -4;
 	}
-
 	/* Close the old key */
 	rv = RegCloseKey(hKey);
 	if (rv != ERROR_SUCCESS) {
-	    debug(1,1)("RegCloseKey %d\n", rv);
+	    debug(1, 1) ("RegCloseKey %d\n", rv);
 	    if (retval == 0) {
 		/* Keep error status from RegCreateKeyEx, if any */
-		retval = -4;  
+		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", rv);
+	    debug(1, 1) ("RegCloseKey %d\n", rv);
 	    if (retval == 0) {
 		/* Keep error status from RegCreateKeyEx, if any */
-		retval = -4;  
+		retval = -4;
 	    }
 	}
     }
-
     return retval;
 }
 
-int store_key(const char *key, DWORD type, unsigned char *value, int value_size)
+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);
-
+    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 (create_key() < 0) {
+	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);
-
+	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 );
+	    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,rv);
+	debug(1, 1) ("RegOpenKeyEx HKLM\\%s, %d\n", REGKEY, 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 */
-
+    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,rv);
+	debug(1, 1) ("RegQueryValueEx(key %s),%d\n", key, 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)");
     }
-    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,rv);
+	debug(1, 1) ("RegCloseKey HKLM\\%s, %d\n", REGKEY, rv);
 	if (retval == 0) {
 	    /* Keep error status from RegQueryValueEx, if any */
-	    retval = -4;  
+	    retval = -4;
 	}
     }
-
     return retval;
 }
 
-void RemoveService()
+static unsigned int
+GetOSVersion()
 {
-    SC_HANDLE   schService;
-    SC_HANDLE   schSCManager;
-    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, servname, SERVICE_ALL_ACCESS);
+    OSVERSIONINFO osvi;
+
+    xfree(WIN32_OS_string);
+    memset(&osvi, '\0', sizeof(OSVERSIONINFO));
+    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+    GetVersionEx((OSVERSIONINFO *) & osvi);
+    switch (osvi.dwPlatformId) {
+    case VER_PLATFORM_WIN32_NT:
+	if (osvi.dwMajorVersion <= 4) {
+	    WIN32_OS_string=xstrdup("Windows NT");
+	    return _WIN_OS_WINNT;
+	}
+	if (osvi.dwMajorVersion == 5) {
+	    WIN32_OS_string=xstrdup("Windows 2000");
+	    return _WIN_OS_WIN2K;
+	}
+	break;
+    case VER_PLATFORM_WIN32_WINDOWS:
+	if ((osvi.dwMajorVersion > 4) ||
+	    ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion > 0))) {
+	    WIN32_OS_string=xstrdup("Windows 98");
+	    return _WIN_OS_WIN98;
+	}
+	WIN32_OS_string=xstrdup("Windows 95");
+	return _WIN_OS_WIN95;
+	break;
+    case VER_PLATFORM_WIN32s:
+	WIN32_OS_string=xstrdup("Windows 3.1 with WIN32S");
+	return _WIN_OS_WIN32S;
+	break;
+    default:
+	return _WIN_OS_UNKNOWN;
+    }
+    WIN32_OS_string=xstrdup("Unknown");
+    return _WIN_OS_UNKNOWN;
+}
 
-        if (schService == NULL) debug(1,1)("OpenService failed");
-            /* Could not open the service */
-        else {
-            /* try to stop the service */
-            if (ControlService(schService, SERVICE_CONTROL_STOP, &svcStatus)) {
-                Sleep(1000);
-                while(QueryServiceStatus(schService, &svcStatus)) {
-                    if(svcStatus.dwCurrentState == SERVICE_STOP_PENDING)
-                        Sleep(1000);
-                    else
-                        break;
-                }
-            }
+/* ====================================================================== */
+/* PUBLIC FUNCTIONS */
+/* ====================================================================== */
 
-            // now remove the service
-            if (DeleteService(schService) == 0) debug(1,1)("DeleteService failed");
-			else printf("Service %s deleted successfuly, see ya'round :)\n", SQUID_SERVICE_NAME);
+VOID
+WIN32_Exit(int ExitStatus)
+{
+#ifdef _SQUID_MSWIN_
+    Win32SockCleanup();
+#endif
+#ifdef USE_WIN32_SERVICE
+    if (ExitStatus) {
+	svcStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
+	svcStatus.dwServiceSpecificExitCode = 1;
+    }
+    svcStatus.dwCurrentState = SERVICE_STOPPED;
+    SetServiceStatus(svcHandle, &svcStatus);
+#endif
+    exit(0);
+}
 
-            CloseServiceHandle(schService);
-        }
+int
+WIN32_Subsystem_Init()
+{
+    WIN32_OS_version = GetOSVersion();
+#ifdef USE_WIN32_SERVICE
+    if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
+	char path[512];
+	HKEY hndKey;
+	/* Register the service Handler function */
+	svcHandle =
+	    RegisterServiceCtrlHandler(WIN32_Service_name,
+	    WIN32_svcHandler);
+	if (svcHandle == 0)
+	    return 1;
+	/* Set Process work dir to directory cointaining squid.exe */
+	GetModuleFileName(NULL, path, 512);
+	path[strlen(path) - 10] = '\0';
+	if (SetCurrentDirectory(path) == 0)
+	    return 1;
+	xfree(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, WIN32_Service_name, NULL, &Type, NULL, &Size);
+	    if (Result == ERROR_SUCCESS && Size) {
+		ConfigFile = xmalloc(Size);
+		RegQueryValueEx(hndKey, WIN32_Service_name, NULL, &Type, ConfigFile,
+		    &Size);
+	    } else
+		ConfigFile = xstrdup(DefaultConfigFile);
+	    RegCloseKey(hndKey);
+	} else {
+	    ConfigFile = xstrdup(DefaultConfigFile);
+	}
+	/* 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);
+    }
+#endif
+#ifdef _SQUID_MSWIN_
+    Win32SockInit();
+#endif
+    return 0;
+}
 
-        CloseServiceHandle(schSCManager);
+#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 InstallService()
+void
+WIN32_RemoveService()
 {
-    SC_HANDLE   schService;
-    SC_HANDLE   schSCManager;
+    SC_HANDLE schService;
+    SC_HANDLE schSCManager;
 
-    TCHAR szPath[512];
-	int lenpath;
-    if ((lenpath=GetModuleFileName( NULL, szPath, 512 )) == 0)
-    {
-        exit(1);
-        return;
+    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");
+    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(1000);
+		while (QueryServiceStatus(schService, &svcStatus)) {
+		    if (svcStatus.dwCurrentState == SERVICE_STOP_PENDING)
+			Sleep(1000);
+		    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);
     }
+}
 
-    schSCManager = OpenSCManager(
-                        NULL,                   // machine (NULL == local)
-                        NULL,                   // database (NULL == default)
-                        SC_MANAGER_ALL_ACCESS   // access required
-                        );
-   if (!schSCManager) debug(1,1)("OpenSCManager failed");
+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);
+    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
-            servname,        // name of service
-            servname, // 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
-            NULL,       // dependencies
-            NULL,                       // LocalSystem account
-            NULL);                      // no password
-
-        if (schService) {
-            CloseServiceHandle(schService);
-
-	    /* Now store the server_root in the registry */
-	    store_key("ServerRoot", REG_SZ,(unsigned char*) szPath, lenpath+1);
-		printf("Service %s installed successfuly, enjoy :)\n", SQUID_SERVICE_NAME);
-		printf("that is, u may start it from the Services applet of control panel\n");
-		printf("Don't forget to edit squid.conf before starting it\n\n");
-		printf("Romeo Anghelache, http://www.andrew.cmu.edu/~romeo/ \n");
-		printf("Guido Serassio, http://serassio.interfree.it \n");
-		printf("No warranties of any kind, no time for support!\n");
-		printf("This work derived from GNU Squid2.3 stable 4\n");
-        }
-        else  debug(1,1)("CreateService failed");
+	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) {
+	    CloseServiceHandle(schService);
+	    /* Now store the config file location in the registry */
+	    if (!ConfigFile)
+		ConfigFile = xstrdup(DefaultConfigFile);
+	    WIN32_StoreKey(WIN32_Service_name, 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);
+}
 
-        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;
+    	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;
 
-int Win32SockInit(void)
+static int Win32SockInit(void)
 {
     int iVersionRequested;
     WSADATA wsaData;
@@ -261,7 +588,6 @@
     }
     else if (s_iInitCount < 0)
 	return (s_iInitCount);
-
     /* s_iInitCount == 0. Do the initailization */
     iVersionRequested = MAKEWORD(2, 0);
     err = WSAStartup((WORD) iVersionRequested, &wsaData);
@@ -275,16 +601,16 @@
 	WSACleanup();
 	return (s_iInitCount);
     }
-	debug(1,1)("Windows sockets initialised");
+    debug(1,1)("Windows sockets initialised");
     s_iInitCount++;
     return (s_iInitCount);
-
 }
 
-
-void Win32SockCleanup(void)
+static void Win32SockCleanup(void)
 {
     if (--s_iInitCount == 0)
 	WSACleanup();
     return;
 }
+#endif /* End native Windows NT EXPERIMENTAL PORT */
+#endif
