⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jk_nt_service.c

📁 精通tomcat书籍原代码,希望大家共同学习
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 *  Copyright 1999-2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/***************************************************************************
 * Description: NT System service for Jakarta/Tomcat                       *
 * Author:      Gal Shachor <shachor@il.ibm.com>                           *
 *              Dave Oxley <Dave@JungleMoss.com>                           *
 * Version:     $Revision: 300540 $                                           *
 ***************************************************************************/

#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>
#include <process.h>

#define AJP12_TAG              ("ajp12")
#define AJP13_TAG              ("ajp13")
#define BASE_REGISTRY_LOCATION ("SYSTEM\\CurrentControlSet\\Services\\")
#define IMAGE_NAME             ("ImagePath")
#define PARAMS_LOCATION        ("Parameters")
#define PRP_LOCATION           ("PropertyFile")

// internal variables
static SERVICE_STATUS          ssStatus;       // current status of the service
static SERVICE_STATUS_HANDLE   sshStatusHandle;
static DWORD                   dwErr = 0;
static char                    szErr[1024] = "";
static HANDLE                  hServerStopEvent = NULL;
static int                     shutdown_port;
static char                    *shutdown_protocol = AJP12_TAG;
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 *cmd_line; /* Start command line */
    char *stdout_file;
    char *stderr_file;
    char *extra_path;
    char *tomcat_home;
    char *java_bin;

    char *shutdown_protocol;
    /* for cmd */
    char *stop_cmd;
    /* For ajp13/ajp12/catalina */
    int  shutdown_port;
    char *shutdown_secret;

    /* 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
static void WINAPI service_ctrl(DWORD dwCtrlCode);
static void WINAPI service_main(DWORD dwArgc, 
                                char **lpszArgv);
static void install_service(char *name,
                            char *dname,
                            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,
                                DWORD dwWin32ExitCode,
                                DWORD dwWaitHint);
static void start_jk_service(char *name);
static void stop_jk_service(void);
static int set_registry_values(SC_HANDLE   schService, char *name, 
                               char *prp_file);
static int create_registry_key(const char *tag, 
                               HKEY *key);
static int set_registry_config_parameter(HKEY hkey, 
                                         const char *tag, 
                                         char *value);
static int get_registry_config_parameter(HKEY hkey, 
                                         const char *tag,  
                                         char *b, DWORD sz);
static int start_tomcat(const char *name, 
                        HANDLE *hTomcat);
static void stop_tomcat(char *name,
                        int port, 
                        const char *protocol,
                        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\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("        -n <service display name> - In quotes if contains non-lphanumeric chars\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 i;
    int err;
    int count;
    int iAction = acNoAction;
    char *pServiceDisplayName = NULL;
    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 winsock");
        return;
    } 

    if(LOBYTE( wsaData.wVersion ) != 1 || 
       HIBYTE( wsaData.wVersion ) != 1)  {
        fprintf(stderr, 
                "Error winsock version is %d %d \n", 
                LOBYTE( wsaData.wVersion ),HIBYTE( wsaData.wVersion ));
        WSACleanup();
        return; 
    } 

    fprintf(stderr, "Asked (and given) winsock %d.%d \n", 
                    LOBYTE(wsaData.wVersion),
                    HIBYTE(wsaData.wVersion));

    __try {
        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("n", cmd)) {
                        pServiceDisplayName = argv[i+1];
                    } 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:
                if (pServiceDisplayName == NULL) {
                    pServiceDisplayName = pServiceName;
                }
                install_service(pServiceName, pServiceDisplayName, pUserName,
                                pPassword, strDependancy, bAutomatic, argv[i-1]);
                return;
            case acRemove:
                remove_service(pServiceName);
                return;
            case acStartTC:
                start_service(pServiceName, pMachine);
                return;
            case acStopTC:
                stop_service(pServiceName, pMachine);
                return;
            }
        } else if(2  == argc) {

            SERVICE_TABLE_ENTRY dispatchTable[] =
            {
                { argv[1], (LPSERVICE_MAIN_FUNCTION)service_main },
                { NULL, NULL }
            };

            if(!StartServiceCtrlDispatcher(dispatchTable)) {
                AddToMessageLog("StartServiceCtrlDispatcher failed.");
            }
            return;
        } 

        usage_message(argv[0]);
        exit(-1);
    } __finally {
        WSACleanup();
    }
}

void WINAPI service_main(DWORD dwArgc, char **lpszArgv)
{
    // register our service control handler:
    //
    //
    sshStatusHandle = RegisterServiceCtrlHandler(lpszArgv[0], service_ctrl);

    if(sshStatusHandle) {

        ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
        ssStatus.dwServiceSpecificExitCode = 0;

        // report the status to the service control manager.
        //
        if(ReportStatusToSCMgr(SERVICE_START_PENDING, // service state
                                NO_ERROR,              // exit code
                                3000)) {                 // wait hint    
            start_jk_service(lpszArgv[0]);
        }
    }

    // try to report the stopped status to the service control manager.
    //
    if(sshStatusHandle) {
        ReportStatusToSCMgr(SERVICE_STOPPED,
                            dwErr,
                            0);
    }
}


void WINAPI service_ctrl(DWORD dwCtrlCode)
{
    /*
     * Handle the requested control code.
     */
    switch(dwCtrlCode)
    {
        /*
         * Stop the service.
         */
        case SERVICE_CONTROL_SHUTDOWN:
        case SERVICE_CONTROL_STOP:
            ssStatus.dwCurrentState = SERVICE_STOP_PENDING;
            stop_jk_service();
            break;

        /*
         * Update the service status.
         */
        case SERVICE_CONTROL_INTERROGATE:
            break;

        /*
         * Invalid control code, nothing to do.
         */
        default:
            break;

    }

    ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);

}

BOOL ReportStatusToSCMgr(DWORD dwCurrentState,
                         DWORD dwWin32ExitCode,
                         DWORD dwWaitHint)
{
    static DWORD dwCheckPoint = 1;
    BOOL fResult = TRUE;

    if(dwCurrentState == SERVICE_START_PENDING) {
        ssStatus.dwControlsAccepted = 0;
    } else {
        ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    }

    ssStatus.dwCurrentState = dwCurrentState;
    ssStatus.dwWin32ExitCode = dwWin32ExitCode;
    ssStatus.dwWaitHint = dwWaitHint;

    if((dwCurrentState == SERVICE_RUNNING) ||
       (dwCurrentState == SERVICE_STOPPED)) {
        ssStatus.dwCheckPoint = 0;
    } else {
        ssStatus.dwCheckPoint = dwCheckPoint++;
    }

    if(!(fResult = SetServiceStatus(sshStatusHandle, &ssStatus))) {
        AddToMessageLog(TEXT("SetServiceStatus"));
    }

    return fResult;
}

typedef WINADVAPI BOOL (WINAPI * pfnChangeServiceConfig2_t)
                       (SC_HANDLE hService, DWORD dwInfoLevel, LPVOID lpInfo);


void install_service(char *name, 
                     char *dname, 
                     char *user, 
                     char *password, 
                     char *deps, 
                     BOOL bAutomatic,
                     char *rel_prp_file)
{
    SC_HANDLE   schService;
    SC_HANDLE   schSCManager;
    char        szExecPath[2048];
    char        szPropPath[2048];
    char        szTrueName[256];
    char        *dummy;
    char        *src, *dst;

    dst = szTrueName;
    for (src = name; *src; ++src) {
        if (dst >= szTrueName + sizeof(szTrueName) - 1) {
            break;
        }
        if (!isspace(*src) && *src != '/' && *src != '\\') {
            *(dst++) = *src;
        }
    }
    *dst = '\0';

    if (0 == stricmp("", deps))
        deps = NULL;

    /* XXX strcat( deps, "Tcpip\0Afd\0" ); */
    
    if(!GetFullPathName(rel_prp_file, sizeof(szPropPath) - 1, szPropPath, &dummy)) {
        printf("Unable to install %s - %s\n", 
               name, 
               GetLastErrorText(szErr, sizeof(szErr)));
        return;
    }

    if(!jk_file_exists(szPropPath)) {
        printf("Unable to install %s - File [%s] does not exists\n", 
               name, 
               szPropPath);
        return;
    }

    szExecPath[0] = '\"';
    if(GetModuleFileName( NULL, szExecPath + 1, sizeof(szExecPath) - 2) == 0) {
        /* Was: if(GetModuleFileName( NULL, szExecPath, sizeof(szExecPath) - 1) == 0) { */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -