--------------------- PatchSet 2752 Date: 2001/08/13 17:27:11 Author: serassio Branch: cygwin-svc Tag: (none) Log: Added full command line support when running as a Windows service Members: doc/win32-relnotes.txt:1.1.2.2.2.1->1.1.2.2.2.2 src/globals.h:1.5.12.10.2.1->1.5.12.10.2.2 src/main.c:1.12.2.12.2.4->1.12.2.12.2.5 src/protos.h:1.9.2.11.2.5->1.9.2.11.2.6 src/win32.c:1.1.50.6.2.4->1.1.50.6.2.5 Index: squid/doc/win32-relnotes.txt =================================================================== RCS file: /cvsroot/squid-sf//squid/doc/Attic/win32-relnotes.txt,v retrieving revision 1.1.2.2.2.1 retrieving revision 1.1.2.2.2.2 diff -u -r1.1.2.2.2.1 -r1.1.2.2.2.2 --- squid/doc/win32-relnotes.txt 2 Jun 2001 13:54:29 -0000 1.1.2.2.2.1 +++ squid/doc/win32-relnotes.txt 13 Aug 2001 17:27:11 -0000 1.1.2.2.2.2 @@ -22,12 +22,22 @@ Service uninstallation is made with -r command line switch plus the appropriate -n switch. -The -k switch family must be used with the appropriate -n switch, so the syntax is: +The -k switch family must be used with the appropriate -f and -n switches, so the syntax is: -squid -k command -n service-name +squid -k command [-f file] -n service-name where service-name is the name specified with -n options at service install time. +To use Squid original command line, the new -O switch must be used, the sintax is: + +squid -O cmdline [-n service-name] + +If multiple service command line options must be specified, use quote. The -n switch is +needed only when non default service name is in use. + +Example: + +squid -O "-D -a 8080" -n squidsvc PSAPI.DLL (Process Status Helper) Considerations Index: squid/src/globals.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/globals.h,v retrieving revision 1.5.12.10.2.1 retrieving revision 1.5.12.10.2.2 diff -u -r1.5.12.10.2.1 -r1.5.12.10.2.2 --- squid/src/globals.h 2 Jun 2001 12:32:41 -0000 1.5.12.10.2.1 +++ squid/src/globals.h 13 Aug 2001 17:27:11 -0000 1.5.12.10.2.2 @@ -1,6 +1,6 @@ /* - * $Id: globals.h,v 1.5.12.10.2.1 2001/06/02 12:32:41 serassio Exp $ + * $Id: globals.h,v 1.5.12.10.2.2 2001/08/13 17:27:11 serassio Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -156,7 +156,8 @@ extern int incoming_sockets_accepted; #if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) extern unsigned int WIN32_OS_version; /* 0 */ -extern char *WIN32_OS_string; -extern char *WIN32_Service_name; +extern char *WIN32_OS_string; /* NULL */ +extern char *WIN32_Service_name; /* NULL */ +extern char *WIN32_Command_Line; /* 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.12.2.12.2.4 retrieving revision 1.12.2.12.2.5 diff -u -r1.12.2.12.2.4 -r1.12.2.12.2.5 --- squid/src/main.c 12 Aug 2001 16:05:13 -0000 1.12.2.12.2.4 +++ squid/src/main.c 13 Aug 2001 17:27:11 -0000 1.12.2.12.2.5 @@ -1,6 +1,6 @@ /* - * $Id: main.c,v 1.12.2.12.2.4 2001/08/12 16:05:13 serassio Exp $ + * $Id: main.c,v 1.12.2.12.2.5 2001/08/13 17:27:11 serassio Exp $ * * DEBUG: section 1 Startup and Main Loop * AUTHOR: Harvest Derived @@ -41,6 +41,7 @@ static int opt_install_service = FALSE; static int opt_remove_service = FALSE; static int opt_signal_service = FALSE; +static int opt_command_line = FALSE; extern void WIN32_svcstatusupdate(DWORD); void WINAPI WIN32_svcHandler(DWORD); #endif @@ -96,7 +97,7 @@ { 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" + "Usage: %s [-dhirsvzCDFRVYX] [-f config-file] [-[au] port] [-k signal] [-n name] [-O CommandLine]\n" #else "Usage: %s [-dhsvzCDFNRVYX] [-f config-file] [-[au] port] [-k signal]\n" #endif @@ -125,6 +126,9 @@ " -F Don't serve any requests until store is rebuilt.\n" #if !(defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))) " -N No daemon mode.\n" +#else + " -O options\n" + " Set Windows Service Command line options in Registry.\n" #endif " -R Do not set REUSEADDR on port.\n" " -S Double-check swap during rebuild.\n" @@ -142,7 +146,7 @@ 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) { + while ((c = getopt(argc, argv, "CDFO:RSVYXa:d:f:hik:m::n:rsu:vz?")) != -1) { #else while ((c = getopt(argc, argv, "CDFNRSVYXa:d:f:hk:m::su:vz?")) != -1) { #endif @@ -160,6 +164,11 @@ case 'N': opt_no_daemon = 1; break; +#else + case 'O': + opt_command_line = 1; + WIN32_Command_Line = xstrdup(optarg); + break; #endif case 'R': opt_reuseaddr = 0; @@ -621,7 +630,7 @@ #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) +SquidMain(int argc, char **argv) #else int main(int argc, char **argv) @@ -638,7 +647,7 @@ #if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) #ifdef USE_WIN32_SERVICE - if (WIN32_Subsystem_Init()) + if (WIN32_Subsystem_Init(&argc, &argv)) return; #else { @@ -701,6 +710,10 @@ WIN32_RemoveService(); return; } + if (opt_command_line) { + WIN32_SetServiceCommandLine(); + return; + } #endif /* parse configuration file Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.9.2.11.2.5 retrieving revision 1.9.2.11.2.6 diff -u -r1.9.2.11.2.5 -r1.9.2.11.2.6 --- squid/src/protos.h 12 Aug 2001 16:20:49 -0000 1.9.2.11.2.5 +++ squid/src/protos.h 13 Aug 2001 17:27:11 -0000 1.9.2.11.2.6 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.9.2.11.2.5 2001/08/12 16:20:49 serassio Exp $ + * $Id: protos.h,v 1.9.2.11.2.6 2001/08/13 17:27:11 serassio Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -1315,10 +1315,15 @@ /* CygWin & Windows NT Port */ /* win32.c */ #if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) +#ifdef USE_WIN32_SERVICE +extern int WIN32_Subsystem_Init(int *, char ***); +#else extern int WIN32_Subsystem_Init(void); +#endif extern void WIN32_sendSignal(int); extern void WIN32_Abort(int); extern void WIN32_Exit(void); +extern void WIN32_SetServiceCommandLine(void); extern void WIN32_InstallService(void); extern void WIN32_RemoveService(void); #endif Index: squid/src/win32.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/win32.c,v retrieving revision 1.1.50.6.2.4 retrieving revision 1.1.50.6.2.5 diff -u -r1.1.50.6.2.4 -r1.1.50.6.2.5 --- squid/src/win32.c 12 Aug 2001 16:05:13 -0000 1.1.50.6.2.4 +++ squid/src/win32.c 13 Aug 2001 17:27:11 -0000 1.1.50.6.2.5 @@ -32,7 +32,9 @@ void WINAPI WIN32_svcHandler(DWORD); static int WIN32_StoreKey(const char *, DWORD, unsigned char *, int); static int WIN32_create_key(void); +static void WIN32_build_argv (char *); void WINAPI SquidMain(DWORD, char **); + /* The following code section is part of an EXPERIMENTAL native */ /* Windows NT/2000 Squid port - Compiles only on MS Visual C++ */ #if defined(_SQUID_MSWIN_) @@ -42,15 +44,28 @@ static SERVICE_STATUS svcStatus; static SERVICE_STATUS_HANDLE svcHandle; +static int WIN32_argc; +static char ** WIN32_argv; +static char * WIN32_module_name; #define VENDOR "GNU" #if defined(_SQUID_MSWIN_) -#define SOFTWARE "SquidNT" +#define SOFTWARENAME "SquidNT" #else -#define SOFTWARE "Squid" +#define SOFTWARENAME "Squid" #endif #define VERSION "2.5" -#define REGKEY "SOFTWARE\\" VENDOR "\\" SOFTWARE "\\" VERSION +#define COMMANDLINE "CommandLine" +#define CONFIGFILE "ConfigFile" +static char REGKEY[256]="SOFTWARE\\"VENDOR"\\"SOFTWARENAME"\\"VERSION"\\"; +static char *keys[] = { + "SOFTWARE", /* key[0] */ + VENDOR, /* key[1] */ + SOFTWARENAME, /* key[2] */ + VERSION, /* key[3] */ + NULL, /* key[4] */ + NULL /* key[5] */ +}; /* ====================================================================== */ /* LOCAL FUNCTIONS */ @@ -59,12 +74,6 @@ static int WIN32_create_key(void) { - static char *keys[] = { "SOFTWARE", - VENDOR, - SOFTWARE, - VERSION, - NULL - }; int index; HKEY hKey; HKEY hKeyNext; @@ -216,6 +225,42 @@ return _WIN_OS_UNKNOWN; } +/* Build argv, argc from string passed from Windows. */ +static void WIN32_build_argv(char *cmd) +{ + int argvlen = 0; + char *word; + + WIN32_argc = 1; + WIN32_argv = (char **) xmalloc ((WIN32_argc+1) * sizeof (char *)); + WIN32_argv[0]=xstrdup(WIN32_module_name); +/* Scan command line until there is nothing left. */ + while (*cmd) { + /* Ignore spaces */ + if (xisspace(*cmd)) { + cmd++; + continue; + } + /* Found the beginning of an argument. */ + word = cmd; + while (*cmd) { + cmd++; /* Skip over this character */ + if (xisspace(*cmd)) /* End of argument if space */ + break; + } + if (*cmd) + *cmd++ = '\0'; /* Terminate `word' */ + /* See if we need to allocate more space for argv */ + if (WIN32_argc >= argvlen) { + argvlen = WIN32_argc + 1; + WIN32_argv = (char **) xrealloc (WIN32_argv, (1 + argvlen) * sizeof (char *)); + } + /* Add word to argv file. */ + WIN32_argv[WIN32_argc++] = word; + } + WIN32_argv[WIN32_argc] = NULL; +} + /* ====================================================================== */ /* PUBLIC FUNCTIONS */ /* ====================================================================== */ @@ -243,8 +288,11 @@ _exit(0); } -int -WIN32_Subsystem_Init() +#ifdef USE_WIN32_SERVICE +int WIN32_Subsystem_Init(int * argc, char *** argv) +#else +int WIN32_Subsystem_Init() +#endif { WIN32_OS_version = GetOSVersion(); if (atexit(WIN32_Exit) != 0) @@ -253,6 +301,7 @@ if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) { char path[512]; HKEY hndKey; + char * CommandLine; if (signal(SIGABRT, WIN32_Abort) == SIG_ERR) return 1; /* Register the service Handler function */ @@ -263,6 +312,7 @@ return 1; /* Set Process work dir to directory cointaining squid.exe */ GetModuleFileName(NULL, path, 512); + WIN32_module_name=xstrdup(path); path[strlen(path) - 10] = '\0'; if (SetCurrentDirectory(path) == 0) return 1; @@ -273,17 +323,31 @@ DWORD Size = 0; LONG Result; Result = - RegQueryValueEx(hndKey, WIN32_Service_name, NULL, &Type, NULL, &Size); + RegQueryValueEx(hndKey, CONFIGFILE, NULL, &Type, NULL, &Size); if (Result == ERROR_SUCCESS && Size) { ConfigFile = xmalloc(Size); - RegQueryValueEx(hndKey, WIN32_Service_name, NULL, &Type, ConfigFile, + RegQueryValueEx(hndKey, CONFIGFILE, NULL, &Type, ConfigFile, &Size); } else ConfigFile = xstrdup(DefaultConfigFile); + Size = 0; + Type = 0; + Result = + RegQueryValueEx(hndKey, COMMANDLINE, NULL, &Type, NULL, &Size); + if (Result == ERROR_SUCCESS && Size) { + CommandLine = xmalloc(Size); + RegQueryValueEx(hndKey, COMMANDLINE, NULL, &Type, CommandLine, + &Size); + } else + CommandLine = xstrdup(""); RegCloseKey(hndKey); } else { ConfigFile = xstrdup(DefaultConfigFile); + CommandLine = xstrdup(""); } + WIN32_build_argv(CommandLine); + *argc = WIN32_argc; + *argv = WIN32_argv; /* Set Service Staus to SERVICE_START_PENDING */ svcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; svcStatus.dwCurrentState = SERVICE_START_PENDING; @@ -376,6 +440,8 @@ if (!WIN32_Service_name) WIN32_Service_name = xstrdup(_WIN_SQUID_DEFAULT_SERVICE_NAME); + strcat(REGKEY, WIN32_Service_name); + keys[4] = WIN32_Service_name; schSCManager = OpenSCManager(NULL, /* machine (NULL == local) */ NULL, /* database (NULL == default) */ SC_MANAGER_ALL_ACCESS /* access required */ @@ -412,6 +478,17 @@ } void +WIN32_SetServiceCommandLine() +{ + if (!WIN32_Service_name) + WIN32_Service_name = xstrdup(_WIN_SQUID_DEFAULT_SERVICE_NAME); + strcat(REGKEY, WIN32_Service_name); + keys[4] = WIN32_Service_name; + /* Now store the Service Command Line in the registry */ + WIN32_StoreKey(COMMANDLINE, REG_SZ, (unsigned char *) WIN32_Command_Line, strlen(WIN32_Command_Line) + 1); +} + +void WIN32_InstallService() { SC_HANDLE schService; @@ -422,6 +499,8 @@ if (!WIN32_Service_name) WIN32_Service_name = xstrdup(_WIN_SQUID_DEFAULT_SERVICE_NAME); + strcat(REGKEY, WIN32_Service_name); + keys[4] = WIN32_Service_name; if ((lenpath = GetModuleFileName(NULL, ServicePath, 512)) == 0) { debug(1, 1) ("Can't get executable path"); exit(1); @@ -454,7 +533,7 @@ /* 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); + WIN32_StoreKey(CONFIGFILE, REG_SZ, (unsigned char *) ConfigFile, strlen(ConfigFile) + 1); printf("Squid Cache version %s for %s\n", version_string, CONFIG_HOST_TYPE); printf("installed successfully as %s Windows System Service.\n", @@ -567,6 +646,8 @@ } WIN32_Service_name = xstrdup(c+1); DispatchTable[0].lpServiceName=WIN32_Service_name; + strcat(REGKEY, WIN32_Service_name); + keys[4] = WIN32_Service_name; if (!StartServiceCtrlDispatcher(DispatchTable)) { fprintf(stderr, "StartServiceCtrlDispatcher error = %ld\n", GetLastError()); @@ -578,6 +659,7 @@ } return 0; } + #endif /* The following code section is part of an EXPERIMENTAL native */