You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by an...@apache.org on 2003/11/13 18:10:56 UTC

cvs commit: jakarta-tomcat-connectors/jk/native2/server/dsapi todo.txt jk_dsapi_plugin.c dsapifilter.h dsapi_redirector2.reg dsapi.dsw dsapi.dsp config.h

andya       2003/11/13 09:10:56

  Added:       jk/native2/server/dsapi todo.txt jk_dsapi_plugin.c
                        dsapifilter.h dsapi_redirector2.reg dsapi.dsw
                        dsapi.dsp config.h
  Log:
  First release of JK2 Domino redirector. Barely tested.
  
  Revision  Changes    Path
  1.1                  jakarta-tomcat-connectors/jk/native2/server/dsapi/todo.txt
  
  Index: todo.txt
  ===================================================================
  $Id: todo.txt,v 1.1 2003/11/13 17:10:56 andya Exp $
  
  Test SSL
  Produce Linux version
  Resolve any licence issues with dsapifilter.h
  
  
  
  1.1                  jakarta-tomcat-connectors/jk/native2/server/dsapi/jk_dsapi_plugin.c
  
  Index: jk_dsapi_plugin.c
  ===================================================================
  /* ========================================================================= *
   *                                                                           *
   *                 The Apache Software License,  Version 1.1                 *
   *                                                                           *
   *          Copyright (c) 1999-2001 The Apache Software Foundation.          *
   *                           All rights reserved.                            *
   *                                                                           *
   * ========================================================================= *
   *                                                                           *
   * Redistribution and use in source and binary forms,  with or without modi- *
   * fication, are permitted provided that the following conditions are met:   *
   *                                                                           *
   * 1. Redistributions of source code  must retain the above copyright notice *
   *    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. The end-user documentation  included with the redistribution,  if any, *
   *    must include the following acknowlegement:                             *
   *                                                                           *
   *       "This product includes  software developed  by the Apache  Software *
   *        Foundation <http://www.apache.org/>."                              *
   *                                                                           *
   *    Alternately, this acknowlegement may appear in the software itself, if *
   *    and wherever such third-party acknowlegements normally appear.         *
   *                                                                           *
   * 4. The names  "The  Jakarta  Project",  "Jk",  and  "Apache  Software     *
   *    Foundation"  must not be used  to endorse or promote  products derived *
   *    from this  software without  prior  written  permission.  For  written *
   *    permission, please contact <ap...@apache.org>.                        *
   *                                                                           *
   * 5. Products derived from this software may not be called "Apache" nor may *
   *    "Apache" appear in their names without prior written permission of the *
   *    Apache Software Foundation.                                            *
   *                                                                           *
   * THIS SOFTWARE IS PROVIDED "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 APACHE  SOFTWARE  FOUNDATION 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 indivi- *
   * duals on behalf of the  Apache Software Foundation.  For more information *
   * on the Apache Software Foundation, please see <http://www.apache.org/>.   *
   *                                                                           *
   * ========================================================================= */
  
  /***************************************************************************
   * Description: DSAPI plugin for Lotus Domino                              *
   * Author:      Andy Armstrong <an...@tagish.com>                           *
   * Version:     $Revision: 1.1 $                                           *
   ***************************************************************************/
  
  /* Based on the IIS redirector by Gal Shachor <sh...@il.ibm.com> */
  
  /* Standard headers */
  #include <stdlib.h>
  #include <stdio.h>
  #include <string.h>
  #include <ctype.h>
  
  /* If we're building under Windows get windows.h. This must be included
   * before any APR includes because APR itself does a #include <windows.h>
   * after turning off some features that we need.
   */
  #ifdef WIN32
  #include <windows.h>
  #endif
  
  #include "config.h"
  
  /* JK stuff */
  #include "jk_global.h"
  #include "jk_requtil.h"
  #include "jk_map.h"
  #include "jk_pool.h"
  #include "jk_logger.h"
  #include "jk_env.h"
  #include "jk_service.h"
  #include "jk_worker.h"
  #include "apr_general.h"
  
  #ifndef NO_CAPI
  /* Domino stuff */
  #include <global.h>
  #include <addin.h>
  #else
  #include <stdarg.h>
  #define NOERROR 0
  #endif
  
  /* Domino DSAPI filter definitions */
  #include "dsapifilter.h"
  
  #if !defined(DLLEXPORT)
  #if defined(WIN32) && !defined(TESTING)
  #define DLLEXPORT __declspec(dllexport)
  #else
  #define DLLEXPORT
  #endif
  #endif
  
  /* Configuration tags */
  #define SERVER_ROOT_TAG		("serverRoot")
  #define WORKER_FILE_TAG		("workersFile")
  #define TOMCAT_START_TAG	("tomcatStart")
  #define TOMCAT_STOP_TAG		("tomcatStop")
  
  #define VERSION				"2.0.0"
  #define VERSION_STRING		"Jakarta/DSAPI/" VERSION
  
  #define FILTERDESC			"Apache Tomcat Interceptor (" VERSION_STRING ")"
  
  #define SERVERDFLT			"Lotus Domino"
  
  #ifdef TESTING
  #define LOGGER				"logger.printf"
  int JK_METHOD jk2_logger_printf_factory(jk_env_t *env, jk_pool_t *pool, jk_bean_t *result, const char *type, const char *name);
  #else
  #define LOGGER				"logger.win32"
  #endif
  
  #define REGISTRY_LOCATION	"Software\\Apache Software Foundation\\Jakarta Dsapi Redirector\\2.0"
  
  #define TOMCAT_STARTSTOP_TO	30000				/* 30 seconds */
  
  #define CONTENT_LENGTH		"Content-length"	/* Name of CL header */
  
  static char  libFileName[MAX_PATH];
  static char  iniFileName[MAX_PATH];
  static int   iniFileUsed = JK_FALSE;
  static int   isInited = JK_FALSE;
  
  static const char *tomcatStart	= NULL;
  static const char *tomcatStop	= NULL;
  static const char *workersFile	= NULL;
  static const char *serverRoot	= NULL;
  
  static jk_workerEnv_t *workerEnv;
  static apr_pool_t *jk_globalPool;
  
  static const char *crlf			= "\r\n";
  
  /* Per request private data */
  typedef struct private_ws {
  	/* 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;
  
  /* Case insentive memcmp() clone
   */
  #ifdef HAVE_MEMICMP
  #define NoCaseMemCmp(ci, cj, l) _memicmp((void *) (ci), (void *) (cj), (l))
  #else
  static int NoCaseMemCmp(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 insentive strcmp() clone
   */
  #ifdef HAVE_STRICMP
  #define NoCaseStrCmp(si, sj) _stricmp((void *) (si), (void *) (sj))
  #else
  static int NoCaseStrCmp(const char *si, const char *sj) {
  	if (0 == strcmp(si, sj)) {
  		return 0;
  	}
  
  	while (*si && tolower(*si) == tolower(*sj)) {
  		si++;
  		sj++;
  	}
  
  	return tolower(*si) - tolower(*sj);
  }
  #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 FindPathElem(const char *str, int slen, const char *ptn, int plen) {
  	const char *sp = str;
  
  	while (slen >= plen) {
  		/* We're looking for a match for the specified string bounded by
  		 * the start of the string, \ or / at the left and the end of the
  		 * string, \ or / at the right. We look for \ as well as / on the
  		 * suspicion that a Windows hosted server might accept URIs
  		 * containing \.
  		 */
  		if (NoCaseMemCmp(sp, ptn, plen) == 0 &&
  			(sp == str || sp[-1] == '\\' || sp[-1] == '/') &&
  			(slen == plen || sp[plen] == '\\' || sp[plen] == '/')) {
  			return 1;
  		}
  
  		slen--;
  		sp++;
  	}
  	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
  
  static void _printf(const char *msg, ...) {
  	char buf[512];		/* dangerous fixed size buffer */
  	va_list ap;
  	va_start(ap, msg);
  	vsprintf(buf, msg, ap);
  	va_end(ap);
  	AddInLogMessageText("Debug: %s", NOERROR, buf);
  }
  
  /* Get the value of a server (CGI) variable as a string
   */
  static int GetVariable(struct jk_env *env, jk_ws_service_t *s, char *hdrName,
  					 char *buf, DWORD bufsz, char **dest, const char *dflt) {
  	int errID;
  	private_ws_t *ws = (private_ws_t *) s->ws_private;
  
  	if (ws->context->GetServerVariable(ws->context, hdrName, buf, bufsz, &errID)) {
  		*dest = s->pool->pstrdup(env, s->pool, buf);
  	} else {
  		*dest = s->pool->pstrdup(env, s->pool, dflt);
  	}
  
  	/* env->l->jkLog(env, env->l, JK_LOG_DEBUG, "%s=%s\n", hdrName, *dest); */
  
  	return JK_TRUE;
  }
  
  /* Get the value of a server (CGI) variable as an integer
   */
  static int GetVariableInt(struct jk_env *env, jk_ws_service_t *s, char *hdrName,
  						char *buf, DWORD bufsz, int *dest, int dflt) {
  	int errID;
  	private_ws_t *ws = (private_ws_t *) s->ws_private;
  
  	if (ws->context->GetServerVariable(ws->context, hdrName, buf, bufsz, &errID)) {
  		*dest = atoi(buf);
  	} else {
  		*dest = dflt;
  	}
  
  	/* env->l->jkLog(env, env->l, JK_LOG_DEBUG, "%s=%d\n", hdrName, *dest); */
  
  	return JK_TRUE;
  }
  
  /* Get the value of a server (CGI) variable as an integer
   */
  static int GetVariableBool(struct jk_env *env, jk_ws_service_t *s, char *hdrName,
  						char *buf, DWORD bufsz, int *dest, int dflt) {
  	int errID;
  	private_ws_t *ws = (private_ws_t *) s->ws_private;
  
  	if (ws->context->GetServerVariable(ws->context, hdrName, buf, bufsz, &errID)) {
  		if (isdigit(buf[0]))
  			*dest = atoi(buf) != 0;
  		else if (NoCaseStrCmp(buf, "yes") == 0 || NoCaseStrCmp(buf, "on") == 0)
  			*dest = 1;
  		else
  			*dest = 0;
  	} else {
  		*dest = dflt;
  	}
  
  	/* env->l->jkLog(env, env->l, JK_LOG_DEBUG, "%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(env, s, (name), workBuf, sizeof(workBuf), (dest), (dflt))
  #define GETVARIABLEINT(name, dest, dflt)	\
  	GetVariableInt(env, s, (name), workBuf, sizeof(workBuf), (dest), (dflt))
  #define GETVARIABLEBOOL(name, dest, dflt)	\
  	GetVariableBool(env, s, (name), workBuf, sizeof(workBuf), (dest), (dflt))
  
  /* Return 1 iff the supplied string contains "web-inf" (in any case
   * variation. We don't allow URIs containing web-inf, although
   * FindPathElem() actually looks for the string bounded by path punctuation
   * or the ends of the string, so web-inf must appear as a single element
   * of the supplied URI
   */
  static int BadURI(const char *uri) {
  	static const char *wi = "web-inf";
  	return FindPathElem(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;
  }
  
  /* Allocate space for a string given a start pointer and an end pointer
   * and return a pointer to the allocated, copied string.
   */
  static char *SubStr(jk_env_t *env, jk_pool_t *pool, const char *start, const char *end) {
  	char *out = NULL;
  
  	if (start != NULL && end != NULL && end > start) {
  		int len = end - start;
  		if (out = pool->alloc(env, pool, len + 1), NULL != out) {
  			memcpy(out, start, len);
  			out[len] = '\0';
  		}
  	}
  	return out;
  }
  
  /* Like SubStr() but use a static buffer if possible.
   */
  static char *MagicSubStr(jk_env_t *env, jk_pool_t *pool, char **bufp, int *bufSz,
  							const char *start, const char *end) {
  	int len = end - start;
  	if (len < *bufSz) {
  		char *rv = *bufp;
  		memcpy(rv, start, len);
  		rv[len++] = '\0';
  		/* Adjust buffer pointer, length */
  		*bufp  += len;
  		*bufSz -= len;
  		return rv;
  	} else {
  		return SubStr(env, pool, start, end);
  	}
  }
  
  static char *StrDup(jk_env_t *env, jk_pool_t *pool, const char *str) {
  	if (NULL == str) {
  		return NULL;
  	}
  
  	return SubStr(env, pool, str, str + strlen(str));
  }
  
  /* Given all the HTTP headers as a single string parse them into individual
   * name, value pairs.
   */
  static int ParseHeaders(jk_env_t *env, jk_ws_service_t *s, const char *hdrs, int hdrSz) {
  	int hdrCount = 0;
  	const char *limit = hdrs + hdrSz;
  	const char *name, *nameEnd;
  	const char *value, *valueEnd;
  	int gotContentLength = FALSE;
  	char buf[256];		/* Static buffer used for headers that are short enough to fit
  						 * in it. A dynamic buffer is used for any longer headers.
  						 */
  
  	while (hdrs < limit) {
  		/* buf is re-used for each header */
  		char *bufp = buf;
  		char *hdrName, *hdrValue;
  		int sz = sizeof(buf);
  
  		/* Skip line *before* doing anything, cos we want to lose the first line which
  		 * contains the request. This code also moves to the next line after each header.
  		 */
  		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;
  		}
  
  		hdrName		= MagicSubStr(env, s->pool, &bufp, &sz, name, nameEnd);
  
  		/* Need to strdup the value because map->put doesn't for some reason */
  		hdrValue	= SubStr(env, s->pool, value, valueEnd);
  
          s->headers_in->put(env, s->headers_in, hdrName, hdrValue, NULL);
  
  		gotContentLength |= (NoCaseStrCmp(hdrName, CONTENT_LENGTH) == 0);
  
  		hdrCount++;
  	}
  
  	/* Add a zero length content-length header if none was found in the 
  	 * request.
  	 */
  	if (!gotContentLength) {
  		s->headers_in->put(env, s->headers_in, CONTENT_LENGTH, "0", NULL);
  		hdrCount++;
  	}
  
  	return hdrCount;
  }
  
  static int JK_METHOD cbInit(struct jk_env *env, jk_ws_service_t *s,
  							struct jk_worker *w, void *serverObj) {
  	return JK_TRUE;
  }
  
  /* Post request cleanup.
   */
  static void JK_METHOD cbAfterRequest( struct jk_env *env, jk_ws_service_t *_this) {
  
  }
  
  /* Set the response head in the server structures. This will be called
   * before the first write.
   */
  static int JK_METHOD cbHead(struct jk_env *env, jk_ws_service_t *s) {
  	/* env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Into jk_ws_service_t::cbHead\n"); */
  
  	if (s->status < 100 || s->status > 1000) {
  		env->l->jkLog(env, env->l, JK_LOG_ERROR, "jk_ws_service_t::cbHead, invalid status %d\n", s->status);
  		return JK_ERR;
  	}
  
  	if (s && s->ws_private) {
  		private_ws_t *p = s->ws_private;
  
  		if (!p->responseStarted) {
  			char *hdrBuf;
  			FilterResponseHeaders frh;
  			int rc, errID;
  			int hdrCount;
  			const char *reason;
  
  			p->responseStarted = JK_TRUE;
  
  			if (NULL == s->msg) {
  				reason = "";
  			} else {
  				reason = s->msg;
  			}
  
  			hdrCount = s->headers_out->size(env, s->headers_out);
  
  			/* Build a single string containing all the headers
  			 * because that's what Domino needs.
  			 */
  			if (hdrCount > 0) {
  				int i;
  				int hdrLen;
  				char *bufp;
  
  				for (i = 0, hdrLen = 3; i < hdrCount; i++) {
  					hdrLen += strlen(s->headers_out->nameAt(env, s->headers_out, i));
  					hdrLen += strlen(s->headers_out->valueAt(env, s->headers_out, i));
  					hdrLen += 4;
  				}
  
  				hdrBuf = s->pool->alloc(env, s->pool, hdrLen);
  				bufp = hdrBuf;
  
  				for (i = 0; i < hdrCount; i++) {
  					Append(&bufp, s->headers_out->nameAt(env, s->headers_out, i));
  					Append(&bufp, ": ");
  					Append(&bufp, s->headers_out->valueAt(env, s->headers_out, i));
  					Append(&bufp, crlf);
  				}
  
  				Append(&bufp, crlf);
  			} else {
  				hdrBuf = (char *) crlf;
  			}
  
  			frh.responseCode = s->status;
  			frh.reasonText = (char *) reason;
  			frh.headerText = hdrBuf;
  
  			/* env->l->jkLog(env, env->l, JK_LOG_DEBUG, "%d %s\n", s->status, reason); */
  
  			/* Send the headers */
  			rc = p->context->ServerSupport(p->context, kWriteResponseHeaders, &frh, NULL, 0, &errID);
  		}
  		return JK_OK;
  	}
  
  	env->l->jkLog(env, env->l, JK_LOG_ERROR, "jk_ws_service_t::cbHead, NULL parameters\n");
  
  	return JK_ERR;
  }
  
  /*
   * Read a chunk of the request body into a buffer.  Attempt to read len
   * bytes into the buffer.  Write the number of bytes actually read into
   * actually_read.  
   */
  static int JK_METHOD cbRead(struct jk_env *env, jk_ws_service_t *s,
  							  void *bytes,
  							  unsigned len,
  							  unsigned *actually_read) {
      /* env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Into jk_ws_service_t::Read\n"); */
  
  	if (s && s->ws_private && bytes && actually_read) {
  		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;
  		*actually_read = len;
  		return JK_OK;
  	}
  
  	env->l->jkLog(env, env->l, JK_LOG_ERROR, "jk_ws_service_t::Read, NULL parameters\n");
  
  	return JK_ERR;
  }
  
  /*
   * Write a chunk of response data back to the browser.
   */
  static int JK_METHOD cbWrite(struct jk_env *env, jk_ws_service_t *s,
  							 const void *bytes, unsigned len) {
  
  	/* env->l->jkLog(env, env->l, 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;
  
  		/* Send the data */
  		if (len > 0) {
  			rc = p->context->WriteClient(p->context, (char *) bytes, len, 0, &errID);
  		}
  
  		return JK_OK;
  	}
  
  	env->l->jkLog(env, env->l, JK_LOG_ERROR, "jk_ws_service_t::Write, NULL parameters\n");
  
  	return JK_ERR;
  }
  
  /*
   * Flush the output buffers.
   */
  static int JK_METHOD cbFlush(struct jk_env *env, jk_ws_service_t *s) {
  	return JK_OK;
  }
  
  /* Return TRUE iff the specified filename is absolute. Note that this is only
   * called in cases where the definition of 'absolute' is not security sensitive. I'm
   * sure there are ways of constructing absolute Win32 paths that it doesn't catch.
   */
  static int IsAbsolute(const char *fn) {
  #ifdef WIN32
  	return fn[0] == '\\' || (isalpha(fn[0]) && fn[1] == ':');
  #else
  	return fn[0] == '/';
  #endif
  }
  
  static const char *AbsPath(jk_env_t *env, const char *base, const char *name) {
  	if (base == NULL || IsAbsolute(name)) {
  		return name;
  	} else {
  		int bsz = strlen(base);
  		int nsz = strlen(name);
  		int ads = (base[bsz-1] != PATHSEP) ? 1 : 0;
  		char *buf;
  		if (buf = workerEnv->pool->alloc(env, workerEnv->pool, bsz + ads + nsz + 1), NULL == buf) {
  			return NULL;
  		}
  		memcpy(buf, base, bsz);
  		if (ads) {
  			buf[bsz] = PATHSEP;
  		}
  		memcpy(buf + bsz + ads, name, nsz);
  		buf[bsz + ads + nsz] = '\0';
  
  		return buf;
  	}
  }
  
  #ifdef WIN32
  static const char *ReadRegistry(jk_env_t *env, HKEY hkey, const char *key, const char *base) {
  	DWORD type = 0;
  	DWORD sz = 0;
  	LONG rc;
  	char *val;
  
  	rc = RegQueryValueEx(hkey, key, (LPDWORD) 0, &type, NULL, &sz);
  	if (rc != ERROR_SUCCESS || type != REG_SZ) {
  		return NULL;
  	}
  
  	if (val = workerEnv->pool->alloc(env, workerEnv->pool, sz), NULL == val) {
  		return NULL;
  	}
  
  	rc = RegQueryValueEx(hkey, key, (LPDWORD) 0, &type, val, &sz);
  	if (rc == ERROR_SUCCESS) {
  		return AbsPath(env, base, val);
  	}
  
  	return NULL;
  }
  #endif
  
  static int ReadFromRegistry(jk_env_t *env) {
  #ifdef WIN32
  	HKEY hkey;
  	long rc;
  
  	rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGISTRY_LOCATION, (DWORD) 0, KEY_READ, &hkey);
  	if (ERROR_SUCCESS != rc) {
  		return JK_FALSE;
  	}
  
  	serverRoot	= ReadRegistry(env, hkey, SERVER_ROOT_TAG,	NULL);
  	workersFile	= ReadRegistry(env, hkey, WORKER_FILE_TAG,	serverRoot);
  	tomcatStart	= ReadRegistry(env, hkey, TOMCAT_START_TAG,	serverRoot);
  	tomcatStop	= ReadRegistry(env, hkey, TOMCAT_STOP_TAG,	serverRoot);
  
  	RegCloseKey(hkey);
  
      iniFileUsed = JK_FALSE;
  
      return	NULL != serverRoot &&
  			NULL != workersFile;
  
  #else
  	return JK_FALSE;
  #endif
  }
  
  /* Read an entry from a map and return a newly allocated copy of it
   * on success or NULL on failure.
   */
  static const char *ReadMap(jk_env_t *env, jk_map_t *map, const char *name, const char *base)
  {
  	const char *s = map->get(env, map, name);
  	if (s) {
  		return AbsPath(env, base, workerEnv->pool->pstrdup(env, workerEnv->pool, s));
  	}
  	return NULL;
  }
  
  /* Read parameters from an ini file or the registry
   */
  static int ReadInitData(jk_env_t *env) {
      jk_map_t *map;
  
  	/* Attempt to read from an ini file */
      if (JK_OK == jk2_map_default_create(env, &map, workerEnv->pool )) {
          if (JK_OK == jk2_config_file_read(env, map, iniFileName)) {
  			serverRoot	= ReadMap(env, map, SERVER_ROOT_TAG,	NULL);
  			workersFile = ReadMap(env, map, WORKER_FILE_TAG,	serverRoot);
  			tomcatStart = ReadMap(env, map, TOMCAT_START_TAG,	serverRoot);
  			tomcatStop	= ReadMap(env, map, TOMCAT_STOP_TAG,	serverRoot);
  
              iniFileUsed = JK_TRUE;
              return	NULL != serverRoot &&
  					NULL != workersFile;
          }
      } else {
          env->l->jkLog(env, env->l, JK_LOG_ERROR,
                 "read_registry_init_data, Failed to create map \n");
      }
  
  	return ReadFromRegistry(env);
  }
  
  /* 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[35];
  
  	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;
  }
  
  /* 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 RejectWithError(FilterContext *context) {
  	static char *msg = "<html><body><h1>Error in Filter</h1></body></html>";
  
  	SimpleResponse(context, 500, "Error in Filter", msg);
  
  	return kFilterHandledRequest;
  }
  
  /* Initialize the service structure
   */
  static int ProcessRequest(struct jk_env *env, jk_ws_service_t *s,
  					struct jk_worker *w, void *serverObj) {
  	/* This is the only fixed size buffer left. It won't be overflowed
  	 * because the Domino API that reads into the buffer accepts a length
  	 * constraint, and it's unlikely ever to be exhausted because the
  	 * strings being will typically be short, but it's still aesthetically
  	 * troublesome.
  	 */
  	char workBuf[16 * 1024];
  	private_ws_t *ws = (private_ws_t *) s->ws_private;
  	FilterRequest fr;
  	char *hdrs;
  	int hdrsz;
  	int errID = 0;
  	int hdrCount;
  	int rc;
  
  	static char *methodName[] = { "", "HEAD", "GET", "POST", "PUT", "DELETE" };
  
  	/* env->l->jkLog(env, env->l, JK_LOG_DEBUG, "ProcessRequest(), s = %p, ws = %p\n", s, ws); */
  
  	/* Should this rc be checked? */
  	rc = ws->context->GetRequest(ws->context, &fr, &errID);
  
  	s->jvm_route = NULL;
  
  	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, SERVERDFLT);
  	GETVARIABLEINT("CONTENT_LENGTH", &s->content_length, 0);
  
  	/* SSL Support
  	 */
  	GETVARIABLEBOOL("HTTPS", &s->is_ssl, 0);
  
  	if (ws->reqData->requestMethod < 0 ||
  		ws->reqData->requestMethod >= sizeof(methodName) / sizeof(methodName[0])) {
  		return JK_ERR;
  	}
  
  	s->method			= methodName[ws->reqData->requestMethod];
  	s->ssl_cert_len		= fr.clientCertLen;
  	s->ssl_cert			= fr.clientCert;
  	s->ssl_cipher		= NULL;
  	s->ssl_session		= NULL;
  	s->ssl_key_size		= -1;
  
      if (JK_OK != jk2_map_default_create(env, &s->headers_out, s->pool)) {
          env->l->jkLog(env, env->l, JK_LOG_ERROR, "jk_ws_service_t::init, Failed to create headers_out map\n");
          return JK_ERR;
      }
  
      if (JK_OK != jk2_map_default_create(env, &s->attributes, s->pool)) {
          env->l->jkLog(env, env->l, JK_LOG_ERROR, "jk_ws_service_t::init, Failed to create attributes map\n");
          return JK_ERR;
  
      }
  
      if (JK_OK!=jk2_map_default_create(env, &s->headers_in, s->pool)) {
          env->l->jkLog(env, env->l, JK_LOG_ERROR, "jk_ws_service_t::init, Failed to create headers_in map\n");
          return JK_ERR;
      }
  
  	if (s->is_ssl) {
  		int i, dummy;
  
  		char *sslNames[] = {
  			"CERT_ISSUER", "CERT_SUBJECT", "CERT_COOKIE", "CERT_FLAGS", "CERT_SERIALNUMBER",
  			"HTTPS_SERVER_SUBJECT", "HTTPS_SECRETKEYSIZE", "HTTPS_SERVER_ISSUER", "HTTPS_KEYSIZE"
  		};
  
  		/* env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Request is SSL\n"); */
  
  		/* Read the variable into a dummy variable: we do this for the side effect of
  		 * reading it into workBuf.
  		 */
  		GETVARIABLEINT("HTTPS_KEYSIZE", &dummy, 0);
  		if (workBuf[0] == '[') {
  			s->ssl_key_size = atoi(workBuf+1);
  		}
  
  		/* Should also try to make suitable values for s->ssl_cipher and
  		 * s->ssl_session
  		 */
  		for (i = 0; i < sizeof(sslNames) / sizeof(sslNames[0]); i++) {
  			char *value = NULL;
  			GETVARIABLE(sslNames[i], &value, NULL);
  			if (value) {
  				s->attributes->put(env, s->attributes, sslNames[i], value, NULL);
  			}
  		}
  	}
  
  	/* Duplicate all the headers now */
  
  	hdrsz = ws->reqData->GetAllHeaders(ws->context, &hdrs, &errID);
  	if (0 == hdrsz) {
  		return JK_ERR;
  	}
  
  	hdrCount = ParseHeaders(env, s, hdrs, hdrsz);
  
  	return JK_OK;
  }
  
  /* 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;
  
  	/* TODO: presumably this return code should be checked */
  	rc = context->GetRequest(context, &fr, &errID);
  
  	if (fr.URL && strlen(fr.URL)) {
  		char *uri = fr.URL;
  		char *qp, *turi;
  	    jk_uriEnv_t *uriEnv = NULL;
  		int errID;
  		char buf[256];	/* enough for the server's name */
  		char *serverName;
  		size_t serverNameSz;
  		int serverPort;
  		char *uriBuf;
  		size_t uriSz, uriBufSz;
  	    jk_env_t *env = workerEnv->globalEnv->getEnv(workerEnv->globalEnv);
  
  		/* env->l->jkLog(env, env->l, JK_LOG_DEBUG, "ParsedRequest() - %s\n", uri); */
  
  		if (!context->GetServerVariable(context, "SERVER_PORT", buf, sizeof(buf), &errID)) {
  			return RejectWithError(context);
  		}
  
  		serverPort = atoi(buf);
  
  		if (!context->GetServerVariable(context, "SERVER_NAME", buf, sizeof(buf), &errID)) {
  			return RejectWithError(context);
  		}
  
  		serverName = buf;	/* note serverName just aliases buf
  							 * and will be destroyed if buf is reused
  							 */
  
  		serverNameSz = strlen(serverName) + 1;
  
  		uriBuf   = serverName + serverNameSz;
  		uriBufSz = sizeof(buf) - serverNameSz;
  		uriSz    = strlen(uri) + 1;
  
  		/* Use the stack buffer for sufficiently short URIs */
  		if (uriSz <= uriBufSz) {
  			turi = uriBuf;
  		} else {
  			turi = context->AllocMem(context, uriSz, 0, &errID);
  		}
  		memcpy(turi, uri, uriSz);
  	
          rc = jk_requtil_unescapeUrl(turi);
  		if (rc < 0) {
  			return RejectWithError(context);
  		}
  
          jk_requtil_getParents(turi);
          if (qp = strchr(turi, '?'), qp != NULL) {
  			*qp++ = '\0';
  		}
  
  		if (BadURI(turi)) {
  			return RejectBadURI(context);
  		}
  
          uriEnv = workerEnv->uriMap->mapUri(env, workerEnv->uriMap, serverName, serverPort, turi);
          
  		if (NULL != uriEnv) {
  			// Here we go
  			private_ws_t ws;
  			jk_ws_service_t s;
  		    jk_pool_t *rPool = NULL;
  		    jk_worker_t *worker = uriEnv->worker;
  
  			rPool = worker->rPoolCache->get(env, worker->rPoolCache);
  			if (NULL == rPool) {
  				rPool = worker->mbean->pool->create(env, worker->mbean->pool, HUGE_POOL_SIZE);
  				/* env->l->jkLog(env, env->l, JK_LOG_DEBUG, "HttpExtensionProc: new rpool\n"); */
  			}
  
  			jk2_requtil_initRequest(env, &s);
  
  			s.pool					= rPool;		/* Do we need one? */
  			s.is_recoverable_error	= JK_FALSE;
  			s.response_started		= JK_FALSE;
  			s.content_read			= 0;
  			s.ws_private			= &ws;
  			s.workerEnv				= workerEnv;
  			s.head					= cbHead;
  			s.read					= cbRead;
  			s.write					= cbWrite;
  			s.init					= cbInit;
  			s.afterRequest			= cbAfterRequest;
  
              if (workerEnv->options == JK_OPT_FWDURICOMPATUNPARSED) {
  				s.req_uri = StrDup(env, rPool, uri);
  				/* Find the query string again in the original URI */
  				if (qp = strchr(s.req_uri, '?'), NULL != qp) {
  					*qp++ = '\0';
  				}
              } else if (workerEnv->options == JK_OPT_FWDURIESCAPED) {
  				/* Nasty static buffer */
  				char euri[256];
  				if (jk_requtil_escapeUrl(turi, euri, sizeof(euri))) {
  					turi = euri;
  				}
  				s.req_uri = turi;
              } else {
  				s.req_uri = turi;
              }
  
  			s.query_string			= qp;
  
  			/* Init our private structure
  			 */
  			ws.responseStarted		= JK_FALSE;
  			ws.context				= context;
  			ws.reqData				= reqData;
  
  			/* Fetch info about the request
  			 */
  			ws.reqSize = context->GetRequestContents(context, &ws.reqBuffer, &errID);
  
  			rc = ProcessRequest(env, &s, worker, context);
  			if (JK_OK == rc) {
  				rc = worker->service(env, uriEnv->worker, &s);
  			}
  
  			if (JK_OK == rc) {
  				result = kFilterHandledRequest;
  				/* env->l->jkLog(env, env->l, JK_LOG_DEBUG, "HttpExtensionProc service() returned OK\n"); */
  			} else {
  				result = kFilterError;
  				env->l->jkLog(env, env->l, JK_LOG_ERROR, "HttpExtensionProc error, service() failed\n");
  			}
  
  			s.afterRequest(env, &s);
  
  			rPool->reset(env, rPool);
  			rc = worker->rPoolCache->put(env, worker->rPoolCache, rPool);
  		}
  
  		workerEnv->globalEnv->releaseEnv(workerEnv->globalEnv, env);
  	}
  
  	return result;
  }
  
  /* Main entry point for the filter. Called by Domino for every HTTP request.
   */
  DLLEXPORT unsigned int HttpFilterProc(FilterContext *context, unsigned int eventType, void *eventData) {
  	switch (eventType) {
  	case kFilterParsedRequest:
  		return ParsedRequest(context, (FilterParsedRequest *) eventData);
  	default:
  		break;
  	}
  
  	return kFilterNotHandled;
  }
  
  static int RunProg(const char *cmd) {
  #ifdef WIN32
      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, (char *) cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))	{
  		DWORD err = GetLastError();
  		AddInLogMessageText("Command \"%s\" failed (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;
  
  #else
  	int err = system(cmd);
  	if (0 == err) {
  		return 1;
  	}
  	AddInLogMessageText("Command \"%s\" failed (error %d)", NOERROR, cmd, err);
  	return 0;
  #endif
  }
  
  /* Called when the filter is unloaded. Free various resources and
   * display a banner.
   */
  DLLEXPORT unsigned int TerminateFilter(unsigned int reserved) {
      jk_env_t *env = workerEnv->globalEnv->getEnv(workerEnv->globalEnv);
  
  	// TODO: Work out if we're doing everything we need to here
  	if (isInited) {
          if (workerEnv) {
              jk_env_t *env = workerEnv->globalEnv;
              workerEnv->close(env, workerEnv);
          }
  
  		isInited = JK_FALSE;
  
  	}
  
  #ifndef TESTING
  	if (NULL != tomcatStop && '\0' != *tomcatStop) {
  		AddInLogMessageText("Attempting to stop Tomcat: %s", NOERROR, tomcatStop);
  		RunProg(tomcatStop);
  	}
  #endif
  
  	AddInLogMessageText(FILTERDESC " unloaded", NOERROR);
  
      apr_pool_destroy(jk_globalPool);
  
  	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) {
      jk_logger_t *l;
      jk_pool_t *globalPool;
      jk_bean_t *jkb;
      jk_env_t *env;
  
  #ifndef WIN32
  	Dl_info info;
  	char *dot, *slash;
  
  	memset(&info, 0, sizeof(info));
  	if (!dladdr(FilterInit, &info) || NULL == info.dli_fname) {
  		goto initFailed;
  	}
  
  	lstrcpyn(libFileName, info.dli_fname, sizeof(libFileName)-1);
  	lstrcpyn(iniFileName, info.dli_fname, sizeof(libFileName)-1);
  	char *slash = strrchr(iniFileName, PATHSEP);
  	if (NULL == slash) {
  		slash = iniFileName;
  	} else {
  		slash++;
  	}
  	char *dot = strrchr(slash, '.');
  	if (NULL == dot) {
  		dot = slash + strlen(slash);
  	}
  	lstrcpyn(slash, ".properties", (iniFileName + sizeof(iniFileName) - 1) - slash);
  #endif
  
      apr_initialize();
      apr_pool_create(&jk_globalPool, NULL);
  
      jk2_pool_apr_create(NULL, &globalPool, NULL, jk_globalPool);
  
      /* Create the global environment. This will register the default
       * factories
       */
      env = jk2_env_getEnv(NULL, globalPool);
  
  #ifdef TESTING
      env->registerFactory(env, "logger.printf", jk2_logger_printf_factory);
  #endif
  
      jkb = env->createBean2(env, env->globalPool, LOGGER, "");
      env->alias(env, LOGGER ":", "logger");
      l = jkb->object;
  
  #ifdef _DEBUG
  	l->level = JK_LOG_DEBUG_LEVEL;	/* is that naughty? */
  #endif
  
      env->l = l;
      env->soName = env->globalPool->pstrdup(env, env->globalPool, libFileName);
  
      if (NULL == env->soName) {
          env->l->jkLog(env, env->l, JK_LOG_ERROR, "Error creating env->soName\n");
  		goto initFailed;
      }
  
  	/* Initialise logger
  	 */
      env->l->init(env, env->l);
  
      /* We should make it relative to JK_HOME or absolute path.
         ap_serverRoot_relative(cmd->pool, opt); */
  
      /* Create the workerEnv
  	 */
      jkb = env->createBean2(env, env->globalPool,"workerEnv", "");
      workerEnv = jkb->object;
      env->alias(env, "workerEnv:", "workerEnv");
  
      if (NULL == workerEnv) {
          env->l->jkLog(env, env->l, JK_LOG_ERROR, "Error creating workerEnv\n");
          goto initFailed;
      }
  
      workerEnv->childId = 0;
  
  	if (!ReadInitData(env)) {
  		goto initFailed;
  	}
  
      workerEnv->initData->add(env, workerEnv->initData, "serverRoot",
                               workerEnv->pool->pstrdup(env, workerEnv->pool, serverRoot));
  
      env->l->jkLog(env, env->l, JK_LOG_INFO, "Set serverRoot %s\n", serverRoot);
  
  	/* Note: we cast away the const qualifier on workersFile here
  	 */
  
  	if (JK_OK != workerEnv->config->setPropertyString(env, workerEnv->config,
  														"config.file", (char *) workersFile)) {
  		goto initFailed;
  	}
  
      workerEnv->init(env, workerEnv);
  
  #ifndef TESTING
  	/* Attempt to launch Tomcat
  	 */
  	if (NULL != tomcatStart && '\0' != *tomcatStart) {
  		AddInLogMessageText("Attempting to start Tomcat: %s", NOERROR, tomcatStart);
  		RunProg(tomcatStart);
  	}
  #endif
  
  	filterInitData->appFilterVersion = kInterfaceVersion;
  	filterInitData->eventFlags = kFilterParsedRequest;
  	strcpy(filterInitData->filterDesc, FILTERDESC);
  
  	isInited = JK_TRUE;
  
  	/* Display banner
  	 */
  	AddInLogMessageText("%s loaded", NOERROR, filterInitData->filterDesc);
  
  	return kFilterHandledEvent;
  
  initFailed:
  	AddInLogMessageText("Error loading %s", NOERROR, FILTERDESC);
  	return kFilterError;
  }
  
  #ifdef WIN32
  /* Handle DLL initialisation (on WIN32) by working out what the INI file
   * should be called.
   */
  BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ulReason, LPVOID lpReserved) {
  	BOOL fReturn = TRUE;
  	char drive[_MAX_DRIVE];
  	char dir[_MAX_DIR];
  	char fname[_MAX_FNAME];
  
  	switch (ulReason) {
  	case DLL_PROCESS_ATTACH:
  		/* TODO: Work out a way to do this on other platforms. */
  		if (GetModuleFileName(hInst, libFileName, sizeof(libFileName))) {
  			_splitpath(libFileName, drive, dir, fname, NULL);
  			_makepath(iniFileName, drive, dir, fname, ".properties");
  		} else {
  			fReturn = FALSE;
  		}
  		break;
  	default:
  		break;
  	}
  	return fReturn;
  }
  #endif
  
  #ifdef TESTING
  /* Handle initialisation in the test harness environment.
   */
  void TestMain(void) {
  	strcpy(libFileName, "test.exe");
  	strcpy(iniFileName, "test.properties");
  }
  #endif
  
  
  
  1.1                  jakarta-tomcat-connectors/jk/native2/server/dsapi/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/native2/server/dsapi/dsapi_redirector2.reg
  
  Index: dsapi_redirector2.reg
  ===================================================================
  Windows Registry Editor Version 5.00
  
  [HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Dsapi Redirector\2.0]
  "serverRoot"="D:\\Works\\Tomcat\\jakarta-tomcat-4.1.27"
  "workersFile"="conf\\workers.properties"
  "tomcatStart"="bin\\startup.bat"
  "tomcatStop"="bin\\shutdown.bat"
  
  
  
  1.1                  jakarta-tomcat-connectors/jk/native2/server/dsapi/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>
  {{{
  }}}
  
  ###############################################################################
  
  Project: "test"=".\test\test.dsp" - Package Owner=<4>
  
  Package=<5>
  {{{
  }}}
  
  Package=<4>
  {{{
  }}}
  
  ###############################################################################
  
  Global:
  
  Package=<5>
  {{{
  }}}
  
  Package=<3>
  {{{
  }}}
  
  ###############################################################################
  
  
  
  
  1.1                  jakarta-tomcat-connectors/jk/native2/server/dsapi/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 Static
  !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 Static"
  !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 "dsapi - Win32 Debug Static" (based on "Win32 (x86) Dynamic-Link Library")
  !MESSAGE "dsapi - Win32 Release Static" (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 /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ISAPI_EXPORTS" /YX /FD /c
  # ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /I "..\..\..\..\..\apr\include" /I "..\..\..\..\..\apr-util\include" /I "..\..\..\..\..\pcre\include" /I "$(NOTESAPI)\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HAVE_JNI" /D "HAS_APR" /D "HAS_PCRE" /D "NT" /U "NOUSER" /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 0xc0a /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 libapr.lib libaprutil.lib ws2_32.lib wsock32.lib advapi32.lib pcre.lib pcreposix.lib notes.lib /nologo /dll /machine:I386 /out:"Release/dsapi_redirector2.dll" /libpath:"..\..\..\..\..\apr\Release" /libpath:"..\..\..\..\..\pcre\lib" /libpath:"..\..\..\..\..\apr-util\Release" /libpath:"$(NOTESAPI)\lib\mswin32"
  
  !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 "ISAPI_EXPORTS" /YX /FD /GZ /c
  # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /I "..\..\..\..\..\apr\include" /I "..\..\..\..\..\apr-util\include" /I "..\..\..\..\..\pcre\include" /I "$(NOTESAPI)\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HAVE_JNI" /D "HAS_APR" /D "HAS_PCRE" /D "NT" /U "NOUSER" /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 0xc0a /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 libapr.lib libaprutil.lib ws2_32.lib wsock32.lib advapi32.lib pcre.lib pcreposix.lib notes.lib /nologo /dll /debug /machine:I386 /out:"Debug/dsapi_redirector2.dll" /pdbtype:sept /libpath:"..\..\..\..\..\apr\Release" /libpath:"..\..\..\..\..\pcre\lib" /libpath:"..\..\..\..\..\apr-util\Release" /libpath:"$(NOTESAPI)\lib\mswin32"
  # SUBTRACT LINK32 /nodefaultlib
  
  !ELSEIF  "$(CFG)" == "dsapi - Win32 Debug Static"
  
  # PROP BASE Use_MFC 0
  # PROP BASE Use_Debug_Libraries 1
  # PROP BASE Output_Dir "DebugS"
  # PROP BASE Intermediate_Dir "DebugS"
  # PROP BASE Ignore_Export_Lib 0
  # PROP BASE Target_Dir ""
  # PROP Use_MFC 0
  # PROP Use_Debug_Libraries 1
  # PROP Output_Dir "DebugS"
  # PROP Intermediate_Dir "DebugS"
  # PROP Ignore_Export_Lib 0
  # PROP Target_Dir ""
  # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /I "$(APACHE2_HOME)\include" /I "$(APACHE2_HOME)\os\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ISAPI_EXPORTS" /D "HAVE_JNI" /D "HAS_APR" /FR /YX /FD /GZ /c
  # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\include" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /I "..\..\..\..\..\apr\include" /I "..\..\..\..\..\apr-util\include" /I "..\..\..\..\..\pcre\include" /I "$(NOTESAPI)\include" /D "_DEBUG" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HAVE_JNI" /D "HAS_APR" /D "HAS_PCRE" /D "NT" /U "NOUSER" /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 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 libapr.lib libaprutil.lib wsock32.lib advapi32.lib /nologo /dll /debug /machine:I386 /out:"Debug/dsapi_redirector2.dll" /pdbtype:sept /libpath:"$(APACHE2_HOME)\lib"
  # SUBTRACT BASE LINK32 /nodefaultlib
  # ADD LINK32 libapr.lib libaprutil.lib ws2_32.lib wsock32.lib advapi32.lib pcre.lib pcreposix.lib notes.lib /nologo /dll /debug /machine:I386 /out:"DebugS/dsapi_redirector2.dll" /pdbtype:sept /libpath:"..\..\..\..\..\apr\Release" /libpath:"..\..\..\..\..\pcre\lib" /libpath:"..\..\..\..\..\apr-util\Release" /libpath:"$(NOTESAPI)\lib\mswin32"
  # SUBTRACT LINK32 /nodefaultlib
  
  !ELSEIF  "$(CFG)" == "dsapi - Win32 Release Static"
  
  # PROP BASE Use_MFC 0
  # PROP BASE Use_Debug_Libraries 0
  # PROP BASE Output_Dir "ReleaseS"
  # PROP BASE Intermediate_Dir "ReleaseS"
  # PROP BASE Ignore_Export_Lib 0
  # PROP BASE Target_Dir ""
  # PROP Use_MFC 0
  # PROP Use_Debug_Libraries 0
  # PROP Output_Dir "ReleaseS"
  # PROP Intermediate_Dir "ReleaseS"
  # PROP Ignore_Export_Lib 0
  # PROP Target_Dir ""
  # ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /I "$(APACHE2_HOME)\include" /I "$(APACHE2_HOME)\os\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ISAPI_EXPORTS" /D "HAVE_JNI" /D "HAS_APR" /FR /YX /FD /c
  # ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /I "..\..\..\..\..\apr\include" /I "..\..\..\..\..\apr-util\include" /I "..\..\..\..\..\pcre\include" /I "$(NOTESAPI)\include" /D "NDEBUG" /D "_WIN32" /D "APR_DECLARE_STATIC" /D "APU_DECLARE_STATIC" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HAVE_JNI" /D "HAS_APR" /D "HAS_PCRE" /D "NT" /U "NOUSER" /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 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 libapr.lib libaprutil.lib wsock32.lib advapi32.lib /nologo /dll /machine:I386 /out:"Release/dsapi_redirector2.dll" /libpath:"$(APACHE2_HOME)\lib"
  # ADD LINK32 libapr.lib libaprutil.lib ws2_32.lib wsock32.lib advapi32.lib pcre.lib pcreposix.lib notes.lib /nologo /dll /machine:I386 /out:"ReleaseS/dsapi_redirector2.dll" /libpath:"..\..\..\..\..\apr\Release" /libpath:"..\..\..\..\..\pcre\lib" /libpath:"..\..\..\..\..\apr-util\Release" /libpath:"$(NOTESAPI)\lib\mswin32"
  
  !ENDIF 
  
  # Begin Target
  
  # Name "dsapi - Win32 Release"
  # Name "dsapi - Win32 Debug"
  # Name "dsapi - Win32 Debug Static"
  # Name "dsapi - Win32 Release Static"
  # Begin Group "Source Files"
  
  # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
  # Begin Group "JK2 Common Source"
  
  # PROP Default_Filter ""
  # Begin Source File
  
  SOURCE=..\..\common\jk_channel.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_channel_apr_socket.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_channel_jni.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_channel_un.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_config.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_config_file.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_endpoint.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_env.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_handler_logon.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_handler_response.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\jni\jk_jni_aprImpl.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_logger_file.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_logger_win32.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_map.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_md5.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_msg_ajp.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_mutex.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_mutex_proc.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_mutex_thread.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_nwmain.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_objCache.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_pool_apr.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_registry.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_requtil.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_shm.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_signal.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_uriEnv.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_uriMap.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_user.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_vm_default.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_worker_ajp13.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_worker_jni.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_worker_lb.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_worker_run.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_worker_status.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_workerEnv.c
  # End Source File
  # End Group
  # Begin Group "DSAPI Source"
  
  # PROP Default_Filter ""
  # Begin Source File
  
  SOURCE=.\jk_dsapi_plugin.c
  # End Source File
  # End Group
  # End Group
  # Begin Group "Header Files"
  
  # PROP Default_Filter "h;hpp;hxx;hm;inl"
  # Begin Group "JK2 Common Headers"
  
  # PROP Default_Filter ""
  # Begin Source File
  
  SOURCE=..\..\include\jk_channel.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_config.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_endpoint.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_env.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_global.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_handler.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_logger.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_logger_win32_message.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_map.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_md5.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_msg.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_objCache.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_pool.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_registry.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_requtil.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_service.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_shm.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_uriEnv.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_uriMap.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_vm.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_worker.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\include\jk_workerEnv.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\jni\org_apache_jk_apr_AprImpl.h
  # End Source File
  # End Group
  # Begin Group "DSAPI Headers"
  
  # PROP Default_Filter ""
  # Begin Source File
  
  SOURCE=.\config.h
  # End Source File
  # Begin Source File
  
  SOURCE=.\dsapifilter.h
  # End Source File
  # End Group
  # End Group
  # Begin Group "Resource Files"
  
  # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
  # Begin Source File
  
  SOURCE=..\..\common\jk_logger_win32_message.mc
  
  !IF  "$(CFG)" == "dsapi - Win32 Release"
  
  # Begin Custom Build - Creating resources from $(InputPath)
  InputDir=\Works\Tomcat\jakarta-tomcat-connectors\jk\native2\common
  InputPath=..\..\common\jk_logger_win32_message.mc
  
  "..\..\common\jk_logger_win32_message.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
  	mc -h $(InputDir) -r $(InputDir) $(InputPath)
  
  # End Custom Build
  
  !ELSEIF  "$(CFG)" == "dsapi - Win32 Debug"
  
  # PROP Ignore_Default_Tool 1
  # Begin Custom Build - Creating resources from $(InputPath)
  InputDir=\Works\Tomcat\jakarta-tomcat-connectors\jk\native2\common
  InputPath=..\..\common\jk_logger_win32_message.mc
  
  "..\..\common\jk_logger_win32_message.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
  	mc -h $(InputDir) -r $(InputDir) $(InputPath)
  
  # End Custom Build
  
  !ELSEIF  "$(CFG)" == "dsapi - Win32 Debug Static"
  
  # PROP BASE Ignore_Default_Tool 1
  # PROP Ignore_Default_Tool 1
  # Begin Custom Build - Creating resources from $(InputPath)
  InputDir=\Works\Tomcat\jakarta-tomcat-connectors\jk\native2\common
  InputPath=..\..\common\jk_logger_win32_message.mc
  
  "..\..\common\jk_logger_win32_message.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
  	mc -h $(InputDir) -r $(InputDir) $(InputPath)
  
  # End Custom Build
  
  !ELSEIF  "$(CFG)" == "dsapi - Win32 Release Static"
  
  # Begin Custom Build - Creating resources from $(InputPath)
  InputDir=\Works\Tomcat\jakarta-tomcat-connectors\jk\native2\common
  InputPath=..\..\common\jk_logger_win32_message.mc
  
  "..\..\common\jk_logger_win32_message.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
  	mc -h $(InputDir) -r $(InputDir) $(InputPath)
  
  # End Custom Build
  
  !ENDIF 
  
  # End Source File
  # Begin Source File
  
  SOURCE=..\..\common\jk_logger_win32_message.rc
  # End Source File
  # End Group
  # Begin Group "Other files"
  
  # PROP Default_Filter ""
  # Begin Source File
  
  SOURCE=.\dsapi_redirector2.reg
  # End Source File
  # Begin Source File
  
  SOURCE=.\todo.txt
  # End Source File
  # End Group
  # End Target
  # End Project
  
  
  
  1.1                  jakarta-tomcat-connectors/jk/native2/server/dsapi/config.h
  
  Index: config.h
  ===================================================================
  /* ========================================================================= *
   *                                                                           *
   *                 The Apache Software License,  Version 1.1                 *
   *                                                                           *
   *          Copyright (c) 1999-2001 The Apache Software Foundation.          *
   *                           All rights reserved.                            *
   *                                                                           *
   * ========================================================================= *
   *                                                                           *
   * Redistribution and use in source and binary forms,  with or without modi- *
   * fication, are permitted provided that the following conditions are met:   *
   *                                                                           *
   * 1. Redistributions of source code  must retain the above copyright notice *
   *    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. The end-user documentation  included with the redistribution,  if any, *
   *    must include the following acknowlegement:                             *
   *                                                                           *
   *       "This product includes  software developed  by the Apache  Software *
   *        Foundation <http://www.apache.org/>."                              *
   *                                                                           *
   *    Alternately, this acknowlegement may appear in the software itself, if *
   *    and wherever such third-party acknowlegements normally appear.         *
   *                                                                           *
   * 4. The names  "The  Jakarta  Project",  "Jk",  and  "Apache  Software     *
   *    Foundation"  must not be used  to endorse or promote  products derived *
   *    from this  software without  prior  written  permission.  For  written *
   *    permission, please contact <ap...@apache.org>.                        *
   *                                                                           *
   * 5. Products derived from this software may not be called "Apache" nor may *
   *    "Apache" appear in their names without prior written permission of the *
   *    Apache Software Foundation.                                            *
   *                                                                           *
   * THIS SOFTWARE IS PROVIDED "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 APACHE  SOFTWARE  FOUNDATION 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 indivi- *
   * duals on behalf of the  Apache Software Foundation.  For more information *
   * on the Apache Software Foundation, please see <http://www.apache.org/>.   *
   *                                                                           *
   * ========================================================================= */
  
  /***************************************************************************
   * Description: DSAPI plugin for Lotus Domino                              *
   * Author:      Andy Armstrong <an...@tagish.com>                           *
   * Version:     $Revision: 1.1 $                                           *
   ***************************************************************************/
  
  #ifndef __config_h
  #define __config_h
  
  #define MAKEVERSION(a, b, c, d) \
  	(((a) << 24) + ((b) << 16) + ((c) << 8) + (d))
  
  /* the _memicmp() function is available */
  #if defined(WIN32)
  
  #define HAVE_MEMICMP
  #define PATHSEP '\\'
  
  #elif defined(LINUX)
  
  #undef HAVE_MEMICMP
  #define PATHSEP '/'
  
  #elif defined(SOLARIS)
  
  #undef HAVE_MEMICMP
  #define PATHSEP '/'
  
  #else
  #error Please define one of WIN32, LINUX or SOLARIS
  #endif
  
  /* define if you don't have the Notes C API which is available from
   *
   *    http://www.lotus.com/rw/dlcapi.nsf
   */
  /* #undef NO_CAPI */
  
  #define DEBUG(args) \
  	do { _printf args ; } while (0)
  
  #endif /* __config_h */
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org