costin 02/03/14 09:43:47 Modified: jk/native/nt_service jk_nt_service.c Log: Merged changes from 3.3 Addition of stop_cmd, allowing the stop to be done by executing a command. ( catalina shutdown protocol is already supported ) Removed some of the checks for settings that are not required. If cmd_line is specified, there is no need for server.xml or other tomcat-specific things. cmd_line, stdout, stderr are required. Revision Changes Path 1.4 +288 -79 jakarta-tomcat-connectors/jk/native/nt_service/jk_nt_service.c Index: jk_nt_service.c =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native/nt_service/jk_nt_service.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- jk_nt_service.c 17 Jan 2002 21:17:02 -0000 1.3 +++ jk_nt_service.c 14 Mar 2002 17:43:47 -0000 1.4 @@ -58,14 +58,14 @@ /*************************************************************************** * Description: NT System service for Jakarta/Tomcat * * Author: Gal Shachor <[EMAIL PROTECTED]> * - * Version: $Revision: 1.3 $ * + * Dave Oxley <[EMAIL PROTECTED]> * + * Version: $Revision: 1.4 $ * ***************************************************************************/ #include "jk_global.h" #include "jk_util.h" #include "jk_ajp13.h" #include "jk_connect.h" - #include <windows.h> #include <stdio.h> #include <stdlib.h> @@ -86,23 +86,39 @@ static HANDLE hServerStopEvent = NULL; static int shutdown_port; static char *shutdown_protocol = AJP12_TAG; -static char *shutdown_secret = NULL; +static char *shutdown_secret = NULL; +static char *shutdown_cmd=NULL; + +typedef enum ActionEnum +{ acNoAction = 0, + acInstall = 1, + acRemove = 2, + acStartTC = 3, + acStopTC = 4 +} ActionEnum; + struct jk_tomcat_startup_data { - char *classpath; - char *tomcat_home; + char *cmd_line; /* Start command line */ char *stdout_file; char *stderr_file; + char *extra_path; + char *tomcat_home; char *java_bin; - char *tomcat_class; - char *server_file; - char *cmd_line; - int shutdown_port; + char *shutdown_protocol; + /* for cmd */ + char *stop_cmd; + /* For ajp13/ajp12/catalina */ + int shutdown_port; char *shutdown_secret; - char *extra_path; + /* Optional/not needed */ + char *classpath; + char *tomcat_class; + char *server_file; }; + typedef struct jk_tomcat_startup_data jk_tomcat_startup_data_t; // internal function prototypes @@ -110,8 +126,16 @@ static void WINAPI service_main(DWORD dwArgc, char **lpszArgv); static void install_service(char *name, - char *prp_file); + char *user, + char *password, + char *deps, + BOOL bAutomatic, + char *rel_prp_file); static void remove_service(char *name); +static void start_service(char *name, + char *machine); +static void stop_service(char *name, + char *machine); static char *GetLastErrorText(char *lpszBuf, DWORD dwSize); static void AddToMessageLog(char *lpszMsg); static BOOL ReportStatusToSCMgr(DWORD dwCurrentState, @@ -131,34 +155,59 @@ char *b, DWORD sz); static int start_tomcat(const char *name, HANDLE *hTomcat); -static void stop_tomcat(short port, +static void stop_tomcat(char *name, + short port, const char *protocol, - char *secret, - HANDLE hTomcat); + char *secret, + HANDLE hTomcat); static int read_startup_data(jk_map_t *init_map, jk_tomcat_startup_data_t *data, jk_pool_t *p); - +static int exec_cmd(const char *name, HANDLE *hTomcat, char *cmdLine); static void usage_message(const char *name) { - printf("%s - Usage:\n", name); - printf("%s -i <service name> <configuration properties file>\n", name); - printf("\tto install the service\n"); - printf("%s -r <service name>\n", name); - printf("\tto remove the service\n"); + printf("%s - Usage:\n\n", name); + printf("To install the service:\n"); + printf("%s -i <service name> {optional params} <config properties file>\n", name); + printf(" Optional parameters\n"); + printf(" -u <user name> - In the form DomainName\\UserName (.\\UserName for local)\n"); + printf(" -p <user password>\n"); + printf(" -a - Set startup type to automatic\n"); + printf(" -d <service dependency> - Can be entered multiple times\n\n"); + printf("To remove the service:\n"); + printf("%s -r <service name>\n\n", name); + printf("To start the service:\n"); + printf("%s -s <service name> {optional params}\n", name); + printf(" Optional parameters\n"); + printf(" -m <machine>\n\n"); + printf("To stop the service:\n"); + printf("%s -t <service name> {optional params}\n", name); + printf(" Optional parameters\n"); + printf(" -m <machine>\n"); } void main(int argc, char **argv) { WORD wVersionRequested; WSADATA wsaData; - int err; - + int i; + int err; + int count; + int iAction = acNoAction; + char *pServiceName = NULL; + char *pUserName = NULL; + char *pPassword = NULL; + char *pMachine = NULL; + BOOL bAutomatic = FALSE; + char strDependancy[256] = ""; + + memset(strDependancy, 0, 255); + wVersionRequested = MAKEWORD(1, 1); err = WSAStartup(wVersionRequested, &wsaData); if(0 != err) { - fprintf(stderr, "Error connecting to winosck"); + fprintf(stderr, "Error connecting to winsock"); return; } @@ -175,20 +224,51 @@ LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion)); - __try { - if((argc > 2) && ((*argv[1] == '-') || (*argv[1] == '/'))) { - char *cmd = argv[1]; - cmd++; - if(0 == stricmp("i", cmd) && (4 == argc)) { - install_service(argv[2], argv[3]); + if(argc > 2) { + count=0; + for (i=1;i<argc;i++) { + if ((*argv[i] == '-') || (*argv[i] == '/')) { + char *cmd = argv[i]; + cmd++; + if(0 == stricmp("i", cmd)) { + iAction = acInstall; + pServiceName = argv[i+1]; + } else if(0 == stricmp("r", cmd)) { + iAction = acRemove; + pServiceName = argv[i+1]; + } else if(0 == stricmp("s", cmd)) { + iAction = acStartTC; + pServiceName = argv[i+1]; + } else if(0 == stricmp("t", cmd)) { + iAction = acStopTC; + pServiceName = argv[i+1]; + } else if(0 == stricmp("u", cmd)) { + pUserName = argv[i+1]; + } else if(0 == stricmp("p", cmd)) { + pPassword = argv[i+1]; + } else if(0 == stricmp("m", cmd)) { + pMachine = argv[i+1]; + } else if(0 == stricmp("a", cmd)) { + bAutomatic = TRUE; + } else if(0 == stricmp("d", cmd)) { + memcpy(strDependancy+count, argv[i+1], strlen(argv[i+1])); + count+= strlen(argv[i+1])+1; + } + } + } + switch (iAction) { + case acInstall: + install_service(pServiceName, pUserName, pPassword, strDependancy, bAutomatic, argv[i-1]); return; - } else if(0 == stricmp("r", cmd) && (3 == argc)) { - remove_service(argv[2]); + case acRemove: + remove_service(pServiceName); return; - } else if(0 == stricmp("s", cmd) && (3 == argc)) { - HANDLE hTomcat; - start_tomcat(argv[2], &hTomcat); + case acStartTC: + start_service(pServiceName, pMachine); + return; + case acStopTC: + stop_service(pServiceName, pMachine); return; } } else if(2 == argc) { @@ -309,6 +389,10 @@ } void install_service(char *name, + char *user, + char *password, + char *deps, + BOOL bAutomatic, char *rel_prp_file) { SC_HANDLE schService; @@ -317,6 +401,9 @@ char szPropPath[2048]; char *dummy; + if (0 == stricmp("", deps)) + deps = NULL; + if(!GetFullPathName(rel_prp_file, sizeof(szPropPath) - 1, szPropPath, &dummy)) { printf("Unable to install %s - %s\n", name, @@ -338,8 +425,8 @@ return; } - schSCManager = OpenSCManager(NULL, // machine (NULL == local) - NULL, // database (NULL == default) + schSCManager = OpenSCManager(NULL, // machine (NULL == local) + NULL, // database (NULL == default) SC_MANAGER_ALL_ACCESS); // access required if(schSCManager) { schService = CreateService(schSCManager, // SCManager database @@ -347,14 +434,14 @@ name, // name to display SERVICE_ALL_ACCESS, // desired access SERVICE_WIN32_OWN_PROCESS, // service type - SERVICE_DEMAND_START, // start type + bAutomatic ? SERVICE_AUTO_START : SERVICE_DEMAND_START, // start type SERVICE_ERROR_NORMAL, // error control type szExecPath, // service's binary NULL, // no load ordering group NULL, // no tag identifier - NULL, // dependencies - NULL, // LocalSystem account - NULL); // no password + deps, // dependencies + user, // account + password); // password if(schService) { printf("The service named %s was created. Now adding registry entries\n", name); @@ -428,6 +515,100 @@ } } +void start_service(char *name, char *machine) +{ + SC_HANDLE schService; + SC_HANDLE schSCManager; + + schSCManager = OpenSCManager(machine, // machine (NULL == local) + NULL, // database (NULL == default) + SC_MANAGER_ALL_ACCESS); // access required + + if(schSCManager) { + schService = OpenService(schSCManager, name, SERVICE_ALL_ACCESS); + + if(schService) { + // try to start the service + if(StartService(schService, 0, NULL)) { + printf("Starting %s.", name); + Sleep(1000); + + while(QueryServiceStatus(schService, &ssStatus )) { + if(ssStatus.dwCurrentState == SERVICE_START_PENDING) { + printf("."); + Sleep(1000); + } else { + break; + } + } + + if(ssStatus.dwCurrentState == SERVICE_RUNNING) { + printf("\n%s started.\n", name); + } else { + printf("\n%s failed to start.\n", name); + } + } + else + printf("StartService failed - %s\n", GetLastErrorText(szErr, sizeof(szErr))); + + CloseServiceHandle(schService); + } else { + printf("OpenService failed - %s\n", GetLastErrorText(szErr, sizeof(szErr))); + } + + CloseServiceHandle(schSCManager); + } else { + printf("OpenSCManager failed - %s\n", GetLastErrorText(szErr, sizeof(szErr))); + } +} + +void stop_service(char *name, char *machine) +{ + SC_HANDLE schService; + SC_HANDLE schSCManager; + + schSCManager = OpenSCManager(machine, // machine (NULL == local) + NULL, // database (NULL == default) + SC_MANAGER_ALL_ACCESS); // access required + + if(schSCManager) { + schService = OpenService(schSCManager, name, SERVICE_ALL_ACCESS); + + if(schService) { + // try to stop the service + if(ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus )) { + printf("Stopping %s.", name); + Sleep(1000); + + while(QueryServiceStatus(schService, &ssStatus )) { + if(ssStatus.dwCurrentState == SERVICE_STOP_PENDING) { + printf("."); + Sleep(1000); + } else { + break; + } + } + + if(ssStatus.dwCurrentState == SERVICE_STOPPED) { + printf("\n%s stopped.\n", name); + } else { + printf("\n%s failed to stop.\n", name); + } + } + else + printf("StopService failed - %s\n", GetLastErrorText(szErr, sizeof(szErr))); + + CloseServiceHandle(schService); + } else { + printf("OpenService failed - %s\n", GetLastErrorText(szErr, sizeof(szErr))); + } + + CloseServiceHandle(schSCManager); + } else { + printf("OpenSCManager failed - %s\n", GetLastErrorText(szErr, sizeof(szErr))); + } +} + static int set_registry_values(char *name, char *prp_file) { @@ -481,7 +662,7 @@ value); if(rc) { printf("Registry values were added\n"); - printf("If you have already updated wrapper.properties you may start the %s service by executing \"net start %s\" from the command prompt\n", + printf("If you have already updated wrapper.properties you may start the %s service by executing \"jk_nt_service -s %s\" from the command prompt\n", name, name); } @@ -534,20 +715,25 @@ * Stop order arrived */ ResetEvent(hServerStopEvent); - stop_tomcat((short)shutdown_port, shutdown_protocol, + stop_tomcat(name, (short)shutdown_port, shutdown_protocol, shutdown_secret, hTomcat); break; case (WAIT_OBJECT_0 + 1): /* * Tomcat died !!! */ + CloseHandle(hServerStopEvent); + CloseHandle(hTomcat); + exit(0); // exit ungracefully so + // Service Control Manager + // will attempt a restart. break; default: /* * some error... * close the servlet container and exit */ - stop_tomcat((short)shutdown_port, shutdown_protocol, + stop_tomcat(name, (short)shutdown_port, shutdown_protocol, shutdown_secret, hTomcat); } CloseHandle(hServerStopEvent); @@ -644,17 +830,26 @@ return lpszBuf; } -static void stop_tomcat(short port, +static void stop_tomcat(char *name, + short port, const char *protocol, char *secret, HANDLE hTomcat) { struct sockaddr_in in; + + if(strcasecmp(protocol, "cmd") == 0 ) { + exec_cmd( name, hTomcat, shutdown_cmd); + /* XXX sleep 100 */ + TerminateProcess(hTomcat, 0); + return; + } if(jk_resolve("localhost", port, &in)) { int sd = jk_open_socket(&in, JK_TRUE, NULL); if(sd >0) { int rc = JK_FALSE; + if(strcasecmp(protocol, "catalina") == 0 ) { char len; @@ -679,6 +874,11 @@ rc = ajp13_marshal_shutdown_into_msgb(msg, &pool, NULL); + if( secret!=NULL ) { + /** will work with old clients, as well as new + */ + rc = jk_b_append_string(msg, secret); + } if(rc) { jk_b_end(msg, AJP13_PROTO); @@ -707,7 +907,7 @@ TerminateProcess(hTomcat, 0); } -static int start_tomcat(const char *name, HANDLE *hTomcat) +static int exec_cmd(const char *name, HANDLE *hTomcat, char *cmdLine) { char tag[1024]; HKEY hk; @@ -774,10 +974,13 @@ FILE_END); memset(&processInformation, 0, sizeof(processInformation)); - - printf(data.cmd_line); + + if( cmdLine==NULL ) + cmdLine=data.cmd_line; + + printf(cmdLine); if(CreateProcess(data.java_bin, - data.cmd_line, + cmdLine, NULL, NULL, TRUE, @@ -791,9 +994,11 @@ CloseHandle(processInformation.hThread); CloseHandle(startupInfo.hStdOutput); CloseHandle(startupInfo.hStdError); + shutdown_port = data.shutdown_port; shutdown_secret = data.shutdown_secret; - shutdown_protocol = strdup(data.shutdown_protocol); + shutdown_protocol = strdup(data.shutdown_protocol); + shutdown_cmd = strdup(data.stop_cmd); return JK_TRUE; } else { @@ -812,18 +1017,23 @@ return JK_FALSE; } +static int start_tomcat(const char *name, HANDLE *hTomcat) +{ + return exec_cmd( name, hTomcat, NULL ); +} + static int create_registry_key(const char *tag, HKEY *key) { LONG lrc = RegCreateKeyEx(HKEY_LOCAL_MACHINE, tag, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_WRITE, - NULL, - key, - NULL); + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_WRITE, + NULL, + key, + NULL); if(ERROR_SUCCESS != lrc) { return JK_FALSE; } @@ -839,9 +1049,9 @@ lrc = RegSetValueEx(hkey, tag, - 0, - REG_SZ, - value, + 0, + REG_SZ, + value, strlen(value)); if(ERROR_SUCCESS != lrc) { @@ -890,45 +1100,40 @@ data->tomcat_class = NULL; data->server_file = NULL; + /* All this is wrong - you just need to configure cmd_line */ + /* Optional - you may have cmd_line defined */ data->server_file = map_get_string(init_map, "wrapper.server_xml", NULL); - if(!data->server_file) { - return JK_FALSE; - } - data->classpath = map_get_string(init_map, "wrapper.class_path", NULL); - if(!data->classpath) { - return JK_FALSE; - } - data->tomcat_home = map_get_string(init_map, "wrapper.tomcat_home", NULL); - if(!data->tomcat_home) { - return JK_FALSE; - } - data->java_bin = map_get_string(init_map, "wrapper.javabin", NULL); - if(!data->java_bin) { - return JK_FALSE; - } - data->tomcat_class = map_get_string(init_map, "wrapper.startup_class", "org.apache.tomcat.startup.Tomcat"); - if(NULL == data->tomcat_class) { - return JK_FALSE; - } - data->cmd_line = map_get_string(init_map, "wrapper.cmd_line", NULL); + + data->stop_cmd = map_get_string(init_map, + "wrapper.stop_cmd", + NULL); + + if(NULL == data->cmd_line && + ( (NULL == data->tomcat_class) || + (NULL == data->server_file) || + (NULL == data->tomcat_home) || + (NULL == data->java_bin) )) { + return JK_FALSE; + } + if(NULL == data->cmd_line) { data->cmd_line = (char *)jk_pool_alloc(p, (20 + strlen(data->java_bin) + @@ -974,6 +1179,10 @@ "wrapper.stdout", NULL); + if(NULL == data->stdout_file && NULL == data->tomcat_home ) { + return JK_FALSE; + } + if(NULL == data->stdout_file) { data->stdout_file = jk_pool_alloc(p, strlen(data->tomcat_home) + 2 + strlen("\\stdout.log")); strcpy(data->stdout_file, data->tomcat_home);
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>