hgomez 01/06/01 01:49:27
Added: jk/src/native/domino config.h dsapi.dsp dsapi.dsw
dsapifilter.h jk_dsapi_plugin.c
tomcat_redirector.reg
Log:
Initial domino support in JTC
Contributed by Andy Armstrong <[EMAIL PROTECTED]>
Revision Changes Path
1.1 jakarta-tomcat-connectors/jk/src/native/domino/config.h
Index: config.h
===================================================================
/*
* 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: DSAPI plugin for Lotus Domino *
* Author: Andy Armstrong <[EMAIL PROTECTED]> *
* Version: $Revision: 1.1 $ *
***************************************************************************/
#ifndef __config_h
#define __config_h
/* the _memicmp() function is available */
#define HAVE_MEMICMP
/* define if you don't have the Notes C API which is available from
*
* http://www.lotus.com/rw/dlcapi.nsf
*/
/* #undef NO_CAPI */
#endif /* __config_h */
1.1 jakarta-tomcat-connectors/jk/src/native/domino/dsapi.dsp
Index: dsapi.dsp
===================================================================
# Microsoft Developer Studio Project File - Name="dsapi" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=dsapi - 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 "dsapi.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 "dsapi.mak" CFG="dsapi - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "dsapi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "dsapi - 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)" == "dsapi - 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 "DSAPI_EXPORTS" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "C:\notesapi\include" /I
"C:\JBuilder4\jdk1.3\include" /I "C:\JBuilder4\jdk1.3\include\win32" /I "..\jk" /D
"NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DSAPI_EXPORTS" /D "NT"
/FR /FD /c
# SUBTRACT CPP /YX /Yc /Yu
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /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
wsock32.lib notes.lib /nologo /dll /machine:I386 /out:"Release/tomcat_redirector.dll"
/libpath:"C:\notesapi\lib\mswin32"
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Cmds=copy Release\tomcat_redirector.dll \\london\c$\lotus\domino
# End Special Build Tool
!ELSEIF "$(CFG)" == "dsapi - 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 "DSAPI_EXPORTS" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "C:\JBuilder4\jdk1.3\include" /I
"C:\JBuilder4\jdk1.3\include\win32" /I "..\jk" /I "C:\notesapi\include" /D "_DEBUG" /D
"WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DSAPI_EXPORTS" /D "NT" /FR /FD /GZ
/c
# SUBTRACT CPP /YX /Yc /Yu
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /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
wsock32.lib notes.lib /nologo /dll /debug /machine:I386
/out:"Debug/tomcat_redirector.dll" /pdbtype:sept /libpath:"C:\notesapi\lib\mswin32"
!ENDIF
# Begin Target
# Name "dsapi - Win32 Release"
# Name "dsapi - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\jk\jk_ajp12_worker.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_ajp13.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_ajp13_worker.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_connect.c
# End Source File
# Begin Source File
SOURCE=.\jk_dsapi_plugin.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_jni_worker.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_lb_worker.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_map.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_msg_buff.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_nwmain.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_pool.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_sockbuf.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_uri_worker_map.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_util.c
# End Source File
# Begin Source File
SOURCE=..\jk\jk_worker.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\config.h
# End Source File
# Begin Source File
SOURCE=.\dsapifilter.h
# End Source File
# Begin Source File
SOURCE=..\jk\jk_ajp12_worker.h
# End Source File
# Begin Source File
SOURCE=..\jk\jk_ajp13.h
# End Source File
# Begin Source File
SOURCE=..\jk\jk_ajp13_worker.h
# End Source File
# Begin Source File
SOURCE=..\jk\jk_connect.h
# End Source File
# Begin Source File
SOURCE=..\jk\jk_global.h
# End Source File
# Begin Source File
SOURCE=..\jk\jk_jni_worker.h
# End Source File
# Begin Source File
SOURCE=..\jk\jk_lb_worker.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_msg_buff.h
# End Source File
# Begin Source File
SOURCE=..\jk\jk_mt.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_sockbuf.h
# End Source File
# Begin Source File
SOURCE=..\jk\jk_uri_worker_map.h
# End Source File
# Begin Source File
SOURCE=..\jk\jk_util.h
# End Source File
# Begin Source File
SOURCE=..\jk\jk_worker.h
# End Source File
# Begin Source File
SOURCE=..\jk\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
# Begin Source File
SOURCE=.\ReadMe.txt
# End Source File
# End Target
# End Project
1.1 jakarta-tomcat-connectors/jk/src/native/domino/dsapi.dsw
Index: dsapi.dsw
===================================================================
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "dsapi"=".\dsapi.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
1.1 jakarta-tomcat-connectors/jk/src/native/domino/dsapifilter.h
Index: dsapifilter.h
===================================================================
/*--------------------------------------------------------------------
*
* File: dsapifilter.h
*
* Copyright (c)1999 Iris Associates
*
*-------------------------------------------------------------------*/
#if !defined(DSAPIFILTER_H)
#define DSAPIFILTER_H
#ifdef __cplusplus
extern "C"
{
#endif
/*---
* Types and Defines
*/
#define kInterfaceVersion 2
#define kMaxFilterDesc 255
typedef unsigned char LMBCS;
typedef enum
{
kFilterNotHandled = 0,
kFilterHandledRequest = 1,
kFilterHandledEvent = 2,
kFilterError = 3
}
FilterReturnCode;
/*--
* Filter interface
*/
/*---
* events to register for
*/
typedef enum
{
kFilterRawRequest = 0x01,
kFilterParsedRequest = 0x02,
kFilterAuthUser = 0x04,
kFilterUserNameList = 0x08,
kFilterMapURL = 0x10,
kFilterResponse = 0x20,
kFilterRawWrite = 0x40,
kFilterEndRequest = 0x80,
kFilterAny = 0xFF
}
EventFlags;
/*---
* filter initialization data
*/
typedef struct
{
unsigned int serverFilterVersion;
unsigned int appFilterVersion;
unsigned int eventFlags;
unsigned int initFlags;
char filterDesc[kMaxFilterDesc + 1];
}
FilterInitData;
/*---
* request line structure
*/
typedef struct
{
unsigned int method;
char *URL;
char *version;
char *userName;
char *password;
unsigned char *clientCert;
unsigned int clientCertLen;
char *contentRead;
unsigned int contentReadLen;
}
FilterRequest;
/*---
* filter context data included in every call to filter
*/
typedef struct _FilterContext
{
unsigned int contextSize;
unsigned int revision;
void *serverContext;
unsigned int serverReserved;
unsigned int securePort;
void *privateContext;
int (*GetRequest) (struct _FilterContext * context, FilterRequest *
request,
unsigned int *errID);
int (*GetRequestContents) (struct _FilterContext * context, char
**contents,
unsigned int
*errID);
int (*GetServerVariable) (struct _FilterContext * context, char *name,
void *buffer,
unsigned int
bufferSize, unsigned int *errID);
int (*WriteClient) (struct _FilterContext * context, char *buffer,
unsigned int bufferLen,
unsigned int reserved,
unsigned int *errID);
void *(*AllocMem) (struct _FilterContext * context, unsigned int size,
unsigned int reserved, unsigned int
*errID);
int (*ServerSupport) (struct _FilterContext * context, unsigned int
funcType, void *data1,
void *data2, unsigned int
other, unsigned int *errID);
}
FilterContext;
typedef unsigned int (*FilterInitFuncType) (FilterInitData * initData);
typedef unsigned int (*FilterEventFuncType) (FilterContext * context, unsigned
int eventType,
void *eventData, unsigned int *errID);
typedef unsigned int (*FilterTermFuncType) (unsigned int);
/*---
* request methods
*/
typedef enum
{
kRequestNone = 0,
kRequestHEAD = 1,
kRequestGET = 2,
kRequestPOST = 3,
kRequestPUT = 4,
kRequestDELETE = 5
}
RequestMethod;
/*---
* server support function types
*/
typedef enum
{
kWriteResponseHeaders = 1
}
ServerSupportTypes;
/*---
* 'data1' for server support function 'kWriteResponseHeaders'
*/
typedef struct
{
unsigned int responseCode;
char *reasonText;
char *headerText;
}
FilterResponseHeaders;
/*---
* raw request (headers not processed yet)
*/
typedef struct
{
unsigned int requestMethod;
int (*GetAllHeaders) (FilterContext * context, char **headers,
unsigned int *errID);
int (*GetHeader) (FilterContext * context, char *name, char *buffer,
unsigned int bufferSize, unsigned
int *errID);
int (*SetHeader) (FilterContext * context, char *name, char *value,
unsigned int *errID);
int (*AddHeader) (FilterContext * context, char *header, unsigned int
*errID);
unsigned int reserved;
}
FilterRawRequest;
/*---
* parsed request
*/
typedef struct
{
unsigned int requestMethod;
int (*GetAllHeaders) (FilterContext * context, char **headers,
unsigned int *errID);
int (*GetHeader) (FilterContext * context, char *name, char *buffer,
unsigned int bufferSize, unsigned
int *errID);
unsigned int reserved;
}
FilterParsedRequest;
/*---
* URL map
*/
typedef struct
{
const char *url;
char *pathBuffer;
unsigned int bufferSize;
unsigned int mapType;
}
FilterMapURL;
/*---
* URL map types
*/
typedef enum
{
kURLMapUnknown = 0,
kURLMapPass = 1,
kURLMapExec = 2,
kURLMapRedirect = 3,
kURLMapService = 4,
kURLMapDomino = 5
}
FilterULMapTypes;
/*---
* user authentication
*/
typedef struct
{
LMBCS *userName;
LMBCS *password;
unsigned char *clientCert;
unsigned int clientCertLen;
unsigned int authFlags;
unsigned int preAuthenticated;
unsigned int foundInCache;
unsigned int authNameSize;
LMBCS *authName;
unsigned int authType;
int (*GetUserNameList) (FilterContext * context, LMBCS * buffer,
unsigned int bufferSize,
unsigned int
*numNames, unsigned int reserved, unsigned int *errID);
int (*GetHeader) (FilterContext * context, char *name, char *buffer,
unsigned int bufferSize, unsigned
int *errID);
}
FilterAuthenticate;
/*---
* user authentication types
*/
typedef enum
{
kNotAuthentic = 0,
kAuthenticBasic = 1,
kAuthenticClientCert = 2
}
FilterAuthenticationTypes;
/*---
* authentication configuration flags
*/
typedef enum
{
kAuthAllowBasic = 1,
kAuthAllowAnonymous = 2,
kAuthAllowSSLCert = 4,
kAuthAllowSSLBasic = 8,
kAuthAllowSSLAnonymous = 16,
kAuthRedirectToSSL = 32
}
FilterAuthConfigFlags;
/*---
* user name list
*/
typedef struct
{
const LMBCS *userName;
int (*GetUserNameList) (FilterContext * context, LMBCS * buffer,
unsigned int bufferSize,
unsigned int
*numNames, unsigned int reserved, unsigned int *errID);
int (*PopulateUserNameList) (FilterContext * context, LMBCS * buffer,
unsigned int
bufferSize, unsigned int *numNames,
unsigned int
reserved, unsigned int *errID);
int (*AddGroupsToList) (FilterContext * context, LMBCS * groupNames,
unsigned int
numGroupNames, unsigned int reserved,
unsigned int *errID);
int (*RemoveGroupsFromList) (FilterContext * context, unsigned int
reserved,
unsigned int
*errID);
unsigned int reserved;
}
FilterUserNameList;
/*---
* request response
*/
typedef struct
{
unsigned int responseCode;
char *reasonText;
int (*GetAllHeaders) (FilterContext * context, char **headers,
unsigned int *errID);
int (*GetHeader) (FilterContext * context, char *name, char *buffer,
unsigned int bufferSize, unsigned
int *errID);
int (*SetHeader) (FilterContext * context, char *name, char *value,
unsigned int *errID);
int (*AddHeader) (FilterContext * context, char *header, unsigned int
*errID);
unsigned int reserved;
}
FilterResponse;
/*---
* write content
*/
typedef struct
{
char *content;
unsigned int contentLen;
unsigned int reserved;
}
FilterRawWrite;
#ifdef __cplusplus
}
#endif
#endif /* DSAPIFILTER_H */
1.1 jakarta-tomcat-connectors/jk/src/native/domino/jk_dsapi_plugin.c
Index: jk_dsapi_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: DSAPI plugin for Lotus Domino *
* Author: Andy Armstrong <[EMAIL PROTECTED]> *
* Version: $Revision: 1.1 $ *
***************************************************************************/
/* Based on the IIS redirector by Gal Shachor <[EMAIL PROTECTED]> */
#include "config.h"
/* JK stuff */
#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"
#ifndef NO_CAPI
/* Domino stuff */
#include <global.h>
#include <addin.h>
#else
#include <stdarg.h>
#define NOERROR 0
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "dsapifilter.h"
#if !defined(DLLEXPORT)
#ifdef WIN32
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT
#endif
#endif
#define VERSION "1.0"
#define VERSION_STRING "Jakarta/DSAPI/" VERSION
/* What we call ourselves */
#define FILTERDESC "Apache Tomcat Interceptor (" VERSION_STRING
")"
/* Registry location of configuration data */
#define REGISTRY_LOCATION "Software\\Apache Software Foundation\\Jakarta Dsapi
Redirector\\1.0"
/* Names of registry keys that contain commands to start, stop Tomcat */
#define TOMCAT_START "tomcat_start"
#define TOMCAT_STOP "tomcat_stop"
#define TOMCAT_STARTSTOP_TO 30000 /* 30 seconds */
static int initDone = JK_FALSE;
static jk_uri_worker_map_t *uw_map = NULL;
static jk_logger_t *logger = NULL;
static int logLevel = JK_LOG_EMERG_LEVEL;
static char logFile[MAX_PATH];
static char workerFile[MAX_PATH];
static char workerMountFile[MAX_PATH];
static char tomcatStart[MAX_PATH];
static char tomcatStop[MAX_PATH];
static char *crlf = "\r\n";
typedef struct private_ws
{
jk_pool_t p;
/* These get passed in by Domino and are used to access various
* Domino methods and data.
*/
FilterContext *context;
FilterParsedRequest *reqData;
/* True iff the response headers have been sent
*/
int responseStarted;
/* Current pointer into and remaining size
* of request body data
*/
char *reqBuffer;
unsigned int reqSize;
} private_ws_t;
/* These three functions are called back (indirectly) by
* Tomcat during request processing. StartResponse() sends
* the headers associated with the response.
*/
static int JK_METHOD StartResponse(jk_ws_service_t * s, int status, const char
*reason,
const char
*const *hdrNames,
const char
*const *hdrValues, unsigned hdrCount);
/* Read() is called by Tomcat to read from the request body (if any).
*/
static int JK_METHOD Read(jk_ws_service_t * s, void *b, unsigned l, unsigned *a);
/* Write() is called by Tomcat to send data back to the client.
*/
static int JK_METHOD Write(jk_ws_service_t * s, const void *b, unsigned l);
static int ReadInitData(void);
static int GetRegParam(HKEY hkey, const char *tag, char *b, DWORD sz);
static unsigned int ParsedRequest(FilterContext *context, FilterParsedRequest
*reqData);
/* Case insentive memcmp() clone
*/
#ifdef HAVE_MEMICMP
#define NoCaseCmp(ci, cj, l) _memicmp((void *) (ci), (void *) (cj), (l))
#else
static int NoCaseCmp(const char *ci, const char *cj, int len)
{
if (0 == memcmp(ci, cj, len))
return 0;
while (len > 0)
{
int cmp = tolower(*ci) - tolower(*cj);
if (cmp != 0) return cmp;
ci++;
cj++;
len--;
}
return 0;
}
#endif
/* Case insensitive substring search.
* str string to search
* slen length of string to search
* ptn pattern to search for
* plen length of pattern
* returns 1 if there's a match otherwise 0
*/
static int NoCaseFind(const char *str, int slen, const char *ptn, int plen)
{
while (slen >= plen)
{
if (NoCaseCmp(str, ptn, plen) == 0)
return 1;
slen--;
str++;
}
return 0;
}
#ifdef NO_CAPI
/* Alternative to the Domino function */
static void AddInLogMessageText(char *msg, unsigned short code, ...)
{
va_list ap;
if (code != NOERROR)
printf("Error %d: ", code);
va_start(ap, code);
vprintf(msg, ap);
va_end(ap);
printf("\n");
}
#endif
/* Return 1 iff the supplied string contains "web-inf" (in any case
* variation. We don't allow URIs containing web-inf.
*/
static int BadURI(const char *uri)
{
static char *wi = "web-inf";
return NoCaseFind(uri, strlen(uri), wi, strlen(wi));
}
/* Replacement for strcat() that updates a buffer pointer. It's
* probably marginal, but this should be more efficient that strcat()
* in cases where the string being concatenated to gets long because
* strcat() has to count from start of the string each time.
*/
static void Append(char **buf, const char *str)
{
int l = strlen(str);
memcpy(*buf, str, l);
(*buf)[l] = '\0';
*buf += l;
}
/* Start the response by sending any headers. Invoked by Tomcat. I don't
* particularly like the fact that this always allocates memory, but
* perhaps jk_pool_alloc() is efficient.
*/
static int JK_METHOD StartResponse(jk_ws_service_t *s, int status, const char
*reason,
const char
*const *hdrNames,
const char
*const *hdrValues, unsigned hdrCount)
{
jk_log(logger, JK_LOG_DEBUG, "Into jk_ws_service_t::StartResponse\n");
if (status < 100 || status > 1000)
{
jk_log(logger, JK_LOG_ERROR, "jk_ws_service_t::StartResponse, invalid
status %d\n", status);
return JK_FALSE;
}
if (s && s->ws_private)
{
private_ws_t *p = s->ws_private;
if (!p->responseStarted)
{
char *hdrBuf;
FilterResponseHeaders frh;
int rc, errID;
p->responseStarted = JK_TRUE;
if (NULL == reason)
reason = "";
/* Build a single string containing all the headers
* because that's what Domino needs.
*/
if (hdrCount > 0)
{
unsigned i;
unsigned hdrLen;
char *bufp;
for (i = 0, hdrLen = 3; i < hdrCount; i++)
hdrLen += strlen(hdrNames[i]) +
strlen(hdrValues[i]) + 4;
hdrBuf = jk_pool_alloc(&p->p, hdrLen);
bufp = hdrBuf;
for (i = 0; i < hdrCount; i++)
{
Append(&bufp, hdrNames[i]);
Append(&bufp, ": ");
Append(&bufp, hdrValues[i]);
Append(&bufp, crlf);
}
Append(&bufp, crlf);
}
else
{
hdrBuf = crlf;
}
frh.responseCode = status;
frh.reasonText = (char *) reason;
frh.headerText = hdrBuf;
//printf("%d %s\n%s", status, reason, hdrBuf);
/* Send the headers */
rc = p->context->ServerSupport(p->context,
kWriteResponseHeaders, &frh, NULL, 0, &errID);
/*
if (rc)
{
jk_log(logger, JK_LOG_ERROR,
"jk_ws_service_t::StartResponse,
ServerSupportFunction failed\n");
return JK_FALSE;
}
*/
}
return JK_TRUE;
}
jk_log(logger, JK_LOG_ERROR, "jk_ws_service_t::StartResponse, NULL
parameters\n");
return JK_FALSE;
}
static int JK_METHOD Read(jk_ws_service_t * s, void *bytes, unsigned len, unsigned
*countp)
{
jk_log(logger, JK_LOG_DEBUG, "Into jk_ws_service_t::Read\n");
if (s && s->ws_private && bytes && countp)
{
private_ws_t *p = s->ws_private;
/* Copy data from Domino's buffer. Although it seems slightly
* improbably we're believing that Domino always buffers the
* entire request in memory. Not properly tested yet.
*/
if (len > p->reqSize) len = p->reqSize;
memcpy(bytes, p->reqBuffer, len);
p->reqBuffer += len;
p->reqSize -= len;
*countp = len;
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 *bytes, unsigned len)
{
jk_log(logger, JK_LOG_DEBUG, "Into jk_ws_service_t::Write\n");
if (s && s->ws_private && bytes)
{
private_ws_t *p = s->ws_private;
int errID, rc;
/* Make sure the response has really started. I'm almost certain
* this isn't necessary, but it was in the ISAPI code, so it's in
* here too.
*/
if (!p->responseStarted)
StartResponse(s, 200, NULL, NULL, NULL, 0);
//printf("Writing %d bytes of content\n", len);
/* Send the data */
if (len > 0)
rc = p->context->WriteClient(p->context, (char *) bytes, len,
0, &errID);
return JK_TRUE;
}
jk_log(logger, JK_LOG_ERROR, "jk_ws_service_t::Write, NULL parameters\n");
return JK_FALSE;
}
static int RunProg(char *cmd)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si); // Start the child process.
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWMAXIMIZED;
if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
DWORD err = GetLastError();
AddInLogMessageText("Command \"%s\" (error %u)", NOERROR, cmd, err);
return FALSE;
}
if (WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, TOMCAT_STARTSTOP_TO))
return TRUE;
AddInLogMessageText("Command \"%s\" didn't complete in time", NOERROR, cmd);
return FALSE;
}
/* Called when the filter is unloaded. Free various resources and
* display a banner.
*/
DLLEXPORT unsigned int TerminateFilter(unsigned int reserved)
{
if (initDone)
{
initDone = JK_FALSE;
uri_worker_map_free(&uw_map, logger);
wc_close(logger);
if (logger)
jk_close_file_logger(&logger);
}
if (tomcatStop[0])
{
AddInLogMessageText("Attempting to stop Tomcat: %s", NOERROR,
tomcatStop);
RunProg(tomcatStop);
}
AddInLogMessageText(FILTERDESC " unloaded", NOERROR);
return kFilterHandledEvent;
}
/* Called when Domino loads the filter. Reads a load of config data from
* the registry and elsewhere and displays a banner.
*/
DLLEXPORT unsigned int FilterInit(FilterInitData * filterInitData)
{
int rc = JK_FALSE;
jk_map_t *map = NULL;
if (!ReadInitData())
goto initFailed;
if (!jk_open_file_logger(&logger, logFile, logLevel))
logger = NULL;
if (tomcatStart[0])
{
AddInLogMessageText("Attempting to start Tomcat: %s", NOERROR,
tomcatStart);
RunProg(tomcatStart);
}
if (map_alloc(&map))
{
if (map_read_properties(map, workerMountFile))
if (uri_worker_map_alloc(&uw_map, map, logger))
rc = JK_TRUE;
map_free(&map);
}
if (!rc) goto initFailed;
rc = JK_FALSE;
if (map_alloc(&map))
{
if (map_read_properties(map, workerFile))
if (wc_open(map, logger))
rc = JK_TRUE;
map_free(&map);
}
if (!rc) goto initFailed;
initDone = JK_TRUE;
filterInitData->appFilterVersion = kInterfaceVersion;
filterInitData->eventFlags = kFilterParsedRequest;
strcpy(filterInitData->filterDesc, FILTERDESC);
// Banner
AddInLogMessageText("%s loaded", NOERROR, filterInitData->filterDesc);
return kFilterHandledEvent;
initFailed:
AddInLogMessageText("Error loading %s", NOERROR, FILTERDESC);
return kFilterError;
}
/* Read parameters from the registry
*/
static int ReadInitData(void)
{
char tmpbuf[1024];
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 (GetRegParam(hkey, JK_LOG_FILE_TAG, tmpbuf, sizeof (logFile)))
strcpy(logFile, tmpbuf);
else
ok = JK_FALSE;
if (GetRegParam(hkey, JK_LOG_LEVEL_TAG, tmpbuf, sizeof (tmpbuf)))
logLevel = jk_parse_log_level(tmpbuf);
else
ok = JK_FALSE;
if (GetRegParam(hkey, JK_WORKER_FILE_TAG, tmpbuf, sizeof (workerFile)))
strcpy(workerFile, tmpbuf);
else
ok = JK_FALSE;
if (GetRegParam(hkey, JK_MOUNT_FILE_TAG, tmpbuf, sizeof (workerMountFile)))
strcpy(workerMountFile, tmpbuf);
else
ok = JK_FALSE;
/* Get the commands that will start and stop Tomcat. We're not too bothered
* if they don't exist.
*/
tomcatStart[0] = '\0';
if (GetRegParam(hkey, TOMCAT_START, tmpbuf, sizeof (tomcatStart)))
strcpy(tomcatStart, tmpbuf);
tomcatStop[0] = '\0';
if (GetRegParam(hkey, TOMCAT_STOP, tmpbuf, sizeof (tomcatStop)))
strcpy(tomcatStop, tmpbuf);
RegCloseKey(hkey);
return ok;
}
static int GetRegParam(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';
//printf("%s = %s\n", tag, b);
return JK_TRUE;
}
/* Main entry point for the filter. Called by Domino for every HTTP request.
*/
DLLEXPORT unsigned int HttpFilterProc(FilterContext *context, unsigned int
eventType, void *eventData)
{
if (initDone)
{
switch (eventType)
{
case kFilterParsedRequest:
return ParsedRequest(context, (FilterParsedRequest *)
eventData);
default:
break;
}
}
return kFilterNotHandled;
}
/* Send a simple response. Used when we don't want to bother Tomcat,
* which in practice means for various error conditions that we can
* detect internally.
*/
static void SimpleResponse(FilterContext *context, int status, char *reason, char
*body)
{
FilterResponseHeaders frh;
int rc, errID;
char hdrBuf[40];
sprintf(hdrBuf, "Content-type: text/html%s%s", crlf, crlf);
frh.responseCode = status;
frh.reasonText = reason;
frh.headerText = hdrBuf;
rc = context->ServerSupport(context, kWriteResponseHeaders, &frh, NULL, 0,
&errID);
rc = context->WriteClient(context, body, strlen(body), 0, &errID);
}
/* Called to reject a URI that contains the string "web-inf". We block
* these because they may indicate an attempt to invoke arbitrary code.
*/
static unsigned int RejectBadURI(FilterContext *context)
{
static char *msg = "<HTML><BODY><H1>Access is Forbidden</H1></BODY></HTML>";
SimpleResponse(context, 403, "Forbidden", msg);
return kFilterHandledRequest;
}
/* Get the value of a server (CGI) variable as a string
*/
static int GetVariable(private_ws_t *ws, char *hdrName,
char *buf, DWORD bufsz, char **dest, const
char *dflt)
{
int errID;
if (ws->context->GetServerVariable(ws->context, hdrName, buf, bufsz, &errID))
*dest = jk_pool_strdup(&ws->p, buf);
else
*dest = jk_pool_strdup(&ws->p, dflt);
//printf("%s = %s\n", hdrName, *dest);
return JK_TRUE;
}
/* Get the value of a server (CGI) variable as an integer
*/
static int GetVariableInt(private_ws_t *ws, char *hdrName,
char *buf, DWORD bufsz, int *dest, int
dflt)
{
int errID;
if (ws->context->GetServerVariable(ws->context, hdrName, buf, bufsz, &errID))
*dest = atoi(buf);
else
*dest = dflt;
//printf("%s = %d\n", hdrName, *dest);
return JK_TRUE;
}
/* A couple of utility macros to supply standard arguments to GetVariable() and
* GetVariableInt().
*/
#define GETVARIABLE(name, dest, dflt) GetVariable(ws, (name), workBuf,
sizeof(workBuf), (dest), (dflt))
#define GETVARIABLEINT(name, dest, dflt) GetVariableInt(ws, (name), workBuf,
sizeof(workBuf), (dest), (dflt))
/* Allocate space for a string given a start pointer and an end pointer
* and return a pointer to the allocated, copied string.
*/
static char *MemDup(private_ws_t *ws, const char *start, const char *end)
{
char *out = NULL;
if (start != NULL && end != NULL && end > start)
{
int len = end - start;
out = jk_pool_alloc(&ws->p, len + 1);
memcpy(out, start, len);
out[len] = '\0';
}
return out;
}
/* Given all the HTTP headers as a single string parse them into individual
* name, value pairs. Called twice: once to work out how many headers there
* are, then again to copy them.
*/
static int ParseHeaders(private_ws_t *ws, const char *hdrs, int hdrsz,
jk_ws_service_t *s)
{
int hdrCount = 0;
const char *limit = hdrs + hdrsz;
const char *name, *nameEnd;
const char *value, *valueEnd;
while (hdrs < limit)
{
/* Skip line *before* doing anything, cos we want to lose the first
line which
* contains the request.
*/
while (hdrs < limit && (*hdrs != '\n' && *hdrs != '\r'))
hdrs++;
while (hdrs < limit && (*hdrs == '\n' || *hdrs == '\r'))
hdrs++;
if (hdrs >= limit)
break;
name = nameEnd = value = valueEnd = NULL;
name = hdrs;
while (hdrs < limit && *hdrs >= ' ' && *hdrs != ':')
hdrs++;
nameEnd = hdrs;
if (hdrs < limit && *hdrs == ':')
{
hdrs++;
while (hdrs < limit && (*hdrs == ' ' || *hdrs == '\t'))
hdrs++;
value = hdrs;
while (hdrs < limit && *hdrs >= ' ')
hdrs++;
valueEnd = hdrs;
}
if (s->headers_names != NULL && s->headers_values != NULL)
{
s->headers_names[hdrCount] = MemDup(ws, name, nameEnd);
s->headers_values[hdrCount] = MemDup(ws, value, valueEnd);
//printf("%s = %s\n", s->headers_names[hdrCount],
s->headers_values[hdrCount]);
}
hdrCount++;
}
return hdrCount;
}
/* Set up all the necessary jk_* workspace based on the current HTTP request.
*/
static int InitService(private_ws_t *ws, jk_ws_service_t *s)
{
char workBuf[16 * 1024];
FilterRequest fr;
char *hdrs, *qp;
int hdrsz;
int errID;
int hdrCount;
int rc;
static char *methodName[] = { "", "HEAD", "GET", "POST", "PUT", "DELETE" };
rc = ws->context->GetRequest(ws->context, &fr, &errID);
s->jvm_route = NULL;
s->start_response = StartResponse;
s->read = Read;
s->write = Write;
s->req_uri = jk_pool_strdup(&ws->p, fr.URL);
s->query_string = NULL;
if (qp = strchr(s->req_uri, '?'), qp != NULL)
{
*qp++ = '\0';
if (strlen(qp))
s->query_string = qp;
}
GETVARIABLE("AUTH_TYPE", &s->auth_type, "");
GETVARIABLE("REMOTE_USER", &s->remote_user, "");
GETVARIABLE("SERVER_PROTOCOL", &s->protocol, "");
GETVARIABLE("REMOTE_HOST", &s->remote_host, "");
GETVARIABLE("REMOTE_ADDR", &s->remote_addr, "");
GETVARIABLE("SERVER_NAME", &s->server_name, "");
GETVARIABLEINT("SERVER_PORT", &s->server_port, 80);
GETVARIABLE("SERVER_SOFTWARE", &s->server_software, "Lotus Domino");
GETVARIABLEINT("SERVER_PORT_SECURE", &s->is_ssl, 0);
GETVARIABLEINT("CONTENT_LENGTH", &s->content_length, 0); // not tested
s->method = methodName[ws->reqData->requestMethod];
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;
if (s->is_ssl)
{
char *sslNames[] =
{
"CERT_ISSUER", "CERT_SUBJECT", "CERT_COOKIE", "CERT_FLAGS",
"CERT_SERIALNUMBER",
"HTTPS_SERVER_SUBJECT", "HTTPS_SECRETKEYSIZE",
"HTTPS_SERVER_ISSUER", "HTTPS_KEYSIZE"
};
char *sslValues[] =
{
NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL
};
unsigned i, varCount = 0;
for (i = 0; i < sizeof(sslNames)/sizeof(sslNames[0]); i++)
{
GETVARIABLE(sslNames[i], &sslValues[i], NULL);
if (sslValues[i]) varCount++;
}
if (varCount > 0)
{
unsigned j;
s->attributes_names = jk_pool_alloc(&ws->p, varCount * sizeof
(char *));
s->attributes_values = jk_pool_alloc(&ws->p, varCount * sizeof
(char *));
j = 0;
for (i = 0; i < sizeof(sslNames)/sizeof(sslNames[0]); i++)
{
if (sslValues[i])
{
s->attributes_names[j] = sslNames[i];
s->attributes_values[j] = sslValues[i];
j++;
}
}
s->num_attributes = varCount;
}
}
/* Duplicate all the headers now */
hdrsz = ws->reqData->GetAllHeaders(ws->context, &hdrs, &errID);
//printf("\nGot headers (length %d)\n--------\n%s\n--------\n\n", hdrsz,
hdrs);
s->headers_names =
s->headers_values = NULL;
hdrCount = ParseHeaders(ws, hdrs, hdrsz, s);
//printf("Found %d headers\n", hdrCount);
s->num_headers = hdrCount;
s->headers_names = jk_pool_alloc(&ws->p, hdrCount * sizeof(char *));
s->headers_values = jk_pool_alloc(&ws->p, hdrCount * sizeof(char *));
hdrCount = ParseHeaders(ws, hdrs, hdrsz, s);
return JK_TRUE;
}
/* Handle an HTTP request. Works out whether Tomcat will be interested then either
* despatches it to Tomcat or passes it back to Domino.
*/
static unsigned int ParsedRequest(FilterContext *context, FilterParsedRequest
*reqData)
{
unsigned int errID;
int rc;
FilterRequest fr;
int result = kFilterNotHandled;
//printf("\nParsedRequest starting\n");
rc = context->GetRequest(context, &fr, &errID);
if (fr.URL && strlen(fr.URL))
{
char *uri = fr.URL;
char *workerName, *qp;
if (qp = strchr(uri, '?'), qp != NULL) *qp = '\0';
workerName = map_uri_to_worker(uw_map, uri, logger);
if (qp) *qp = '?';
//printf("Worker for this URL is %s\n", workerName);
if (NULL != workerName)
{
private_ws_t ws;
jk_ws_service_t s;
jk_pool_atom_t buf[SMALL_POOL_SIZE];
if (BadURI(uri))
return RejectBadURI(context);
/* Go dispatch the call */
jk_init_ws_service(&s);
jk_open_pool(&ws.p, buf, sizeof (buf));
ws.responseStarted = JK_FALSE;
ws.context = context;
ws.reqData = reqData;
ws.reqSize = context->GetRequestContents(context,
&ws.reqBuffer, &errID);
s.ws_private = &ws;
s.pool = &ws.p;
if (InitService(&ws, &s))
{
jk_worker_t *worker =
wc_get_worker_for_name(workerName, logger);
jk_log(logger, JK_LOG_DEBUG, "HttpExtensionProc %s a
worker for name %s\n",
worker ? "got" : "could not get",
workerName);
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))
{
result =
kFilterHandledRequest;
jk_log(logger, JK_LOG_DEBUG,
"HttpExtensionProc service() returned OK\n");
}
else
{
result = kFilterError;
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",
workerName);
}
}
jk_close_pool(&ws.p);
}
}
return result;
}
1.1
jakarta-tomcat-connectors/jk/src/native/domino/tomcat_redirector.reg
Index: tomcat_redirector.reg
===================================================================
REGEDIT4
[HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Dsapi
Redirector\1.0]
"log_file"="D:\\tomcat\\logs\\domino.log"
"log_level"="debug"
"worker_file"="D:\\tomcat\\conf\\workers.properties"
"worker_mount_file"="D:\\tomcat\\conf\\uriworkermap.properties"
"tomcat_start"="D:\\tomcat\\bin\\tomcat.bat start"
"tomcat_stop"="D:\\tomcat\\bin\\tomcat.bat stop"