You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by al...@locus.apache.org on 2000/08/26 04:03:56 UTC
cvs commit: jakarta-tomcat/src/native/nt_service jk_nt_service.c nt_service.dsp
alex 00/08/25 19:03:55
Added: src/native/mod_jk/iis isapi.def isapi.dsp isapi.dsw
jk_isapi_plugin.c
src/native/mod_jk/jni Makefile.solaris jk_jnicb.c jk_jnicb.h
jni_connect.dsp jni_connect.dsw
src/native/mod_jk/netscape Makefile.solaris
jk_nsapi_plugin.c nsapi.dsp nsapi.dsw
src/native/mod_jk/nt_service jk_nt_service.c nt_service.dsp
Removed: src/native/iis isapi.def isapi.dsp isapi.dsw
jk_isapi_plugin.c
src/native/jni_connect Makefile.solaris jk_jnicb.c
jk_jnicb.h jni_connect.dsp jni_connect.dsw
src/native/netscape Makefile.solaris jk_nsapi_plugin.c
nsapi.dsp nsapi.dsw
src/native/nt_service jk_nt_service.c nt_service.dsp
Log:
Moved remaining jk directories to mod_jk dir. Again, I can't test the makefiles, so please test the configuration and let me know if it breaks. I did my best to change e.g. ..\jk to ..\common but I'm not sure it worked.
Revision Changes Path
1.1 jakarta-tomcat/src/native/mod_jk/iis/isapi.def
Index: isapi.def
===================================================================
LIBRARY "isapi_redirect"
EXPORTS
HttpFilterProc
GetFilterVersion
GetExtensionVersion
HttpExtensionProc
TerminateFilter
TerminateExtension
1.1 jakarta-tomcat/src/native/mod_jk/iis/isapi.dsp
Index: isapi.dsp
===================================================================
# Microsoft Developer Studio Project File - Name="isapi" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=isapi - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "isapi.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "isapi.mak" CFG="isapi - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "isapi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "isapi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "isapi - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "isapi___Win32_Release"
# PROP BASE Intermediate_Dir "isapi___Win32_Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "isapi_release"
# PROP Intermediate_Dir "isapi_release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ISAPI_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\common" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ISAPI_EXPORTS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 wsock32.lib advapi32.lib /nologo /dll /machine:I386 /out:"isapi_release/isapi_redirect.dll"
!ELSEIF "$(CFG)" == "isapi - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "isapi___Win32_Debug"
# PROP BASE Intermediate_Dir "isapi___Win32_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "isapi_debug"
# PROP Intermediate_Dir "isapi_debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ISAPI_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\common" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ISAPI_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 wsock32.lib advapi32.lib /nologo /dll /debug /machine:I386 /out:"isapi_debug/isapi_redirect.dll" /pdbtype:sept
!ENDIF
# Begin Target
# Name "isapi - Win32 Release"
# Name "isapi - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\isapi.def
# End Source File
# Begin Source File
SOURCE=..\common\jk_ajp12_worker.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_ajp13.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_ajp13_worker.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_connect.c
# End Source File
# Begin Source File
SOURCE=.\jk_isapi_plugin.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_jni_worker.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_lb_worker.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_map.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_msg_buff.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_pool.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_sockbuf.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_uri_worker_map.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_util.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_worker.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\common\jk_ajp12_worker.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_ajp13.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_ajp13_worker.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_ajp23_worker.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_connect.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_global.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_jni_worker.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_lb_worker.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_logger.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_map.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_msg_buff.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_mt.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_pool.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_service.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_sockbuf.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_uri_worker_map.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_util.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_worker.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_worker_list.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project
1.1 jakarta-tomcat/src/native/mod_jk/iis/isapi.dsw
Index: isapi.dsw
===================================================================
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "isapi"=".\isapi.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
1.1 jakarta-tomcat/src/native/mod_jk/iis/jk_isapi_plugin.c
Index: jk_isapi_plugin.c
===================================================================
/*
* Copyright (c) 1997-1999 The Java Apache Project. 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. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Java Apache
* Project for use in the Apache JServ servlet engine project
* <http://java.apache.org/>."
*
* 4. The names "Apache JServ", "Apache JServ Servlet Engine" and
* "Java Apache Project" must not be used to endorse or promote products
* derived from this software without prior written permission.
*
* 5. Products derived from this software may not be called "Apache JServ"
* nor may "Apache" nor "Apache JServ" appear in their names without
* prior written permission of the Java Apache Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Java Apache
* Project for use in the Apache JServ servlet engine project
* <http://java.apache.org/>."
*
* THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "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 JAVA APACHE PROJECT 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 Java Apache Group. For more information
* on the Java Apache Project and the Apache JServ Servlet Engine project,
* please see <http://java.apache.org/>.
*
*/
/***************************************************************************
* Description: ISAPI plugin for IIS/PWS *
* Author: Gal Shachor <sh...@il.ibm.com> *
* Version: $Revision: 1.1 $ *
***************************************************************************/
#include <httpext.h>
#include <httpfilt.h>
#include <wininet.h>
#include "jk_global.h"
#include "jk_util.h"
#include "jk_map.h"
#include "jk_pool.h"
#include "jk_service.h"
#include "jk_worker.h"
#include "jk_ajp12_worker.h"
#include "jk_uri_worker_map.h"
#define VERSION_STRING "Jakarta/ISAPI/1.0b1"
/*
* We use special two headers to pass values from the filter to the
* extension. These values are:
*
* 1. The real URI before redirection took place
* 2. The name of the worker to be used.
*
*/
#define URI_HEADER_NAME ("TOMCATURI:")
#define WORKER_HEADER_NAME ("TOMCATWORKER:")
#define HTTP_URI_HEADER_NAME ("HTTP_TOMCATURI")
#define HTTP_WORKER_HEADER_NAME ("HTTP_TOMCATWORKER")
#define REGISTRY_LOCATION ("Software\\Apache Software Foundation\\Jakarta Isapi Redirector\\1.0")
#define EXTENSION_URI_TAG ("extension_uri")
#define GET_SERVER_VARIABLE_VALUE(name, place) { \
(place) = NULL; \
huge_buf_sz = sizeof(huge_buf); \
if(get_server_value(private_data->lpEcb, \
(name), \
huge_buf, \
huge_buf_sz, \
"")) { \
(place) = jk_pool_strdup(&private_data->p, huge_buf); \
} \
}\
#define GET_SERVER_VARIABLE_VALUE_INT(name, place, def) { \
huge_buf_sz = sizeof(huge_buf); \
if(get_server_value(private_data->lpEcb, \
(name), \
huge_buf, \
huge_buf_sz, \
"")) { \
(place) = atoi(huge_buf); \
if(0 == (place)) { \
(place) = def; \
} \
} else { \
(place) = def; \
} \
}\
static int is_inited = JK_FALSE;
static jk_uri_worker_map_t *uw_map = NULL;
static jk_logger_t *logger = NULL;
static char extension_uri[INTERNET_MAX_URL_LENGTH] = "/jakarta/isapi_redirect.dll";
static char log_file[MAX_PATH * 2];
static int log_level = JK_LOG_EMERG_LEVEL;
static char worker_file[MAX_PATH * 2];
static char worker_mount_file[MAX_PATH * 2];
struct isapi_private_data {
jk_pool_t p;
int request_started;
unsigned bytes_read_so_far;
LPEXTENSION_CONTROL_BLOCK lpEcb;
};
typedef struct isapi_private_data isapi_private_data_t;
static int JK_METHOD start_response(jk_ws_service_t *s,
int status,
const char *reason,
const char * const *header_names,
const char * const *header_values,
unsigned num_of_headers);
static int JK_METHOD read(jk_ws_service_t *s,
void *b,
unsigned l,
unsigned *a);
static int JK_METHOD write(jk_ws_service_t *s,
const void *b,
unsigned l);
static int init_ws_service(isapi_private_data_t *private_data,
jk_ws_service_t *s,
char **worker_name);
static int initialize_extension(void);
static int read_registry_init_data(void);
static int get_registry_config_parameter(HKEY hkey,
const char *tag,
char *b,
DWORD sz);
static int get_server_value(LPEXTENSION_CONTROL_BLOCK lpEcb,
char *name,
char *buf,
DWORD bufsz,
char *def_val);
static int uri_is_web_inf(char *uri)
{
char *c = uri;
while(*c) {
*c = tolower(*c);
c++;
}
if(strstr(uri, "web-inf")) {
return JK_TRUE;
}
return JK_FALSE;
}
static int JK_METHOD start_response(jk_ws_service_t *s,
int status,
const char *reason,
const char * const *header_names,
const char * const *header_values,
unsigned num_of_headers)
{
static char crlf[3] = { (char)13, (char)10, '\0' };
jk_log(logger, JK_LOG_DEBUG,
"Into jk_ws_service_t::start_response\n");
if(status < 100 || status > 1000) {
jk_log(logger, JK_LOG_ERROR,
"jk_ws_service_t::start_response, invalid status %d\n", status);
return JK_FALSE;
}
if(s && s->ws_private) {
isapi_private_data_t *p = s->ws_private;
if(!p->request_started) {
DWORD len_of_status;
char *status_str;
char *headers_str;
p->request_started = JK_TRUE;
/*
* Create the status line
*/
if(!reason) {
reason = "";
}
status_str = (char *)_alloca((6 + strlen(reason)) * sizeof(char));
sprintf(status_str, "%d %s", status, reason);
len_of_status = strlen(status_str);
/*
* Create response headers string
*/
if(num_of_headers) {
unsigned i;
unsigned len_of_headers;
for(i = 0 , len_of_headers = 0 ; i < num_of_headers ; i++) {
len_of_headers += strlen(header_names[i]);
len_of_headers += strlen(header_values[i]);
len_of_headers += 3; /* extra for : and crlf */
}
len_of_headers += 3; /* crlf and terminating null char */
headers_str = (char *)_alloca(len_of_headers * sizeof(char));
headers_str[0] = '\0';
for(i = 0 ; i < num_of_headers ; i++) {
strcat(headers_str, header_names[i]);
strcat(headers_str, ":");
strcat(headers_str, header_values[i]);
strcat(headers_str, crlf);
}
strcat(headers_str, crlf);
} else {
headers_str = crlf;
}
if(!p->lpEcb->ServerSupportFunction(p->lpEcb->ConnID,
HSE_REQ_SEND_RESPONSE_HEADER,
status_str,
(LPDWORD)&len_of_status,
(LPDWORD)headers_str)) {
jk_log(logger, JK_LOG_ERROR,
"jk_ws_service_t::start_response, ServerSupportFunction failed\n");
return JK_FALSE;
}
}
return JK_TRUE;
}
jk_log(logger, JK_LOG_ERROR,
"jk_ws_service_t::start_response, NULL parameters\n");
return JK_FALSE;
}
static int JK_METHOD read(jk_ws_service_t *s,
void *b,
unsigned l,
unsigned *a)
{
jk_log(logger, JK_LOG_DEBUG,
"Into jk_ws_service_t::read\n");
if(s && s->ws_private && b && a) {
isapi_private_data_t *p = s->ws_private;
*a = 0;
if(l) {
char *buf = b;
DWORD already_read = p->lpEcb->cbAvailable - p->bytes_read_so_far;
if(already_read >= l) {
memcpy(buf, p->lpEcb->lpbData + p->bytes_read_so_far, l);
p->bytes_read_so_far += l;
*a = l;
} else {
/*
* Try to copy what we already have
*/
if(already_read > 0) {
memcpy(buf, p->lpEcb->lpbData + p->bytes_read_so_far, already_read);
buf += already_read;
l -= already_read;
p->bytes_read_so_far = p->lpEcb->cbAvailable;
*a = already_read;
}
/*
* Now try to read from the client ...
*/
if(p->lpEcb->ReadClient(p->lpEcb->ConnID, buf, &l)) {
*a += l;
} else {
jk_log(logger, JK_LOG_ERROR,
"jk_ws_service_t::read, ReadClient failed\n");
return JK_FALSE;
}
}
}
return JK_TRUE;
}
jk_log(logger, JK_LOG_ERROR,
"jk_ws_service_t::read, NULL parameters\n");
return JK_FALSE;
}
static int JK_METHOD write(jk_ws_service_t *s,
const void *b,
unsigned l)
{
jk_log(logger, JK_LOG_DEBUG,
"Into jk_ws_service_t::write\n");
if(s && s->ws_private && b) {
isapi_private_data_t *p = s->ws_private;
if(l) {
unsigned written = 0;
char *buf = (char *)b;
if(!p->request_started) {
start_response(s, 200, NULL, NULL, NULL, 0);
}
while(written < l) {
DWORD try_to_write = l - written;
if(!p->lpEcb->WriteClient(p->lpEcb->ConnID,
buf + written,
&try_to_write,
0)) {
jk_log(logger, JK_LOG_ERROR,
"jk_ws_service_t::write, WriteClient failed\n");
return JK_FALSE;
}
written += try_to_write;
}
}
return JK_TRUE;
}
jk_log(logger, JK_LOG_ERROR,
"jk_ws_service_t::write, NULL parameters\n");
return JK_FALSE;
}
BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer)
{
ULONG http_filter_revision = HTTP_FILTER_REVISION
pVer->dwFilterVersion = pVer->dwServerFilterVersion;
if(pVer->dwFilterVersion > http_filter_revision) {
pVer->dwFilterVersion = http_filter_revision;
}
pVer->dwFlags = SF_NOTIFY_ORDER_HIGH |
SF_NOTIFY_SECURE_PORT |
SF_NOTIFY_NONSECURE_PORT |
SF_NOTIFY_PREPROC_HEADERS;
strcpy(pVer->lpszFilterDesc, VERSION_STRING);
if(!is_inited) {
return initialize_extension();
}
return TRUE;
}
DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc,
DWORD dwNotificationType,
LPVOID pvNotification)
{
if(is_inited &&
(SF_NOTIFY_PREPROC_HEADERS == dwNotificationType)) {
PHTTP_FILTER_PREPROC_HEADERS p = (PHTTP_FILTER_PREPROC_HEADERS)pvNotification;
char uri[INTERNET_MAX_URL_LENGTH];
char *query;
DWORD sz = sizeof(uri);
jk_log(logger, JK_LOG_DEBUG,
"HttpFilterProc started\n");
/*
* Just in case somebody set these headers in the request!
*/
p->SetHeader(pfc, URI_HEADER_NAME, NULL);
p->SetHeader(pfc, WORKER_HEADER_NAME, NULL);
if(!p->GetHeader(pfc, "url", (LPVOID)uri, (LPDWORD)&sz)) {
jk_log(logger, JK_LOG_ERROR,
"HttpFilterProc error while getting the url\n");
return SF_STATUS_REQ_ERROR;
}
if(strlen(uri)) {
char *worker;
query = strchr(uri, '?');
if(query) {
*query = '\0';
}
jk_log(logger, JK_LOG_DEBUG,
"In HttpFilterProc test redirection of %s\n",
uri);
worker = map_uri_to_worker(uw_map, uri, logger);
if(query) {
*query = '?';
}
if(worker) {
/* This is a servlet, should redirect ... */
jk_log(logger, JK_LOG_DEBUG,
"HttpFilterProc [%s] is a servlet url - should redirect to %s\n",
uri, worker);
if(!p->AddHeader(pfc, URI_HEADER_NAME, uri) ||
!p->AddHeader(pfc, WORKER_HEADER_NAME, worker) ||
!p->SetHeader(pfc, "url", extension_uri)) {
jk_log(logger, JK_LOG_ERROR,
"HttpFilterProc error while adding request headers\n");
return SF_STATUS_REQ_ERROR;
}
} else {
jk_log(logger, JK_LOG_DEBUG,
"HttpFilterProc [%s] is not a servlet url\n",
uri);
}
/*
* Check if somebody is feading us with his own TOMCAT data headers.
* We reject such postings !
*/
jk_log(logger, JK_LOG_DEBUG,
"HttpFilterProc check if [%s] is points to the web-inf directory\n",
uri);
if(uri_is_web_inf(uri)) {
char crlf[3] = { (char)13, (char)10, '\0' };
char ctype[30];
char *msg = "<HTML><BODY><H1>Access is Forbidden</H1></BODY></HTML>";
DWORD len = strlen(msg);
jk_log(logger, JK_LOG_EMERG,
"HttpFilterProc [%s] points to the web-inf directory.\nSomebody try to hack into the site!!!\n",
uri);
sprintf(ctype,
"Content-Type:text/html%s%s",
crlf,
crlf);
/* reject !!! */
pfc->ServerSupportFunction(pfc,
SF_REQ_SEND_RESPONSE_HEADER,
"403 Forbidden",
(DWORD)crlf,
(DWORD)ctype);
pfc->WriteClient(pfc, msg, &len, 0);
return SF_STATUS_REQ_FINISHED;
}
}
}
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer)
{
pVer->dwExtensionVersion = MAKELONG( HSE_VERSION_MINOR,
HSE_VERSION_MAJOR );
strcpy(pVer->lpszExtensionDesc, VERSION_STRING);
if(!is_inited) {
return initialize_extension();
}
return TRUE;
}
DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpEcb)
{
DWORD rc = HSE_STATUS_ERROR;
lpEcb->dwHttpStatusCode = HTTP_STATUS_SERVER_ERROR;
jk_log(logger, JK_LOG_DEBUG,
"HttpExtensionProc started\n");
if(is_inited) {
isapi_private_data_t private_data;
jk_ws_service_t s;
jk_pool_atom_t buf[SMALL_POOL_SIZE];
char *worker_name;
jk_init_ws_service(&s);
jk_open_pool(&private_data.p, buf, sizeof(buf));
private_data.request_started = JK_FALSE;
private_data.bytes_read_so_far = 0;
private_data.lpEcb = lpEcb;
s.ws_private = &private_data;
s.pool = &private_data.p;
if(init_ws_service(&private_data, &s, &worker_name)) {
jk_worker_t *worker = wc_get_worker_for_name(worker_name, logger);
jk_log(logger, JK_LOG_DEBUG,
"HttpExtensionProc %s a worker for name %s\n",
worker ? "got" : "could not get",
worker_name);
if(worker) {
jk_endpoint_t *e = NULL;
if(worker->get_endpoint(worker, &e, logger)) {
int recover = JK_FALSE;
if(e->service(e, &s, logger, &recover)) {
rc = HSE_STATUS_SUCCESS_AND_KEEP_CONN;
lpEcb->dwHttpStatusCode = HTTP_STATUS_OK;
jk_log(logger, JK_LOG_DEBUG,
"HttpExtensionProc service() returned OK\n");
} else {
jk_log(logger, JK_LOG_ERROR,
"HttpExtensionProc error, service() failed\n");
}
e->done(&e, logger);
}
} else {
jk_log(logger, JK_LOG_ERROR,
"HttpExtensionProc error, could not get a worker for name %s\n",
worker_name);
}
}
jk_close_pool(&private_data.p);
} else {
jk_log(logger, JK_LOG_ERROR,
"HttpExtensionProc error, not initialized\n");
}
return rc;
}
BOOL WINAPI TerminateExtension(DWORD dwFlags)
{
return TerminateFilter(dwFlags);
}
BOOL WINAPI TerminateFilter(DWORD dwFlags)
{
if(is_inited) {
is_inited = JK_FALSE;
uri_worker_map_free(&uw_map, logger);
wc_close(logger);
if(logger) {
jk_close_file_logger(&logger);
}
}
return TRUE;
}
BOOL WINAPI DllMain(HINSTANCE hInst, // Instance Handle of the DLL
ULONG ulReason, // Reason why NT called this DLL
LPVOID lpReserved) // Reserved parameter for future use
{
BOOL fReturn = TRUE;
switch (ulReason) {
case DLL_PROCESS_DETACH:
__try {
TerminateFilter(HSE_TERM_MUST_UNLOAD);
} __except(1) {
}
break;
default:
break;
}
return fReturn;
}
static int initialize_extension(void)
{
int rc = JK_FALSE;
if(read_registry_init_data()) {
jk_map_t *map;
if(!jk_open_file_logger(&logger, log_file, log_level)) {
logger = NULL;
}
if(map_alloc(&map)) {
if(map_read_properties(map, worker_mount_file)) {
if(uri_worker_map_alloc(&uw_map, map, logger)) {
rc = JK_TRUE;
}
}
map_free(&map);
}
if(rc) {
rc = JK_FALSE;
if(map_alloc(&map)) {
if(map_read_properties(map, worker_file)) {
if(wc_open(map, logger)) {
rc = JK_TRUE;
}
}
map_free(&map);
}
}
}
if(rc) {
is_inited = JK_TRUE;
}
return rc;
}
static int read_registry_init_data(void)
{
char tmpbuf[INTERNET_MAX_URL_LENGTH];
HKEY hkey;
long rc;
int ok = JK_TRUE;
rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
REGISTRY_LOCATION,
(DWORD)0,
KEY_READ,
&hkey);
if(ERROR_SUCCESS != rc) {
return JK_FALSE;
}
if(get_registry_config_parameter(hkey,
JK_LOG_FILE_TAG,
tmpbuf,
sizeof(log_file))) {
strcpy(log_file, tmpbuf);
} else {
ok = JK_FALSE;
}
if(get_registry_config_parameter(hkey,
JK_LOG_LEVEL_TAG,
tmpbuf,
sizeof(tmpbuf))) {
log_level = jk_parse_log_level(tmpbuf);
} else {
ok = JK_FALSE;
}
if(get_registry_config_parameter(hkey,
EXTENSION_URI_TAG,
tmpbuf,
sizeof(extension_uri))) {
strcpy(extension_uri, tmpbuf);
} else {
ok = JK_FALSE;
}
if(get_registry_config_parameter(hkey,
JK_WORKER_FILE_TAG,
tmpbuf,
sizeof(worker_file))) {
strcpy(worker_file, tmpbuf);
} else {
ok = JK_FALSE;
}
if(get_registry_config_parameter(hkey,
JK_MOUNT_FILE_TAG,
tmpbuf,
sizeof(worker_mount_file))) {
strcpy(worker_mount_file, tmpbuf);
} else {
ok = JK_FALSE;
}
RegCloseKey(hkey);
return ok;
}
static int get_registry_config_parameter(HKEY hkey,
const char *tag,
char *b,
DWORD sz)
{
DWORD type = 0;
LONG lrc;
lrc = RegQueryValueEx(hkey,
tag,
(LPDWORD)0,
&type,
(LPBYTE)b,
&sz);
if((ERROR_SUCCESS != lrc) || (type != REG_SZ)) {
return JK_FALSE;
}
b[sz] = '\0';
return JK_TRUE;
}
static int init_ws_service(isapi_private_data_t *private_data,
jk_ws_service_t *s,
char **worker_name)
{
char huge_buf[16 * 1024]; /* should be enough for all */
DWORD huge_buf_sz;
s->jvm_route = NULL;
s->start_response = start_response;
s->read = read;
s->write = write;
GET_SERVER_VARIABLE_VALUE(HTTP_WORKER_HEADER_NAME, (*worker_name));
GET_SERVER_VARIABLE_VALUE(HTTP_URI_HEADER_NAME, s->req_uri);
if(s->req_uri) {
char *t = strchr(s->req_uri, '?');
if(t) {
*t = '\0';
t++;
if(!strlen(t)) {
t = NULL;
}
}
s->query_string = t;
} else {
s->query_string = private_data->lpEcb->lpszQueryString;
*worker_name = JK_AJP12_WORKER_NAME;
GET_SERVER_VARIABLE_VALUE("URL", s->req_uri);
}
GET_SERVER_VARIABLE_VALUE("AUTH_TYPE", s->auth_type);
GET_SERVER_VARIABLE_VALUE("REMOTE_USER", s->remote_user);
GET_SERVER_VARIABLE_VALUE("SERVER_PROTOCOL", s->protocol);
GET_SERVER_VARIABLE_VALUE("REMOTE_HOST", s->remote_host);
GET_SERVER_VARIABLE_VALUE("REMOTE_ADDR", s->remote_addr);
GET_SERVER_VARIABLE_VALUE("SERVER_NAME", s->server_name);
GET_SERVER_VARIABLE_VALUE_INT("SERVER_PORT", s->server_port, 80)
GET_SERVER_VARIABLE_VALUE("SERVER_SOFTWARE", s->server_software);
GET_SERVER_VARIABLE_VALUE_INT("SERVER_PORT_SECURE", s->is_ssl, 0);
s->method = private_data->lpEcb->lpszMethod;
s->content_length = private_data->lpEcb->cbTotalBytes;
s->ssl_cert = NULL;
s->ssl_cert_len = 0;
s->ssl_cipher = NULL;
s->ssl_session = NULL;
s->headers_names = NULL;
s->headers_values = NULL;
s->num_headers = 0;
/*
* Add SSL IIS environment
*/
if(s->is_ssl) {
char *ssl_env_names[9] = {
"CERT_ISSUER",
"CERT_SUBJECT",
"CERT_COOKIE",
"HTTPS_SERVER_SUBJECT",
"CERT_FLAGS",
"HTTPS_SECRETKEYSIZE",
"CERT_SERIALNUMBER",
"HTTPS_SERVER_ISSUER",
"HTTPS_KEYSIZE"
};
char *ssl_env_values[9] = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
unsigned i;
unsigned num_of_vars = 0;
for(i = 0 ; i < 9 ; i++) {
GET_SERVER_VARIABLE_VALUE(ssl_env_names[i], ssl_env_values[i]);
if(ssl_env_values[i]) {
num_of_vars++;
}
}
if(num_of_vars) {
unsigned j;
s->attributes_names =
jk_pool_alloc(&private_data->p, num_of_vars * sizeof(char *));
s->attributes_values =
jk_pool_alloc(&private_data->p, num_of_vars * sizeof(char *));
j = 0;
for(i = 0 ; i < 9 ; i++) {
if(ssl_env_values[i]) {
s->attributes_names[j] = ssl_env_names[i];
s->attributes_values[j] = ssl_env_values[i];
j++;
}
}
s->num_attributes = num_of_vars;
}
}
huge_buf_sz = sizeof(huge_buf);
if(get_server_value(private_data->lpEcb,
"ALL_HTTP",
huge_buf,
huge_buf_sz,
"")) {
unsigned cnt = 0;
char *tmp;
for(tmp = huge_buf ; *tmp ; tmp++) {
if(*tmp == '\n'){
cnt++;
}
}
if(cnt) {
char *headers_buf = jk_pool_strdup(&private_data->p, huge_buf);
unsigned i;
unsigned len_of_http_prefix = strlen("HTTP_");
cnt -= 2; /* For our two special headers */
s->headers_names = jk_pool_alloc(&private_data->p, cnt * sizeof(char *));
s->headers_values = jk_pool_alloc(&private_data->p, cnt * sizeof(char *));
if(!s->headers_names || !s->headers_values || !headers_buf) {
return JK_FALSE;
}
for(i = 0, tmp = headers_buf ; *tmp && i < cnt ; ) {
int real_header = JK_TRUE;
/* Skipp the HTTP_ prefix to the beginning of th header name */
tmp += len_of_http_prefix;
if(!strnicmp(tmp, URI_HEADER_NAME, strlen(URI_HEADER_NAME)) ||
!strnicmp(tmp, WORKER_HEADER_NAME, strlen(WORKER_HEADER_NAME))) {
real_header = JK_FALSE;
} else {
s->headers_names[i] = tmp;
}
while(':' != *tmp && *tmp) {
if('_' == *tmp) {
*tmp = '-';
} else {
*tmp = tolower(*tmp);
}
tmp++;
}
*tmp = '\0';
tmp++;
/* Skipp all the WS chars after the ':' to the beginning of th header value */
while(' ' == *tmp || '\t' == *tmp || '\v' == *tmp) {
tmp++;
}
if(real_header) {
s->headers_values[i] = tmp;
}
while(*tmp != '\n' && *tmp != '\r') {
tmp++;
}
*tmp = '\0';
tmp++;
/* skipp CR LF */
while(*tmp == '\n' || *tmp == '\r') {
tmp++;
}
if(real_header) {
i++;
}
}
s->num_headers = cnt;
} else {
/* We must have our two headers */
return JK_FALSE;
}
} else {
return JK_FALSE;
}
return JK_TRUE;
}
static int get_server_value(LPEXTENSION_CONTROL_BLOCK lpEcb,
char *name,
char *buf,
DWORD bufsz,
char *def_val)
{
if(!lpEcb->GetServerVariable(lpEcb->ConnID,
name,
buf,
(LPDWORD)&bufsz)) {
strcpy(buf, def_val);
return JK_FALSE;
}
if(bufsz > 0) {
buf[bufsz - 1] = '\0';
}
return JK_TRUE;
}
1.1 jakarta-tomcat/src/native/mod_jk/jni/Makefile.solaris
Index: Makefile.solaris
===================================================================
# Defines for example NSAPI programs running under SOLARIS
CC_CMD=gcc -DSOLARIS -D_REENTRANT
LD_SHAREDCMD=ld -G
all:
prepare:
OS_TYPE=solaris
INCLUDEDIR=../common
JAVA_INCLUDE=$(JAVA_HOME)/include
JK_OBJS = ../common/jk_map.o ../common/jk_util.o ../common/jk_pool.o jk_jnicb.o
INCLUDE_FLAGS=-I$(INCLUDEDIR) -I$(JAVA_INCLUDE) -I$(JAVA_INCLUDE)/$(OS_TYPE)
COMMON_DEFS=-Wall
all: jni_connect.so
jni_connect.so: $(JK_OBJS)
$(MAKE) prepare
$(LD_SHAREDCMD) $(JK_OBJS) -o jni_connect.so $(EXTRA_LDDEFINES)
.c.o:
$(CC_CMD) $(COMMON_DEFS) $(INCLUDE_FLAGS) -c $<
clean:
rm $(JK_OBJS)
1.1 jakarta-tomcat/src/native/mod_jk/jni/jk_jnicb.c
Index: jk_jnicb.c
===================================================================
/*
* Copyright (c) 1997-1999 The Java Apache Project. 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. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Java Apache
* Project for use in the Apache JServ servlet engine project
* <http://java.apache.org/>."
*
* 4. The names "Apache JServ", "Apache JServ Servlet Engine" and
* "Java Apache Project" must not be used to endorse or promote products
* derived from this software without prior written permission.
*
* 5. Products derived from this software may not be called "Apache JServ"
* nor may "Apache" nor "Apache JServ" appear in their names without
* prior written permission of the Java Apache Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Java Apache
* Project for use in the Apache JServ servlet engine project
* <http://java.apache.org/>."
*
* THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "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 JAVA APACHE PROJECT 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 Java Apache Group. For more information
* on the Java Apache Project and the Apache JServ Servlet Engine project,
* please see <http://java.apache.org/>.
*
*/
/***************************************************************************
* Description: JNI callbacks implementation for the JNI in process adapter*
* Author: Gal Shachor <sh...@il.ibm.com> *
* Version: $Revision: 1.1 $ *
***************************************************************************/
#include "jk_jnicb.h"
#include "jk_service.h"
#include "jk_util.h"
#include "jk_pool.h"
/*
* Class: org_apache_tomcat_service_connector_JNIConnectionHandler
* Method: getNumberOfHeaders
* Signature: (JJ)I
*/
JNIEXPORT jint JNICALL
Java_org_apache_tomcat_service_connector_JNIConnectionHandler_getNumberOfHeaders
(JNIEnv *env, jobject o, jlong s, jlong l)
{
/* [V] Convert indirectly from jlong -> int -> pointer to shut up gcc */
/* I hope it's okay on other compilers and/or machines... */
jk_ws_service_t *ps = (jk_ws_service_t *)(int)s;
jk_logger_t *pl = (jk_logger_t *)(int)l;
jk_log(pl, JK_LOG_DEBUG, "Into JNIConnectionHandler::getNumberOfHeaders\n");
if(!ps) {
jk_log(pl, JK_LOG_ERROR,
"In JNIConnectionHandler::getNumberOfHeaders, NULL ws service object\n");
/* [V] JNIConnectionHandler doesn't handle this */
return -1;
}
jk_log(pl, JK_LOG_DEBUG,
"Done JNIConnectionHandler::getNumberOfHeaders, found %d headers\n",
ps->num_headers);
return (jint)ps->num_headers;
}
/*
* Class: org_apache_tomcat_service_connector_JNIConnectionHandler
* Method: read
* Signature: (JJ[BII)I
*/
JNIEXPORT jint JNICALL
Java_org_apache_tomcat_service_connector_JNIConnectionHandler_read
(JNIEnv *env, jobject o, jlong s, jlong l, jbyteArray buf, jint from, jint cnt)
{
jk_ws_service_t *ps = (jk_ws_service_t *)(int)s;
jk_logger_t *pl = (jk_logger_t *)(int)l;
jint rc = -1;
jboolean iscommit;
jbyte *nbuf;
unsigned nfrom = (unsigned)from;
unsigned ncnt = (unsigned)cnt;
unsigned acc = 0;
jk_log(pl, JK_LOG_DEBUG, "Into JNIConnectionHandler::read\n");
if(!ps) {
jk_log(pl, JK_LOG_ERROR,
"In JNIConnectionHandler::read, NULL ws service object\n");
return -1;
}
nbuf = (*env)->GetByteArrayElements(env, buf, &iscommit);
if(!nbuf) {
jk_log(pl, JK_LOG_ERROR,
"In JNIConnectionHandler::read, GetByteArrayElements error\n");
return -1;
}
if(!ps->read(ps, nbuf + nfrom, ncnt, &acc)) {
jk_log(pl, JK_LOG_ERROR,
"In JNIConnectionHandler::read, failed to read from web server\n");
} else {
rc = (jint)acc;
}
(*env)->ReleaseByteArrayElements(env, buf, nbuf, 0);
jk_log(pl, JK_LOG_DEBUG, "Done JNIConnectionHandler::read\n");
return rc;
}
/*
* Class: org_apache_tomcat_service_connector_JNIConnectionHandler
* Method: readEnvironment
* Signature: (JJ[Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL
Java_org_apache_tomcat_service_connector_JNIConnectionHandler_readEnvironment
(JNIEnv *env, jobject o, jlong s, jlong l, jobjectArray envbuf)
{
jk_ws_service_t *ps = (jk_ws_service_t *)(int)s;
jk_logger_t *pl = (jk_logger_t *)(int)l;
char port[10];
jk_log(pl, JK_LOG_DEBUG,
"Into JNIConnectionHandler::readEnvironment. Environment follows --->\n");
if(!ps) {
jk_log(pl, JK_LOG_ERROR,
"In JNIConnectionHandler::readEnvironment, NULL ws service object\n");
return JK_FALSE;
}
sprintf(port, "%d", ps->server_port);
if(ps->method) {
(*env)->SetObjectArrayElement(env,
envbuf,
0,
(*env)->NewStringUTF(env, ps->method));
jk_log(pl, JK_LOG_DEBUG, "---> method: %s\n", ps->method);
}
if(ps->req_uri) {
(*env)->SetObjectArrayElement(env,
envbuf,
1,
(*env)->NewStringUTF(env, ps->req_uri));
jk_log(pl, JK_LOG_DEBUG, "---> req_uri: %s\n", ps->req_uri);
}
if(ps->query_string) {
(*env)->SetObjectArrayElement(env,
envbuf,
2,
(*env)->NewStringUTF(env, ps->query_string));
jk_log(pl, JK_LOG_DEBUG, "---> query_string: %s\n", ps->query_string);
}
if(ps->remote_addr) {
(*env)->SetObjectArrayElement(env,
envbuf,
3,
(*env)->NewStringUTF(env, ps->remote_addr));
jk_log(pl, JK_LOG_DEBUG, "---> remote_addr: %s\n", ps->remote_addr);
}
if(ps->remote_host) {
(*env)->SetObjectArrayElement(env,
envbuf,
4,
(*env)->NewStringUTF(env, ps->remote_host));
jk_log(pl, JK_LOG_DEBUG, "---> remote_host: %s\n", ps->remote_host);
}
if(ps->server_name) {
(*env)->SetObjectArrayElement(env,
envbuf,
5,
(*env)->NewStringUTF(env, ps->server_name));
jk_log(pl, JK_LOG_DEBUG, "---> server_name: %s\n", ps->server_name);
}
(*env)->SetObjectArrayElement(env,
envbuf,
6,
(*env)->NewStringUTF(env, port));
jk_log(pl, JK_LOG_DEBUG, "---> server_port: %s\n", port);
if(ps->auth_type) {
(*env)->SetObjectArrayElement(env,
envbuf,
7,
(*env)->NewStringUTF(env, ps->auth_type));
jk_log(pl, JK_LOG_DEBUG, "---> auth_type: %s\n", ps->auth_type);
}
if(ps->remote_user) {
(*env)->SetObjectArrayElement(env,
envbuf,
8,
(*env)->NewStringUTF(env, ps->remote_user));
jk_log(pl, JK_LOG_DEBUG, "---> remote_user: %s\n", ps->remote_user);
}
if(ps->is_ssl) {
(*env)->SetObjectArrayElement(env,
envbuf,
9,
(*env)->NewStringUTF(env, "https"));
} else {
(*env)->SetObjectArrayElement(env,
envbuf,
9,
(*env)->NewStringUTF(env, "http"));
}
jk_log(pl, JK_LOG_DEBUG, "---> is_ssl: %s\n", ps->is_ssl ? "yes" : "no");
if(ps->protocol) {
(*env)->SetObjectArrayElement(env,
envbuf,
10,
(*env)->NewStringUTF(env, ps->protocol));
jk_log(pl, JK_LOG_DEBUG, "---> protocol: %s\n", ps->protocol);
}
if(ps->server_software) {
(*env)->SetObjectArrayElement(env,
envbuf,
11,
(*env)->NewStringUTF(env, ps->server_software));
jk_log(pl, JK_LOG_DEBUG, "---> server_software: %s\n", ps->server_software);
}
if(ps->is_ssl) {
if(ps->ssl_cert) {
(*env)->SetObjectArrayElement(env,
envbuf,
12,
(*env)->NewStringUTF(env, ps->ssl_cert));
jk_log(pl, JK_LOG_DEBUG, "---> ssl_cert: %s\n", ps->ssl_cert);
}
if(ps->ssl_cipher) {
(*env)->SetObjectArrayElement(env,
envbuf,
13,
(*env)->NewStringUTF(env, ps->ssl_cipher));
jk_log(pl, JK_LOG_DEBUG, "---> ssl_cipher: %s\n", ps->ssl_cipher);
}
if(ps->ssl_session) {
(*env)->SetObjectArrayElement(env,
envbuf,
14,
(*env)->NewStringUTF(env, ps->ssl_session));
jk_log(pl, JK_LOG_DEBUG, "---> ssl_session: %s\n", ps->ssl_session);
}
}
jk_log(pl, JK_LOG_DEBUG,
"Done JNIConnectionHandler::readEnvironment\n");
return JK_TRUE;
}
/*
* Class: org_apache_tomcat_service_connector_JNIConnectionHandler
* Method: readHeaders
* Signature: (JJ[Ljava/lang/String;[Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL
Java_org_apache_tomcat_service_connector_JNIConnectionHandler_readHeaders
(JNIEnv *env, jobject o, jlong s, jlong l, jobjectArray hnames, jobjectArray hvalues)
{
jk_ws_service_t *ps = (jk_ws_service_t *)(int)s;
jk_logger_t *pl = (jk_logger_t *)(int)l;
unsigned i;
jk_log(pl, JK_LOG_DEBUG, "Into JNIConnectionHandler::readHeaders\n");
if(!ps) {
jk_log(pl, JK_LOG_ERROR,
"In JNIConnectionHandler::readHeaders, NULL ws service object\n");
return JK_FALSE;
}
jk_log(pl, JK_LOG_DEBUG, "In JNIConnectionHandler::readHeaders, %d headers follow --->\n",
ps->num_headers);
for(i = 0 ; i < ps->num_headers ; i++) {
(*env)->SetObjectArrayElement(env,
hnames,
i,
(*env)->NewStringUTF(env, ps->headers_names[i]));
(*env)->SetObjectArrayElement(env,
hvalues,
i,
(*env)->NewStringUTF(env, ps->headers_values[i]));
jk_log(pl, JK_LOG_DEBUG, "---> %s = %s\n",
ps->headers_names[i], ps->headers_values[i]);
}
jk_log(pl, JK_LOG_DEBUG,
"Done JNIConnectionHandler::readHeaders\n");
return JK_TRUE;
}
/*
* Class: org_apache_tomcat_service_connector_JNIConnectionHandler
* Method: startReasponse
* Signature: (JJILjava/lang/String;[Ljava/lang/String;[Ljava/lang/String;I)I
*/
JNIEXPORT jint JNICALL
Java_org_apache_tomcat_service_connector_JNIConnectionHandler_startReasponse
(JNIEnv *env, jobject o, jlong s, jlong l,
jint sc, jstring msg, jobjectArray hnames, jobjectArray hvalues, jint hcnt)
{
jk_ws_service_t *ps = (jk_ws_service_t *)(int)s;
jk_logger_t *pl = (jk_logger_t *)(int)l;
const char *nmsg = NULL;
char **nhnames = NULL;
char **nhvalues = NULL;
jstring *shnames = NULL;
jstring *shvalues = NULL;
int i = 0;
int ok = JK_TRUE;
jk_log(pl, JK_LOG_DEBUG, "Into JNIConnectionHandler::startReasponse\n");
if(!ps) {
jk_log(pl, JK_LOG_ERROR,
"In JNIConnectionHandler::startReasponse, NULL ws service object\n");
return JK_FALSE;
}
jk_log(pl, JK_LOG_DEBUG, "In JNIConnectionHandler::startReasponse, %d headers follow --->\n",
hcnt);
if(hcnt) {
ok = JK_FALSE;
nhnames = (char **)jk_pool_alloc(ps->pool, hcnt * sizeof(char *));
nhvalues = (char **)jk_pool_alloc(ps->pool, hcnt * sizeof(char *));
shnames = (jstring *)jk_pool_alloc(ps->pool, hcnt * sizeof(jstring));
shvalues = (jstring *)jk_pool_alloc(ps->pool, hcnt * sizeof(jstring));
if(nhvalues && nhnames && shnames && shnames) {
for( ; i < hcnt ; i++) {
jboolean iscommit;
shvalues[i] = shnames[i] = NULL;
nhnames[i] = nhvalues[i] = NULL;
shnames[i] = (*env)->GetObjectArrayElement(env, hnames, i);
shvalues[i] = (*env)->GetObjectArrayElement(env, hvalues, i);
if(!shvalues[i] || !shnames[i]) {
jk_log(pl, JK_LOG_ERROR,
"In JNIConnectionHandler::startReasponse, GetObjectArrayElement error\n");
break;
}
nhnames[i] = (char *)(*env)->GetStringUTFChars(env, shnames[i], &iscommit);
nhvalues[i] = (char *)(*env)->GetStringUTFChars(env, shvalues[i], &iscommit);
if(!nhvalues[i] || !nhnames[i]) {
jk_log(pl, JK_LOG_ERROR,
"In JNIConnectionHandler::startReasponse, GetStringUTFChars error\n");
break;
}
jk_log(pl, JK_LOG_DEBUG, "---> %s=%s\n", nhnames[i], nhvalues[i]);
}
if(i == hcnt) {
ok = JK_TRUE;
jk_log(pl, JK_LOG_DEBUG,
"In JNIConnectionHandler::startReasponse. ----- End headers.\n", hcnt);
}
} else {
jk_log(pl, JK_LOG_ERROR,
"In JNIConnectionHandler::startReasponse, memory allocation error\n");
}
}
if(msg && ok) {
jboolean iscommit;
nmsg = (*env)->GetStringUTFChars(env, msg, &iscommit);
if(!nmsg) {
ok = JK_FALSE;
}
}
if(ok) {
if(!ps->start_response(ps, sc, nmsg, (const char**)nhnames, (const char**)nhvalues, hcnt)) {
ok = JK_FALSE;
jk_log(pl, JK_LOG_ERROR,
"In JNIConnectionHandler::startReasponse, servers startReasponse failed\n");
}
}
if(nmsg) {
(*env)->ReleaseStringUTFChars(env, msg, nmsg);
}
if(i < hcnt) {
i++;
}
if(nhvalues) {
int j;
for(j = 0 ; j < i ; j++) {
if(nhvalues[j]) {
(*env)->ReleaseStringUTFChars(env, shvalues[j], nhvalues[j]);
}
}
}
if(nhnames) {
int j;
for(j = 0 ; j < i ; j++) {
if(nhnames[j]) {
(*env)->ReleaseStringUTFChars(env, shnames[j], nhnames[j]);
}
}
}
jk_log(pl, JK_LOG_DEBUG, "Done JNIConnectionHandler::startReasponse.\n");
return ok;
}
/*
* Class: org_apache_tomcat_service_connector_JNIConnectionHandler
* Method: write
* Signature: (JJ[BII)I
*/
JNIEXPORT jint JNICALL
Java_org_apache_tomcat_service_connector_JNIConnectionHandler_write
(JNIEnv *env, jobject o, jlong s, jlong l, jbyteArray buf, jint from, jint cnt)
{
jk_ws_service_t *ps = (jk_ws_service_t *)(int)s;
jk_logger_t *pl = (jk_logger_t *)(int)l;
jint rc = JK_FALSE;
jboolean iscommit;
jbyte *nbuf;
unsigned nfrom = (unsigned)from;
unsigned ncnt = (unsigned)cnt;
jk_log(pl, JK_LOG_DEBUG,
"In JNIConnectionHandler::write\n");
if(!ps) {
jk_log(pl, JK_LOG_ERROR,
"In JNIConnectionHandler::write, NULL ws service object\n");
return JK_FALSE;
}
nbuf = (*env)->GetByteArrayElements(env, buf, &iscommit);
if(!nbuf) {
jk_log(pl, JK_LOG_ERROR,
"In JNIConnectionHandler::write, GetByteArrayElements error\n");
return JK_FALSE;
}
if(!ps->write(ps, nbuf + nfrom, ncnt)) {
jk_log(pl, JK_LOG_ERROR,
"In JNIConnectionHandler::write, failed to write to the web server\n");
} else {
rc = (jint)JK_TRUE;
}
(*env)->ReleaseByteArrayElements(env, buf, nbuf, JNI_ABORT);
return rc;
}
1.1 jakarta-tomcat/src/native/mod_jk/jni/jk_jnicb.h
Index: jk_jnicb.h
===================================================================
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_apache_tomcat_service_connector_JNIConnectionHandler */
#ifndef _Included_org_apache_tomcat_service_connector_JNIConnectionHandler
#define _Included_org_apache_tomcat_service_connector_JNIConnectionHandler
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_apache_tomcat_service_connector_JNIConnectionHandler
* Method: getNumberOfHeaders
* Signature: (JJ)I
*/
JNIEXPORT jint JNICALL Java_org_apache_tomcat_service_connector_JNIConnectionHandler_getNumberOfHeaders
(JNIEnv *, jobject, jlong, jlong);
/*
* Class: org_apache_tomcat_service_connector_JNIConnectionHandler
* Method: read
* Signature: (JJ[BII)I
*/
JNIEXPORT jint JNICALL Java_org_apache_tomcat_service_connector_JNIConnectionHandler_read
(JNIEnv *, jobject, jlong, jlong, jbyteArray, jint, jint);
/*
* Class: org_apache_tomcat_service_connector_JNIConnectionHandler
* Method: readEnvironment
* Signature: (JJ[Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_org_apache_tomcat_service_connector_JNIConnectionHandler_readEnvironment
(JNIEnv *, jobject, jlong, jlong, jobjectArray);
/*
* Class: org_apache_tomcat_service_connector_JNIConnectionHandler
* Method: readHeaders
* Signature: (JJ[Ljava/lang/String;[Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_org_apache_tomcat_service_connector_JNIConnectionHandler_readHeaders
(JNIEnv *, jobject, jlong, jlong, jobjectArray, jobjectArray);
/*
* Class: org_apache_tomcat_service_connector_JNIConnectionHandler
* Method: startReasponse
* Signature: (JJILjava/lang/String;[Ljava/lang/String;[Ljava/lang/String;I)I
*/
JNIEXPORT jint JNICALL Java_org_apache_tomcat_service_connector_JNIConnectionHandler_startReasponse
(JNIEnv *, jobject, jlong, jlong, jint, jstring, jobjectArray, jobjectArray, jint);
/*
* Class: org_apache_tomcat_service_connector_JNIConnectionHandler
* Method: write
* Signature: (JJ[BII)I
*/
JNIEXPORT jint JNICALL Java_org_apache_tomcat_service_connector_JNIConnectionHandler_write
(JNIEnv *, jobject, jlong, jlong, jbyteArray, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
1.1 jakarta-tomcat/src/native/mod_jk/jni/jni_connect.dsp
Index: jni_connect.dsp
===================================================================
# Microsoft Developer Studio Project File - Name="jni_connect" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=jni_connect - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "jni_connect.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "jni_connect.mak" CFG="jni_connect - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "jni_connect - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "jni_connect - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "jni_connect - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "release"
# PROP Intermediate_Dir "release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JNI_CONNECT_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /I "..\jk" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JNI_CONNECT_EXPORTS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
!ELSEIF "$(CFG)" == "jni_connect - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "debug"
# PROP Intermediate_Dir "debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JNI_CONNECT_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /I "..\jk" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JNI_CONNECT_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "jni_connect - Win32 Release"
# Name "jni_connect - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\jk_jnicb.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_map.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_pool.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_util.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\jk\jk_ajp12_worker.h
# End Source File
# Begin Source File
SOURCE=..\jk\jk_global.h
# End Source File
# Begin Source File
SOURCE=.\jk_jnicb.h
# End Source File
# Begin Source File
SOURCE=..\jk\jk_logger.h
# End Source File
# Begin Source File
SOURCE=..\jk\jk_map.h
# End Source File
# Begin Source File
SOURCE=..\jk\jk_pool.h
# End Source File
# Begin Source File
SOURCE=..\jk\jk_service.h
# End Source File
# Begin Source File
SOURCE=..\jk\jk_util.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project
1.1 jakarta-tomcat/src/native/mod_jk/jni/jni_connect.dsw
Index: jni_connect.dsw
===================================================================
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "jni_connect"=.\jni_connect.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
1.1 jakarta-tomcat/src/native/mod_jk/netscape/Makefile.solaris
Index: Makefile.solaris
===================================================================
# Defines for example NSAPI programs running under SOLARIS
CC_CMD=gcc -DNET_SSL -DSOLARIS -D_REENTRANT
LD_SHAREDCMD=ld -G
all:
prepare:
OS_TYPE=solaris
INCLUDEDIR=$(SUITSPOT_HOME)/include
JAVA_INCLUDE=$(JAVA_HOME)/include
JK_OBJS = jk_ajp12_worker.o jk_lb_worker.o jk_sockbuf.o jk_connect.o jk_map.o \
jk_uri_worker_map.o jk_nsapi_plugin.o jk_util.o jk_jni_worker.o \
jk_pool.o jk_worker.o
INCLUDE_FLAGS=-I$(INCLUDEDIR) -I$(INCLUDEDIR)/base -I$(INCLUDEDIR)/frame -I$(JAVA_INCLUDE) -I$(JAVA_INCLUDE)/$(OS_TYPE)
COMMON_DEFS=-DMCC_HTTPD -DXP_UNIX -DSPAPI20 -DSOLARIS -Wall
all: nsapi_redirector.so
nsapi_redirector.so: $(JK_OBJS)
$(MAKE) prepare
$(LD_SHAREDCMD) $(JK_OBJS) -o nsapi_redirector.so $(EXTRA_LDDEFINES)
.c.o:
$(CC_CMD) $(COMMON_DEFS) $(INCLUDE_FLAGS) -c $<
clean:
rm $(JK_OBJS)
1.1 jakarta-tomcat/src/native/mod_jk/netscape/jk_nsapi_plugin.c
Index: jk_nsapi_plugin.c
===================================================================
/*
* Copyright (c) 1997-1999 The Java Apache Project. 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. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Java Apache
* Project for use in the Apache JServ servlet engine project
* <http://java.apache.org/>."
*
* 4. The names "Apache JServ", "Apache JServ Servlet Engine" and
* "Java Apache Project" must not be used to endorse or promote products
* derived from this software without prior written permission.
*
* 5. Products derived from this software may not be called "Apache JServ"
* nor may "Apache" nor "Apache JServ" appear in their names without
* prior written permission of the Java Apache Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Java Apache
* Project for use in the Apache JServ servlet engine project
* <http://java.apache.org/>."
*
* THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "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 JAVA APACHE PROJECT 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 Java Apache Group. For more information
* on the Java Apache Project and the Apache JServ Servlet Engine project,
* please see <http://java.apache.org/>.
*
*/
/***************************************************************************
* Description: NSAPI plugin for Netscape servers *
* Author: Gal Shachor <sh...@il.ibm.com> *
* Version: $Revision: 1.1 $ *
***************************************************************************/
#include "jk_global.h"
#include "jk_util.h"
#include "jk_map.h"
#include "jk_pool.h"
#include "jk_service.h"
#include "jk_worker.h"
#include "jk_ajp12_worker.h"
#include "nsapi.h"
#define URI_PATTERN "path"
struct nsapi_private_data {
jk_pool_t p;
int request_started;
pblock *pb;
Session *sn;
Request *rq;
};
typedef struct nsapi_private_data nsapi_private_data_t;
static int init_on_other_thread_is_done = JK_FALSE;
static int init_on_other_thread_is_ok = JK_FALSE;
static jk_logger_t *logger = NULL;
static int JK_METHOD start_response(jk_ws_service_t *s,
int status,
const char *reason,
const char * const *header_names,
const char * const *header_values,
unsigned num_of_headers);
static int JK_METHOD ws_read(jk_ws_service_t *s,
void *b,
unsigned l,
unsigned *a);
static int JK_METHOD ws_write(jk_ws_service_t *s,
const void *b,
unsigned l);
NSAPI_PUBLIC int jk_init(pblock *pb,
Session *sn,
Request *rq);
NSAPI_PUBLIC void jk_term(void *p);
NSAPI_PUBLIC int jk_service(pblock *pb,
Session *sn,
Request *rq);
static int init_ws_service(nsapi_private_data_t *private_data,
jk_ws_service_t *s);
static int setup_http_headers(nsapi_private_data_t *private_data,
jk_ws_service_t *s);
static void init_workers_on_other_threads(void *init_d)
{
jk_map_t *init_map = (jk_map_t *)init_d;
if(wc_open(init_map, logger)) {
init_on_other_thread_is_ok = JK_TRUE;
} else {
jk_log(logger, JK_LOG_EMERG, "In init_workers_on_other_threads, failed\n");
}
init_on_other_thread_is_done = JK_TRUE;
}
static int JK_METHOD start_response(jk_ws_service_t *s,
int status,
const char *reason,
const char * const *header_names,
const char * const *header_values,
unsigned num_of_headers)
{
if(s && s->ws_private) {
nsapi_private_data_t *p = s->ws_private;
if(!p->request_started) {
unsigned i;
p->request_started = JK_TRUE;
/* Remove "old" content type */
param_free(pblock_remove("content-type", p->rq->srvhdrs));
if(num_of_headers) {
for (i = 0 ; i < (int)num_of_headers ; i++) {
pblock_nvinsert(header_names[i],
header_values[i],
p->rq->srvhdrs);
}
} else {
pblock_nvinsert("content-type",
"text/plain",
p->rq->srvhdrs);
}
protocol_status(p->sn,
p->rq,
status,
(char *)reason);
protocol_start_response(p->sn, p->rq);
}
return JK_TRUE;
}
return JK_FALSE;
}
static int JK_METHOD ws_read(jk_ws_service_t *s,
void *b,
unsigned l,
unsigned *a)
{
if(s && s->ws_private && b && a) {
nsapi_private_data_t *p = s->ws_private;
*a = 0;
if(l) {
char *buf = b;
unsigned i;
netbuf *inbuf = p->sn->inbuf;
#ifdef netbuf_getbytes
i = netbuf_getbytes(inbuf, b, l);
if(NETBUF_EOF == i || NETBUF_ERROR == i) {
return JK_FALSE;
}
#else
int ch;
for(i = 0 ; i < l ; i++) {
ch = netbuf_getc(inbuf);
/*
* IO_EOF is 0 (zero) which is a very reasonable byte
* when it comes to binary data. So we are not breaking
* out of the read loop when reading it.
*
* We are protected from an infinit loop by the Java part of
* Tomcat.
*/
if(IO_ERROR == ch) {
break;
}
buf[i] = ch;
}
if(0 == i) {
return JK_FALSE;
}
#endif
*a = i;
}
return JK_TRUE;
}
return JK_FALSE;
}
static int JK_METHOD ws_write(jk_ws_service_t *s,
const void *b,
unsigned l)
{
if(s && s->ws_private && b) {
nsapi_private_data_t *p = s->ws_private;
if(l) {
if(!p->request_started) {
start_response(s, 200, NULL, NULL, NULL, 0);
}
if(net_write(p->sn->csd, (char *)b, (int)l) == IO_ERROR) {
return JK_FALSE;
}
}
return JK_TRUE;
}
return JK_FALSE;
}
NSAPI_PUBLIC int jk_init(pblock *pb,
Session *sn,
Request *rq)
{
char *worker_prp_file = pblock_findval(JK_WORKER_FILE_TAG, pb);
char *log_level_str = pblock_findval(JK_LOG_LEVEL_TAG, pb);
char *log_file = pblock_findval(JK_LOG_FILE_TAG, pb);
int rc = REQ_ABORTED;
jk_map_t *init_map;
fprintf(stderr, "In jk_init %s %s %s\n",worker_prp_file, log_level_str, log_file);
if(!worker_prp_file) {
worker_prp_file = JK_WORKER_FILE_DEF;
}
if(!log_level_str) {
log_level_str = JK_LOG_LEVEL_DEF;
}
if(!jk_open_file_logger(&logger, log_file,
jk_parse_log_level(log_level_str))) {
logger = NULL;
}
if(map_alloc(&init_map)) {
if(map_read_properties(init_map, worker_prp_file)) {
int sleep_cnt;
SYS_THREAD s;
s = systhread_start(SYSTHREAD_DEFAULT_PRIORITY,
0,
init_workers_on_other_threads,
init_map);
for(sleep_cnt = 0 ; sleep_cnt < 60 ; sleep_cnt++) {
systhread_sleep(1000);
jk_log(logger, JK_LOG_DEBUG, "jk_init, a second passed\n");
if(init_on_other_thread_is_done) {
break;
}
}
if(init_on_other_thread_is_done &&
init_on_other_thread_is_ok) {
magnus_atrestart(jk_term, NULL);
rc = REQ_PROCEED;
}
/* if(wc_open(init_map, logger)) {
magnus_atrestart(jk_term, NULL);
rc = REQ_PROCEED;
}
*/
}
map_free(&init_map);
}
return rc;
}
NSAPI_PUBLIC void jk_term(void *p)
{
wc_close(logger);
if(logger) {
jk_close_file_logger(&logger);
}
}
NSAPI_PUBLIC int jk_service(pblock *pb,
Session *sn,
Request *rq)
{
char *worker_name = pblock_findval(JK_WORKER_NAME_TAG, pb);
char *uri_pattern = pblock_findval(URI_PATTERN, pb);
jk_worker_t *worker;
int rc = REQ_ABORTED;
if(uri_pattern) {
char *uri = pblock_findval("uri", rq->reqpb);
if(0 != shexp_match(uri, uri_pattern)) {
return REQ_NOACTION;
}
}
if(!worker_name) {
worker_name = JK_AJP12_WORKER_NAME;
}
worker = wc_get_worker_for_name(worker_name, logger);
if(worker) {
nsapi_private_data_t private_data;
jk_ws_service_t s;
jk_pool_atom_t buf[SMALL_POOL_SIZE];
jk_open_pool(&private_data.p, buf, sizeof(buf));
private_data.request_started = JK_FALSE;
private_data.pb = pb;
private_data.sn = sn;
private_data.rq = rq;
jk_init_ws_service(&s);
s.ws_private = &private_data;
s.pool = &private_data.p;
if(init_ws_service(&private_data, &s)) {
jk_endpoint_t *e = NULL;
if(worker->get_endpoint(worker, &e, logger)) {
int recover = JK_FALSE;
if(e->service(e, &s, logger, &recover)) {
rc = REQ_PROCEED;
}
e->done(&e, logger);
}
}
jk_close_pool(&private_data.p);
}
return rc;
}
static int init_ws_service(nsapi_private_data_t *private_data,
jk_ws_service_t *s)
{
char *tmp;
int rc;
s->jvm_route = NULL;
s->start_response = start_response;
s->read = ws_read;
s->write = ws_write;
s->auth_type = pblock_findval("auth-type", private_data->rq->vars);
s->remote_user = pblock_findval("auth-user", private_data->rq->vars);
s->content_length = 0;
tmp = NULL;
rc = request_header("content-length",
&tmp,
private_data->sn,
private_data->rq);
if((rc != REQ_ABORTED) && tmp) {
s->content_length = atoi(tmp);
}
s->method = pblock_findval("method", private_data->rq->reqpb);
s->protocol = pblock_findval("protocol", private_data->rq->reqpb);
s->remote_host = session_dns(private_data->sn);
s->remote_addr = pblock_findval("ip", private_data->sn->client);
s->req_uri = pblock_findval("uri", private_data->rq->reqpb);
s->query_string = pblock_findval("query", private_data->rq->reqpb);
s->server_name = server_hostname;
s->server_port = server_portnum;
s->server_software = system_version();
s->headers_names = NULL;
s->headers_values = NULL;
s->num_headers = 0;
s->is_ssl = security_active;
if(s->is_ssl) {
s->ssl_cert = pblock_findval("auth-cert", private_data->rq->vars);
if(s->ssl_cert) {
s->ssl_cert_len = strlen(s->ssl_cert);
}
s->ssl_cipher = pblock_findval("cipher", private_data->sn->client);
s->ssl_session = pblock_findval("ssl-id", private_data->sn->client);
} else {
s->ssl_cert = NULL;
s->ssl_cert_len = 0;
s->ssl_cipher = NULL;
s->ssl_session = NULL;
}
return setup_http_headers(private_data, s);
}
static int setup_http_headers(nsapi_private_data_t *private_data,
jk_ws_service_t *s)
{
pblock *headers_jar = private_data->rq->headers;
int cnt;
int i;
for(i = 0, cnt = 0 ; i < headers_jar->hsize ; i++) {
struct pb_entry *h = headers_jar->ht[i];
while(h && h->param) {
cnt++;
h = h->next;
}
}
if(cnt) {
s->headers_names = jk_pool_alloc(&private_data->p, cnt * sizeof(char *));
s->headers_values = jk_pool_alloc(&private_data->p, cnt * sizeof(char *));
if(s->headers_names && s->headers_values) {
for(i = 0, cnt = 0 ; i < headers_jar->hsize ; i++) {
struct pb_entry *h = headers_jar->ht[i];
while(h && h->param) {
s->headers_names[cnt] = h->param->name;
s->headers_values[cnt] = h->param->value;
cnt++;
h = h->next;
}
}
s->num_headers = cnt;
return JK_TRUE;
}
} else {
s->num_headers = cnt;
s->headers_names = NULL;
s->headers_values = NULL;
return JK_TRUE;
}
return JK_FALSE;
}
1.1 jakarta-tomcat/src/native/mod_jk/netscape/nsapi.dsp
Index: nsapi.dsp
===================================================================
# Microsoft Developer Studio Project File - Name="nsapi" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=nsapi - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "nsapi.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "nsapi.mak" CFG="nsapi - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "nsapi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "nsapi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "nsapi - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "nsapi_release"
# PROP Intermediate_Dir "nsapi_release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NSAPI_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\common" /I "$(NS_HOME)\include" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NSAPI_EXPORTS" /D "XP_WIN32" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 wsock32.lib ns-httpd36.lib /nologo /dll /machine:I386 /out:"nsapi_release/nsapi_redirect.dll" /libpath:"$(NS_HOME)\lib"
!ELSEIF "$(CFG)" == "nsapi - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "nsapi___Win32_Debug"
# PROP BASE Intermediate_Dir "nsapi___Win32_Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "nsapi_debug"
# PROP Intermediate_Dir "nsapi_debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NSAPI_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\common" /I "$(NS_HOME)\include" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NSAPI_EXPORTS" /D "XP_WIN32" /D "MCC_HTTPD" /D "SPAPI20" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 wsock32.lib ns-httpd36.lib /nologo /dll /debug /machine:I386 /out:"nsapi_debug/nsapi_redirect.dll" /pdbtype:sept /libpath:"$(NS_HOME)\lib"
!ENDIF
# Begin Target
# Name "nsapi - Win32 Release"
# Name "nsapi - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\common\jk_ajp12_worker.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_ajp13.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_ajp13_worker.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_connect.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_jni_worker.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_lb_worker.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_map.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_msg_buff.c
# End Source File
# Begin Source File
SOURCE=.\jk_nsapi_plugin.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_pool.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_sockbuf.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_uri_worker_map.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_util.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_worker.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\common\jk_ajp12_worker.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_ajp13.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_ajp13_worker.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_connect.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_global.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_jni_worker.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_lb_worker.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_logger.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_map.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_msg_buff.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_mt.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_pool.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_service.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_sockbuf.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_uri_worker_map.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_util.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_worker.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_worker_list.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project
1.1 jakarta-tomcat/src/native/mod_jk/netscape/nsapi.dsw
Index: nsapi.dsw
===================================================================
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "nsapi"=".\nsapi.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
1.1 jakarta-tomcat/src/native/mod_jk/nt_service/jk_nt_service.c
Index: jk_nt_service.c
===================================================================
/*
* Copyright (c) 1997-1999 The Java Apache Project. 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. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Java Apache
* Project for use in the Apache JServ servlet engine project
* <http://java.apache.org/>."
*
* 4. The names "Apache JServ", "Apache JServ Servlet Engine" and
* "Java Apache Project" must not be used to endorse or promote products
* derived from this software without prior written permission.
*
* 5. Products derived from this software may not be called "Apache JServ"
* nor may "Apache" nor "Apache JServ" appear in their names without
* prior written permission of the Java Apache Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Java Apache
* Project for use in the Apache JServ servlet engine project
* <http://java.apache.org/>."
*
* THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "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 JAVA APACHE PROJECT 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 Java Apache Group. For more information
* on the Java Apache Project and the Apache JServ Servlet Engine project,
* please see <http://java.apache.org/>.
*
*/
/***************************************************************************
* Description: NT System service for Jakarta/Tomcat *
* Author: Gal Shachor <sh...@il.ibm.com> *
* Version: $Revision: 1.1 $ *
***************************************************************************/
#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;
struct jk_tomcat_startup_data {
char *classpath;
char *tomcat_home;
char *stdout_file;
char *stderr_file;
char *java_bin;
char *tomcat_class;
char *server_file;
char *cmd_line;
int shutdown_port;
char *shutdown_protocol;
char *extra_path;
};
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 *prp_file);
static void remove_service(char *name);
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(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(short port,
const char *protocol,
HANDLE hTomcat);
static int read_startup_data(jk_map_t *init_map,
jk_tomcat_startup_data_t *data,
jk_pool_t *p);
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");
}
void main(int argc, char **argv)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1, 1);
err = WSAStartup(wVersionRequested, &wsaData);
if(0 != err) {
fprintf(stderr, "Error connecting to winosck");
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) && ((*argv[1] == '-') || (*argv[1] == '/'))) {
char *cmd = argv[1];
cmd++;
if(0 == stricmp("i", cmd) && (4 == argc)) {
install_service(argv[2], argv[3]);
return;
} else if(0 == stricmp("r", cmd) && (3 == argc)) {
remove_service(argv[2]);
return;
} else if(0 == stricmp("s", cmd) && (3 == argc)) {
HANDLE hTomcat;
start_tomcat(argv[2], &hTomcat);
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_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;
}
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;
}
void install_service(char *name,
char *rel_prp_file)
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
char szExecPath[2048];
char szPropPath[2048];
char *dummy;
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;
}
if(GetModuleFileName( NULL, szExecPath, sizeof(szExecPath) - 1) == 0) {
printf("Unable to install %s - %s\n",
name,
GetLastErrorText(szErr, sizeof(szErr)));
return;
}
schSCManager = OpenSCManager(NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS); // access required
if(schSCManager) {
schService = CreateService(schSCManager, // SCManager database
name, // name of service
name, // name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
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
if(schService) {
printf("The service named %s was created. Now adding registry entries\n", name);
if(set_registry_values(name, szPropPath)) {
CloseServiceHandle(schService);
} else {
printf("CreateService failed setting the private registry - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
DeleteService(schService);
CloseServiceHandle(schService);
}
} else {
printf("CreateService failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
}
CloseServiceHandle(schSCManager);
} else {
printf("OpenSCManager failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
}
}
void remove_service(char *name)
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
schSCManager = OpenSCManager(NULL, // 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);
}
}
// now remove the service
if(DeleteService(schService)) {
printf("%s removed.\n", name);
} else {
printf("DeleteService 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)
{
char tag[1024];
HKEY hk;
int rc;
strcpy(tag, BASE_REGISTRY_LOCATION);
strcat(tag, name);
strcat(tag, "\\");
strcat(tag, PARAMS_LOCATION);
rc = create_registry_key(tag, &hk);
if(rc) {
rc = set_registry_config_parameter(hk, PRP_LOCATION, prp_file);
if(!rc) {
printf("Error: Can not create value [%s] - %s\n",
PRP_LOCATION,
GetLastErrorText(szErr, sizeof(szErr)));
}
RegCloseKey(hk);
} else {
printf("Error: Can not create key [%s] - %s\n",
tag,
GetLastErrorText(szErr, sizeof(szErr)));
}
if(rc) {
char value[2024];
rc = JK_FALSE;
strcpy(tag, BASE_REGISTRY_LOCATION);
strcat(tag, name);
if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
tag,
(DWORD)0,
KEY_WRITE | KEY_READ,
&hk)) {
rc = get_registry_config_parameter(hk,
IMAGE_NAME,
value,
sizeof(value));
if(rc) {
strcat(value, " ");
strcat(value, name);
rc = set_registry_config_parameter(hk,
IMAGE_NAME,
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",
name,
name);
}
}
RegCloseKey(hk);
}
if(!rc) {
printf("Error: Failed to update the service command line - %s\n",
GetLastErrorText(szErr, sizeof(szErr)));
}
}
return rc;
}
static void start_jk_service(char *name)
{
/*
* report the status to the service control manager.
*/
if(ReportStatusToSCMgr(SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000)) { // wait hint
/*
* create the event object. The control handler function signals
* this event when it receives the "stop" control code.
*/
hServerStopEvent = CreateEvent(NULL, // no security attributes
TRUE, // manual reset event
FALSE, // not-signalled
NULL); // no name
if(hServerStopEvent) {
if(ReportStatusToSCMgr(SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
20000)) { // wait hint
HANDLE hTomcat = NULL;
int rc = start_tomcat(name, &hTomcat);
if(rc && ReportStatusToSCMgr(SERVICE_RUNNING, // service state
NO_ERROR, // exit code
0)) { // wait hint
HANDLE waitfor[] = { hServerStopEvent, hTomcat};
DWORD dwIndex = WaitForMultipleObjects(2, waitfor, FALSE, INFINITE);
switch(dwIndex) {
case WAIT_OBJECT_0:
/*
* Stop order arrived
*/
ResetEvent(hServerStopEvent);
stop_tomcat((short)shutdown_port, shutdown_protocol, hTomcat);
break;
case (WAIT_OBJECT_0 + 1):
/*
* Tomcat died !!!
*/
break;
default:
/*
* some error...
* close the servlet container and exit
*/
stop_tomcat((short)shutdown_port, shutdown_protocol, hTomcat);
}
CloseHandle(hServerStopEvent);
CloseHandle(hTomcat);
}
}
}
}
if(hServerStopEvent) {
CloseHandle(hServerStopEvent);
}
}
static void stop_jk_service(void)
{
if(hServerStopEvent) {
SetEvent(hServerStopEvent);
}
}
static void AddToMessageLog(char *lpszMsg)
{
char szMsg[2048];
HANDLE hEventSource;
char * lpszStrings[2];
printf("Error: %s\n", lpszMsg);
dwErr = GetLastError();
hEventSource = RegisterEventSource(NULL, "Jakrta - Tomcat");
sprintf(szMsg, "%s error: %d", "Jakrta - Tomcat", dwErr);
lpszStrings[0] = szMsg;
lpszStrings[1] = lpszMsg;
if(hEventSource != NULL) {
ReportEvent(hEventSource, // handle of event source
EVENTLOG_ERROR_TYPE, // event type
0, // event category
0, // event ID
NULL, // current user's SID
2, // strings in lpszStrings
0, // no bytes of raw data
lpszStrings, // array of error strings
NULL); // no raw data
DeregisterEventSource(hEventSource);
}
}
//
// FUNCTION: GetLastErrorText
//
// PURPOSE: copies error message text to string
//
// PARAMETERS:
// lpszBuf - destination buffer
// dwSize - size of buffer
//
// RETURN VALUE:
// destination buffer
//
// COMMENTS:
//
char *GetLastErrorText( char *lpszBuf, DWORD dwSize )
{
DWORD dwRet;
char *lpszTemp = NULL;
dwRet = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
GetLastError(),
LANG_NEUTRAL,
(char *)&lpszTemp,
0,
NULL);
// supplied buffer is not long enough
if(!dwRet || ((long)dwSize < (long)dwRet+14)) {
lpszBuf[0] = '\0';
} else {
lpszTemp[lstrlen(lpszTemp)-2] = '\0'; //remove cr and newline character
sprintf(lpszBuf, "%s (0x%x)", lpszTemp, GetLastError());
}
if(lpszTemp) {
LocalFree((HLOCAL) lpszTemp );
}
return lpszBuf;
}
static void stop_tomcat(short port,
const char *protocol,
HANDLE hTomcat)
{
struct sockaddr_in in;
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, "ajp13")) {
jk_pool_t pool;
jk_msg_buf_t *msg = NULL;
jk_pool_atom_t buf[TINY_POOL_SIZE];
jk_open_pool(&pool, buf, sizeof(buf));
msg = jk_b_new(&pool);
jk_b_set_buffer_size(msg, 512);
rc = ajp13_marshal_shutdown_into_msgb(msg,
&pool,
NULL);
if(rc) {
jk_b_end(msg);
if(0 > jk_tcp_socket_sendfull(sd,
jk_b_get_buff(msg),
jk_b_get_len(msg))) {
rc = JK_FALSE;
}
}
} else {
char b[] = {(char)254, (char)15};
int rc = send(sd, b, 2, 0);
if(2 == rc) {
rc = JK_TRUE;
}
}
jk_close_socket(sd);
if(2 == rc) {
if(WAIT_OBJECT_0 == WaitForSingleObject(hTomcat, 30*1000)) {
return;
}
}
}
}
TerminateProcess(hTomcat, 0);
}
static int start_tomcat(const char *name, HANDLE *hTomcat)
{
char tag[1024];
HKEY hk;
strcpy(tag, BASE_REGISTRY_LOCATION);
strcat(tag, name);
strcat(tag, "\\");
strcat(tag, PARAMS_LOCATION);
if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
tag,
(DWORD)0,
KEY_READ,
&hk)) {
char prp_file[2048];
if(get_registry_config_parameter(hk,
PRP_LOCATION,
prp_file,
sizeof(prp_file))) {
jk_map_t *init_map;
if(map_alloc(&init_map)) {
if(map_read_properties(init_map, prp_file)) {
jk_tomcat_startup_data_t data;
jk_pool_t p;
jk_pool_atom_t buf[HUGE_POOL_SIZE];
jk_open_pool(&p, buf, sizeof(buf));
if(read_startup_data(init_map, &data, &p)) {
STARTUPINFO startupInfo;
PROCESS_INFORMATION processInformation;
SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
if(data.extra_path) {
jk_append_libpath(&p, data.extra_path);
}
memset(&startupInfo, 0, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);
startupInfo.lpTitle = "Jakarta Tomcat";
startupInfo.dwFlags = STARTF_USESTDHANDLES;
startupInfo.hStdInput = NULL;
startupInfo.hStdOutput = CreateFile(data.stdout_file,
GENERIC_WRITE,
FILE_SHARE_READ,
&sa,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
startupInfo.hStdError = CreateFile(data.stderr_file,
GENERIC_WRITE,
FILE_SHARE_READ,
&sa,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
memset(&processInformation, 0, sizeof(processInformation));
printf(data.cmd_line);
if(CreateProcess(data.java_bin,
data.cmd_line,
NULL,
NULL,
TRUE,
CREATE_NEW_CONSOLE,
NULL,
data.tomcat_home,
&startupInfo,
&processInformation)){
*hTomcat = processInformation.hProcess;
CloseHandle(processInformation.hThread);
CloseHandle(startupInfo.hStdOutput);
CloseHandle(startupInfo.hStdError);
shutdown_port = data.shutdown_port;
shutdown_protocol = strdup(data.shutdown_protocol);
return JK_TRUE;
} else {
printf("Error: Can not create new process - %s\n",
GetLastErrorText(szErr, sizeof(szErr)));
}
}
}
}
map_free(&init_map);
}
RegCloseKey(hk);
}
return JK_FALSE;
}
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);
if(ERROR_SUCCESS != lrc) {
return JK_FALSE;
}
return JK_TRUE;
}
static int set_registry_config_parameter(HKEY hkey,
const char *tag,
char *value)
{
LONG lrc;
lrc = RegSetValueEx(hkey,
tag,
0,
REG_SZ,
value,
strlen(value));
if(ERROR_SUCCESS != lrc) {
return JK_FALSE;
}
return JK_TRUE;
}
static int get_registry_config_parameter(HKEY hkey,
const char *tag,
char *b,
DWORD sz)
{
DWORD type = 0;
LONG lrc;
lrc = RegQueryValueEx(hkey,
tag,
(LPDWORD)0,
&type,
(LPBYTE)b,
&sz);
if(ERROR_SUCCESS != lrc) {
return JK_FALSE;
}
b[sz] = '\0';
return JK_TRUE;
}
static int read_startup_data(jk_map_t *init_map,
jk_tomcat_startup_data_t *data,
jk_pool_t *p)
{
data->classpath = NULL;
data->tomcat_home = NULL;
data->stdout_file = NULL;
data->stderr_file = NULL;
data->java_bin = NULL;
data->extra_path = NULL;
data->tomcat_class = NULL;
data->server_file = NULL;
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);
if(NULL == data->cmd_line) {
data->cmd_line = (char *)jk_pool_alloc(p, (20 +
strlen(data->java_bin) +
strlen(" -classpath ") +
strlen(data->classpath) +
strlen(data->tomcat_class) +
strlen(" -home ") +
strlen(data->tomcat_home) +
strlen(" -config ") +
strlen(data->server_file)
) * sizeof(char));
if(NULL == data->cmd_line) {
return JK_FALSE;
}
strcpy(data->cmd_line, data->java_bin);
strcat(data->cmd_line, " -classpath ");
strcat(data->cmd_line, data->classpath);
strcat(data->cmd_line, " ");
strcat(data->cmd_line, data->tomcat_class);
strcat(data->cmd_line, " -home ");
strcat(data->cmd_line, data->tomcat_home);
strcat(data->cmd_line, " -config ");
strcat(data->cmd_line, data->server_file);
}
data->shutdown_port = map_get_int(init_map,
"wrapper.shutdown_port",
8007);
data->shutdown_protocol = map_get_string(init_map,
"wrapper.shutdown_protocol",
AJP12_TAG);
data->extra_path = map_get_string(init_map,
"wrapper.ld_path",
NULL);
data->stdout_file = map_get_string(init_map,
"wrapper.stdout",
NULL);
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);
strcat(data->stdout_file, "\\stdout.log");
}
data->stderr_file = map_get_string(init_map,
"wrapper.stderr",
NULL);
if(NULL == data->stderr_file) {
data->stderr_file = jk_pool_alloc(p, strlen(data->tomcat_home) + 2 + strlen("\\stderr.log"));
strcpy(data->stderr_file, data->tomcat_home);
strcat(data->stderr_file, "\\stderr.log");
}
return JK_TRUE;
}
1.1 jakarta-tomcat/src/native/mod_jk/nt_service/nt_service.dsp
Index: nt_service.dsp
===================================================================
# Microsoft Developer Studio Project File - Name="nt_service" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=nt_service - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "nt_service.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "nt_service.mak" CFG="nt_service - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "nt_service - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "nt_service - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "nt_service - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "../jk" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/jk_nt_service.exe"
!ELSEIF "$(CFG)" == "nt_service - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../jk" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/jk_nt_service.exe" /pdbtype:sept
!ENDIF
# Begin Target
# Name "nt_service - Win32 Release"
# Name "nt_service - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\common\jk_ajp13.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_connect.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_map.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_msg_buff.c
# End Source File
# Begin Source File
SOURCE=.\jk_nt_service.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_pool.c
# End Source File
# Begin Source File
SOURCE=..\common\jk_util.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\common\jk_ajp12_worker.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_connect.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_global.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_logger.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_map.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_pool.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_service.h
# End Source File
# Begin Source File
SOURCE=..\common\jk_util.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project