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/14 14:08:05 UTC

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

andya       2003/11/14 05:08:05

  Modified:    jk/native2/server/dsapi jk_dsapi_plugin.c
                        dsapi_redirector2.reg dsapi.dsp config.h
  Added:       jk/native2/server/dsapi INSTALL.txt BUILD.txt
  Log:
  Various changes, mainly cosmetic and some documentation now.
  
  Revision  Changes    Path
  1.2       +229 -274  jakarta-tomcat-connectors/jk/native2/server/dsapi/jk_dsapi_plugin.c
  
  Index: jk_dsapi_plugin.c
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native2/server/dsapi/jk_dsapi_plugin.c,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- jk_dsapi_plugin.c	13 Nov 2003 17:10:56 -0000	1.1
  +++ jk_dsapi_plugin.c	14 Nov 2003 13:08:05 -0000	1.2
  @@ -102,27 +102,6 @@
   /* 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);
  @@ -130,27 +109,22 @@
   #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 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 int tomcatTimeout		= TOMCAT_STARTSTOP_TO;
  +
  +static const char *crlf			= "\r\n";
   
   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
  @@ -174,9 +148,9 @@
   /* Case insentive memcmp() clone
    */
   #ifdef HAVE_MEMICMP
  -#define NoCaseMemCmp(ci, cj, l) _memicmp((void *) (ci), (void *) (cj), (l))
  +#define noCaseMemCmp(ci, cj, l) _memicmp((void *) (ci), (void *) (cj), (l))
   #else
  -static int NoCaseMemCmp(const char *ci, const char *cj, int len) {
  +static int noCaseMemCmp(const char *ci, const char *cj, int len) {
   	if (0 == memcmp(ci, cj, len)) {
   		return 0;
   	}
  @@ -197,9 +171,9 @@
   /* Case insentive strcmp() clone
    */
   #ifdef HAVE_STRICMP
  -#define NoCaseStrCmp(si, sj) _stricmp((void *) (si), (void *) (sj))
  +#define noCaseStrCmp(si, sj) _stricmp((void *) (si), (void *) (sj))
   #else
  -static int NoCaseStrCmp(const char *si, const char *sj) {
  +static int noCaseStrCmp(const char *si, const char *sj) {
   	if (0 == strcmp(si, sj)) {
   		return 0;
   	}
  @@ -220,7 +194,7 @@
    * 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) {
  +static int scanPath(const char *str, int slen, const char *ptn, int plen) {
   	const char *sp = str;
   
   	while (slen >= plen) {
  @@ -230,7 +204,7 @@
   		 * suspicion that a Windows hosted server might accept URIs
   		 * containing \.
   		 */
  -		if (NoCaseMemCmp(sp, ptn, plen) == 0 &&
  +		if (noCaseMemCmp(sp, ptn, plen) == 0 &&
   			(sp == str || sp[-1] == '\\' || sp[-1] == '/') &&
   			(slen == plen || sp[plen] == '\\' || sp[plen] == '/')) {
   			return 1;
  @@ -258,6 +232,7 @@
   }
   #endif
   
  +#ifdef _DEBUG
   static void _printf(const char *msg, ...) {
   	char buf[512];		/* dangerous fixed size buffer */
   	va_list ap;
  @@ -266,11 +241,12 @@
   	va_end(ap);
   	AddInLogMessageText("Debug: %s", NOERROR, buf);
   }
  +#endif
   
   /* 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) {
  +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;
   
  @@ -287,7 +263,7 @@
   
   /* 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,
  +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;
  @@ -305,18 +281,19 @@
   
   /* 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) {
  +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]))
  +		if (isdigit(buf[0])) {
   			*dest = atoi(buf) != 0;
  -		else if (NoCaseStrCmp(buf, "yes") == 0 || NoCaseStrCmp(buf, "on") == 0)
  +		} else if (noCaseStrCmp(buf, "yes") == 0 || noCaseStrCmp(buf, "on") == 0) {
   			*dest = 1;
  -		else
  +		} else {
   			*dest = 0;
  +		}
   	} else {
   		*dest = dflt;
   	}
  @@ -326,25 +303,25 @@
   	return JK_TRUE;
   }
   
  -/* A couple of utility macros to supply standard arguments to GetVariable() and
  - * GetVariableInt().
  +/* 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))
  +	getVariable(env, s, (name), workBuf, sizeof(workBuf), (dest), (dflt))
   #define GETVARIABLEINT(name, dest, dflt)	\
  -	GetVariableInt(env, s, (name), workBuf, sizeof(workBuf), (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))
  +	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
  + * scanPath() 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 int badURI(const char *uri) {
   	static const char *wi = "web-inf";
  -	return FindPathElem(uri, strlen(uri), wi, strlen(wi));
  +	return scanPath(uri, strlen(uri), wi, strlen(wi));
   }
   
   /* Replacement for strcat() that updates a buffer pointer. It's
  @@ -352,7 +329,7 @@
    * 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) {
  +static void append(char **buf, const char *str) {
   	int l = strlen(str);
   	memcpy(*buf, str, l);
   	(*buf)[l] = '\0';
  @@ -362,7 +339,7 @@
   /* 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) {
  +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) {
  @@ -375,9 +352,9 @@
   	return out;
   }
   
  -/* Like SubStr() but use a static buffer if possible.
  +/* Like subStr() but use a static buffer if possible.
    */
  -static char *MagicSubStr(jk_env_t *env, jk_pool_t *pool, char **bufp, int *bufSz,
  +static char *smartSubStr(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) {
  @@ -389,97 +366,12 @@
   		*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, start, end);
   	}
  -
  -	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) {
  +							struct jk_worker *w, void *context) {
   	return JK_TRUE;
   }
   
  @@ -495,7 +387,7 @@
   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) {
  +	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;
   	}
  @@ -512,12 +404,7 @@
   
   			p->responseStarted = JK_TRUE;
   
  -			if (NULL == s->msg) {
  -				reason = "";
  -			} else {
  -				reason = s->msg;
  -			}
  -
  +			reason = (NULL == s->msg) ? "" : s->msg;
   			hdrCount = s->headers_out->size(env, s->headers_out);
   
   			/* Build a single string containing all the headers
  @@ -538,22 +425,20 @@
   				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, 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);
  +				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); */
  +			frh.responseCode	= s->status;
  +			frh.reasonText		= (char *) reason;
  +			frh.headerText		= hdrBuf;
   
   			/* Send the headers */
   			rc = p->context->ServerSupport(p->context, kWriteResponseHeaders, &frh, NULL, 0, &errID);
  @@ -569,26 +454,26 @@
   /*
    * 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.  
  + * nRead.  
    */
   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"); */
  +							  void *bytes, unsigned len, unsigned *nRead) {
   
  -	if (s && s->ws_private && bytes && actually_read) {
  +	if (s && s->ws_private && bytes && nRead) {
   		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;
  +		if (len > p->reqSize) {
  +			len = p->reqSize;
  +		}
   		memcpy(bytes, p->reqBuffer, len);
   		p->reqBuffer += len;
   		p->reqSize -= len;
  -		*actually_read = len;
  +		*nRead = len;
  +
   		return JK_OK;
   	}
   
  @@ -633,7 +518,7 @@
    * 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) {
  +static int isAbsolutePath(const char *fn) {
   #ifdef WIN32
   	return fn[0] == '\\' || (isalpha(fn[0]) && fn[1] == ':');
   #else
  @@ -641,14 +526,15 @@
   #endif
   }
   
  -static const char *AbsPath(jk_env_t *env, const char *base, const char *name) {
  -	if (base == NULL || IsAbsolute(name)) {
  +static const char *makeAbsolutePath(jk_env_t *env, const char *base, const char *name) {
  +	if (base == NULL || isAbsolutePath(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;
   		}
  @@ -664,7 +550,7 @@
   }
   
   #ifdef WIN32
  -static const char *ReadRegistry(jk_env_t *env, HKEY hkey, const char *key, const char *base) {
  +static const char *readRegistry(jk_env_t *env, HKEY hkey, const char *key, const char *base) {
   	DWORD type = 0;
   	DWORD sz = 0;
   	LONG rc;
  @@ -681,27 +567,32 @@
   
   	rc = RegQueryValueEx(hkey, key, (LPDWORD) 0, &type, val, &sz);
   	if (rc == ERROR_SUCCESS) {
  -		return AbsPath(env, base, val);
  +		return makeAbsolutePath(env, base, val);
   	}
   
   	return NULL;
   }
   #endif
   
  -static int ReadFromRegistry(jk_env_t *env) {
  +static int readFromRegistry(jk_env_t *env) {
   #ifdef WIN32
   	HKEY hkey;
   	long rc;
  +	const char *timeout;
   
   	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);
  +	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);
  +	timeout		= readRegistry(env, hkey, TOMCAT_TIMEOUT_TAG,	NULL);
  +	if (timeout != NULL) {
  +		tomcatTimeout = atoi(timeout);
  +	}
   
   	RegCloseKey(hkey);
   
  @@ -718,27 +609,34 @@
   /* 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)
  +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 makeAbsolutePath(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) {
  +static int readConfigData(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);
  +			const char *timeout;
  +
  +			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);
  +			timeout		= readMap(env, map, TOMCAT_TIMEOUT_TAG,	NULL);
  +
  +			if (timeout != NULL) {
  +				tomcatTimeout = atoi(timeout);
  +			}
   
               iniFileUsed = JK_TRUE;
               return	NULL != serverRoot &&
  @@ -749,14 +647,14 @@
                  "read_registry_init_data, Failed to create map \n");
       }
   
  -	return ReadFromRegistry(env);
  +	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) {
  +static void simpleResponse(FilterContext *context, int status, char *reason, char *body) {
   	FilterResponseHeaders frh;
   	int rc, errID;
   	char hdrBuf[35];
  @@ -774,29 +672,103 @@
   /* 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>";
  +static unsigned int rejectBadURI(FilterContext *context) {
  +	static char *msg = "<html><body><h1>Access is Forbidden</h1></body></html>";
   
  -	SimpleResponse(context, 403, "Forbidden", msg);
  +	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.
  +/* Called to generate a generic error response.
    */
  -static unsigned int RejectWithError(FilterContext *context) {
  +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);
  +	simpleResponse(context, 500, "Error in Filter", msg);
   
   	return kFilterHandledRequest;
   }
   
  +/* 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 = JK_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		= smartSubStr(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;
  +}
  +
   /* Initialize the service structure
    */
  -static int ProcessRequest(struct jk_env *env, jk_ws_service_t *s,
  -					struct jk_worker *w, void *serverObj) {
  +static int processRequest(struct jk_env *env, jk_ws_service_t *s,
  +					struct jk_worker *w, FilterRequest *fr) {
   	/* 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
  @@ -805,19 +777,14 @@
   	 */
   	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);
  +	/* env->l->jkLog(env, env->l, JK_LOG_DEBUG, "processRequest(), s = %p, ws = %p\n", s, ws); */
   
   	s->jvm_route = NULL;
   
  @@ -841,8 +808,8 @@
   	}
   
   	s->method			= methodName[ws->reqData->requestMethod];
  -	s->ssl_cert_len		= fr.clientCertLen;
  -	s->ssl_cert			= fr.clientCert;
  +	s->ssl_cert_len		= fr->clientCertLen;
  +	s->ssl_cert			= fr->clientCert;
   	s->ssl_cipher		= NULL;
   	s->ssl_session		= NULL;
   	s->ssl_key_size		= -1;
  @@ -855,10 +822,9 @@
       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)) {
  +    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;
       }
  @@ -866,6 +832,8 @@
   	if (s->is_ssl) {
   		int i, dummy;
   
  +		/* It seems that Domino doesn't actually expose many of these but we live in hope.
  +		 */
   		char *sslNames[] = {
   			"CERT_ISSUER", "CERT_SUBJECT", "CERT_COOKIE", "CERT_FLAGS", "CERT_SERIALNUMBER",
   			"HTTPS_SERVER_SUBJECT", "HTTPS_SECRETKEYSIZE", "HTTPS_SERVER_ISSUER", "HTTPS_KEYSIZE"
  @@ -893,14 +861,14 @@
   		}
   	}
   
  -	/* Duplicate all the headers now */
  -
  +	/* 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);
  +	hdrCount = parseHeaders(env, s, hdrs, hdrsz);
   
   	return JK_OK;
   }
  @@ -908,7 +876,7 @@
   /* 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) {
  +static unsigned int parsedRequest(FilterContext *context, FilterParsedRequest *reqData) {
   	unsigned int errID;
   	int rc;
   	FilterRequest fr;
  @@ -917,7 +885,7 @@
   	/* TODO: presumably this return code should be checked */
   	rc = context->GetRequest(context, &fr, &errID);
   
  -	if (fr.URL && strlen(fr.URL)) {
  +	if (NONBLANK(fr.URL)) {
   		char *uri = fr.URL;
   		char *qp, *turi;
   	    jk_uriEnv_t *uriEnv = NULL;
  @@ -930,16 +898,16 @@
   		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); */
  +		/* 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);
  +			return rejectWithError(context);
   		}
   
   		serverPort = atoi(buf);
   
   		if (!context->GetServerVariable(context, "SERVER_NAME", buf, sizeof(buf), &errID)) {
  -			return RejectWithError(context);
  +			return rejectWithError(context);
   		}
   
   		serverName = buf;	/* note serverName just aliases buf
  @@ -962,7 +930,7 @@
   	
           rc = jk_requtil_unescapeUrl(turi);
   		if (rc < 0) {
  -			return RejectWithError(context);
  +			return rejectWithError(context);
   		}
   
           jk_requtil_getParents(turi);
  @@ -970,8 +938,8 @@
   			*qp++ = '\0';
   		}
   
  -		if (BadURI(turi)) {
  -			return RejectBadURI(context);
  +		if (badURI(turi)) {
  +			return rejectBadURI(context);
   		}
   
           uriEnv = workerEnv->uriMap->mapUri(env, workerEnv->uriMap, serverName, serverPort, turi);
  @@ -991,7 +959,7 @@
   
   			jk2_requtil_initRequest(env, &s);
   
  -			s.pool					= rPool;		/* Do we need one? */
  +			s.pool					= rPool;
   			s.is_recoverable_error	= JK_FALSE;
   			s.response_started		= JK_FALSE;
   			s.content_read			= 0;
  @@ -1000,11 +968,11 @@
   			s.head					= cbHead;
   			s.read					= cbRead;
   			s.write					= cbWrite;
  -			s.init					= cbInit;
  +			s.init					= cbInit;			/* never seems to be used */
   			s.afterRequest			= cbAfterRequest;
   
               if (workerEnv->options == JK_OPT_FWDURICOMPATUNPARSED) {
  -				s.req_uri = StrDup(env, rPool, uri);
  +				s.req_uri = env->globalPool->pstrdup(env, rPool, libFileName);
   				/* Find the query string again in the original URI */
   				if (qp = strchr(s.req_uri, '?'), NULL != qp) {
   					*qp++ = '\0';
  @@ -1012,7 +980,7 @@
               } else if (workerEnv->options == JK_OPT_FWDURIESCAPED) {
   				/* Nasty static buffer */
   				char euri[256];
  -				if (jk_requtil_escapeUrl(turi, euri, sizeof(euri))) {
  +				if (jk_requtil_escapeUrl(turi, buf, sizeof(euri))) {
   					turi = euri;
   				}
   				s.req_uri = turi;
  @@ -1020,19 +988,19 @@
   				s.req_uri = turi;
               }
   
  -			s.query_string			= qp;
  +			s.query_string		= qp;
   
   			/* Init our private structure
   			 */
  -			ws.responseStarted		= JK_FALSE;
  -			ws.context				= context;
  -			ws.reqData				= reqData;
  +			ws.responseStarted	= JK_FALSE;
  +			ws.context			= context;
  +			ws.reqData			= reqData;
   
   			/* Fetch info about the request
   			 */
  -			ws.reqSize = context->GetRequestContents(context, &ws.reqBuffer, &errID);
  +			ws.reqSize			= context->GetRequestContents(context, &ws.reqBuffer, &errID);
   
  -			rc = ProcessRequest(env, &s, worker, context);
  +			rc = processRequest(env, &s, worker, &fr);
   			if (JK_OK == rc) {
   				rc = worker->service(env, uriEnv->worker, &s);
   			}
  @@ -1045,8 +1013,6 @@
   				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);
   		}
  @@ -1057,25 +1023,12 @@
   	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) {
  +static int runProg(const char *cmd) {
   #ifdef WIN32
       STARTUPINFO si;
       PROCESS_INFORMATION pi;
   
  -	ZeroMemory(&si, sizeof(si));
  +	memset(&si, 0, sizeof(si));
       si.cb			= sizeof(si);    // Start the child process.
   	si.dwFlags		= STARTF_USESHOWWINDOW;
   	si.wShowWindow	= SW_SHOWMAXIMIZED;
  @@ -1083,16 +1036,15 @@
   	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;
  +		return JK_FALSE;
   	}
   
  -	if (WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, TOMCAT_STARTSTOP_TO)) {
  -		return TRUE;
  +	if (WAIT_OBJECT_0 == WaitForSingleObject(pi.hProcess, tomcatTimeout)) {
  +		return JK_TRUE;
   	}
   
   	AddInLogMessageText("Command \"%s\" didn't complete in time", NOERROR, cmd);
  -	return FALSE;
  -
  +	return JK_FALSE;
   #else
   	int err = system(cmd);
   	if (0 == err) {
  @@ -1103,6 +1055,19 @@
   #endif
   }
   
  +/* 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;
  +}
  +
   /* Called when the filter is unloaded. Free various resources and
    * display a banner.
    */
  @@ -1117,13 +1082,12 @@
           }
   
   		isInited = JK_FALSE;
  -
   	}
   
   #ifndef TESTING
  -	if (NULL != tomcatStop && '\0' != *tomcatStop) {
  +	if (NONBLANK(tomcatStop)) {
   		AddInLogMessageText("Attempting to stop Tomcat: %s", NOERROR, tomcatStop);
  -		RunProg(tomcatStop);
  +		runProg(tomcatStop);
   	}
   #endif
   
  @@ -1154,17 +1118,17 @@
   
   	lstrcpyn(libFileName, info.dli_fname, sizeof(libFileName)-1);
   	lstrcpyn(iniFileName, info.dli_fname, sizeof(libFileName)-1);
  -	char *slash = strrchr(iniFileName, PATHSEP);
  +	slash = strrchr(iniFileName, PATHSEP);
   	if (NULL == slash) {
   		slash = iniFileName;
   	} else {
   		slash++;
   	}
  -	char *dot = strrchr(slash, '.');
  +	dot = strrchr(slash, '.');
   	if (NULL == dot) {
   		dot = slash + strlen(slash);
   	}
  -	lstrcpyn(slash, ".properties", (iniFileName + sizeof(iniFileName) - 1) - slash);
  +	lstrcpyn(slash, PROPERTIES_EXT, (iniFileName + sizeof(iniFileName) - 1) - slash);
   #endif
   
       apr_initialize();
  @@ -1185,10 +1149,6 @@
       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);
   
  @@ -1201,9 +1161,6 @@
   	 */
       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", "");
  @@ -1217,7 +1174,7 @@
   
       workerEnv->childId = 0;
   
  -	if (!ReadInitData(env)) {
  +	if (!readConfigData(env)) {
   		goto initFailed;
   	}
   
  @@ -1228,7 +1185,6 @@
   
   	/* 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;
  @@ -1239,16 +1195,16 @@
   #ifndef TESTING
   	/* Attempt to launch Tomcat
   	 */
  -	if (NULL != tomcatStart && '\0' != *tomcatStart) {
  +	if (NONBLANK(tomcatStart)) {
   		AddInLogMessageText("Attempting to start Tomcat: %s", NOERROR, tomcatStart);
  -		RunProg(tomcatStart);
  +		runProg(tomcatStart);
   	}
   #endif
   
  -	filterInitData->appFilterVersion = kInterfaceVersion;
  -	filterInitData->eventFlags = kFilterParsedRequest;
  -	strcpy(filterInitData->filterDesc, FILTERDESC);
  +	filterInitData->appFilterVersion	= kInterfaceVersion;
  +	filterInitData->eventFlags			= kFilterParsedRequest;
   
  +	lstrcpyn(filterInitData->filterDesc, FILTERDESC, sizeof(filterInitData->filterDesc));
   	isInited = JK_TRUE;
   
   	/* Display banner
  @@ -1274,10 +1230,9 @@
   
   	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");
  +			_makepath(iniFileName, drive, dir, fname, PROPERTIES_EXT);
   		} else {
   			fReturn = FALSE;
   		}
  @@ -1294,6 +1249,6 @@
    */
   void TestMain(void) {
   	strcpy(libFileName, "test.exe");
  -	strcpy(iniFileName, "test.properties");
  +	strcpy(iniFileName, "test" PROPERTIES_EXT);
   }
   #endif
  
  
  
  1.2       +2 -1      jakarta-tomcat-connectors/jk/native2/server/dsapi/dsapi_redirector2.reg
  
  Index: dsapi_redirector2.reg
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native2/server/dsapi/dsapi_redirector2.reg,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- dsapi_redirector2.reg	13 Nov 2003 17:10:56 -0000	1.1
  +++ dsapi_redirector2.reg	14 Nov 2003 13:08:05 -0000	1.2
  @@ -2,6 +2,7 @@
   
   [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"
  +"workersFile"="conf\\workers2.properties"
   "tomcatStart"="bin\\startup.bat"
   "tomcatStop"="bin\\shutdown.bat"
  +"tomcatTimeout"="30000"
  
  
  
  1.2       +6 -4      jakarta-tomcat-connectors/jk/native2/server/dsapi/dsapi.dsp
  
  Index: dsapi.dsp
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native2/server/dsapi/dsapi.dsp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- dsapi.dsp	13 Nov 2003 17:10:56 -0000	1.1
  +++ dsapi.dsp	14 Nov 2003 13:08:05 -0000	1.2
  @@ -56,7 +56,8 @@
   # 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"
  +# ADD LINK32 libapr.lib libaprutil.lib ws2_32.lib wsock32.lib advapi32.lib notes.lib libpcre.dll.a libpcreposix.dll.a /nologo /dll /machine:I386 /out:"Release/dsapi_redirector2.dll" /libpath:"..\..\..\..\..\apr\Release" /libpath:"..\..\..\..\..\pcre\lib" /libpath:"..\..\..\..\..\apr-util\Release" /libpath:"$(NOTESAPI)\lib\mswin32"
  +# SUBTRACT LINK32 /nodefaultlib
   
   !ELSEIF  "$(CFG)" == "dsapi - Win32 Debug"
   
  @@ -83,7 +84,7 @@
   # 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"
  +# ADD LINK32 libapr.lib libaprutil.lib ws2_32.lib wsock32.lib advapi32.lib notes.lib libpcre.dll.a libpcreposix.dll.a /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"
  @@ -113,7 +114,7 @@
   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"
  +# ADD LINK32 apr.lib aprutil.lib ws2_32.lib wsock32.lib advapi32.lib libpcre.a libpcreposix.a notes.lib /nologo /dll /debug /machine:I386 /out:"DebugS/dsapi_redirector2.dll" /pdbtype:sept /libpath:"..\..\..\..\..\pcre\lib" /libpath:"..\..\..\..\..\apr\LibR" /libpath:"..\..\..\..\..\apr-util\LibR" /libpath:"..\..\..\..\..\apr-iconv\LibR" /libpath:"$(NOTESAPI)\lib\mswin32"
   # SUBTRACT LINK32 /nodefaultlib
   
   !ELSEIF  "$(CFG)" == "dsapi - Win32 Release Static"
  @@ -142,7 +143,8 @@
   # 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"
  +# ADD LINK32 apr.lib aprutil.lib ws2_32.lib wsock32.lib advapi32.lib libpcre.a libpcreposix.a notes.lib /nologo /dll /machine:I386 /out:"ReleaseS/dsapi_redirector2.dll" /libpath:"..\..\..\..\..\pcre\lib" /libpath:"..\..\..\..\..\apr\LibR" /libpath:"..\..\..\..\..\apr-util\LibR" /libpath:"..\..\..\..\..\apr-iconv\LibR" /libpath:"$(NOTESAPI)\lib\mswin32"
  +# SUBTRACT LINK32 /nodefaultlib
   
   !ENDIF 
   
  
  
  
  1.2       +32 -1     jakarta-tomcat-connectors/jk/native2/server/dsapi/config.h
  
  Index: config.h
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native2/server/dsapi/config.h,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- config.h	13 Nov 2003 17:10:56 -0000	1.1
  +++ config.h	14 Nov 2003 13:08:05 -0000	1.2
  @@ -67,6 +67,9 @@
   #define MAKEVERSION(a, b, c, d) \
   	(((a) << 24) + ((b) << 16) + ((c) << 8) + (d))
   
  +#define NONBLANK(s) \
  +	(NULL != (s) && '\0' != *(s))
  +
   /* the _memicmp() function is available */
   #if defined(WIN32)
   
  @@ -93,7 +96,35 @@
    */
   /* #undef NO_CAPI */
   
  +#ifdef _DEBUG
   #define DEBUG(args) \
   	do { _printf args ; } while (0)
  +#else
  +#define DEBUG(args) \
  +	do { } while (0)
  +#endif
  +
  +#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 TOMCAT_TIMEOUT_TAG	"tomcatTimeout"
  +#define VERSION				"2.0.0"
  +#define VERSION_STRING		"Jakarta/DSAPI/" VERSION
  +#define FILTERDESC			"Apache Tomcat Interceptor (" VERSION_STRING ")"
  +#define SERVERDFLT			"Lotus Domino"
  +#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 */
  +#define PROPERTIES_EXT		".properties"
   
   #endif /* __config_h */
  
  
  
  1.1                  jakarta-tomcat-connectors/jk/native2/server/dsapi/INSTALL.txt
  
  Index: INSTALL.txt
  ===================================================================
  $Id: INSTALL.txt,v 1.1 2003/11/14 13:08:05 andya Exp $
  
  Installing the Domino Redirector
  --------------------------------
  
  If necessary build dsapi_redirector2.dll as per the instructions in
  BUILD.txt. Copy the DLL into the Domino program directory (this is the
  directory, which may be called something like C:\Lotus\Domino, that
  contains a file called nlnotes.exe). Shortly we will tell Domino where
  to find this file, but before we do that we need to make some registry
  entries. The simplest way is to edit the supplied file
  dsapi_redirector2.reg, which initially will look like this
  
      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\\workers2.properties"
      "tomcatStart"="bin\\startup.bat"
      "tomcatStop"="bin\\shutdown.bat"
      "tomcatTimeout"="30000"
  
  Change serverRoot to reflect the location of your Tomcat installation.
  The other filename parameters can either be relative to serverRoot or
  absolute paths. Once edited double click on dsapi_redirector2.reg to
  enter it into the registry.
  
  Automatically Starting Tomcat
  -----------------------------
  
  The last three registry entries above provide commands that the
  redirector DLL will use to start and stop Tomcat when the Domino http
  server starts and stops respectively. If you don't require this
  behaviour these two lines can be omitted (or deleted if you've already
  placed them in the registry).
  
  The Workers File
  ----------------
  
  If necessary take the sample workers2.properties file from jakarta-
  tomcat- connectors\jk\conf and place it in the location specified in the
  registry settings above (typically the conf directory of your Tomcat
  installation). Edit the file to suit your Tomcat setup.
  
  Configuring Domino
  ------------------
  
  Finally we need to configure Domino to use the DSAPI extension DLL. For
  those who are unfamiliar with Domino server configuration most of a
  server's configurable behavior is dictated by a document called the
  "server document" in a database called the "Public Name and Address
  Book" or "NAB" for short (N.B. Lotus have renamed the NAB to "Domino
  Directory" from Domino 5 onwards). Each Domino server will have a NAB
  (called names.nsf) and each NAB will have a number of server documents
  including one for the current server. If you have not previously
  configured a Domino server you may need to refer to the supplied
  documentation, or you may need to pass this document to your tame Domino
  administrator.
  
  Assuming you know your way around a Domino server document what we're
  going to do is actually quite simple. Open the server document for this
  server, place it in Edit mode, then locate the DSAPI section and the
  'DSAPI filter file names' field on the Internet Protocols tab, HTTP sub-
  tab. Add "dsapi_redirector2.dll" to the DSAPI field, then save and close
  the document.
  
  Restart Domino
  --------------
  
  In order to get these settings to take effect and make sure that you
  haven't disrupted anything else you should now restart the Domino
  server. If the server is running as a service and you have changed any
  relevant system variables (JAVA_HOME, TOMCAT_HOME, CLASSPATH) since the
  last time you restarted the computer you should do a complete restart
  now because updates to system variables are not seen by services until
  after a reboot. If all goes well you should see something like this on
  the server console when the web server starts up.
  
      14/11/2003 13:02:18   Attempting to start Tomcat: D:\Works\Tomcat\jakarta-tomcat-4.1.27\bin\startup.bat
      Using CATALINA_BASE:   D:\Works\Tomcat\jakarta-tomcat-4.1.27
      Using CATALINA_HOME:   D:\Works\Tomcat\jakarta-tomcat-4.1.27
      Using CATALINA_TMPDIR: D:\Works\Tomcat\jakarta-tomcat-4.1.27\temp
      Using JAVA_HOME:       C:\JBuilder8\jdk1.4
      14/11/2003 13:02:18   Apache Tomcat Interceptor (Jakarta/DSAPI/2.0.0) loaded
      14/11/2003 13:02:19   HTTP Web Server started
  
  At about the same time Tomcat should open in a new window (assuming you
  enabled the autostart option in the registry settings). You should now
  be able to visit a URL that is handled by Tomcat. Something like
  
      http://name-of-server/servlet/SnoopServlet
  
  may be available, depending on how Tomcat is configured. If that all
  works you're done ;-)
  
  Please let me know if you have any problems.
  
  Andy Armstrong, <an...@tagish.com>
  
  
  
  1.1                  jakarta-tomcat-connectors/jk/native2/server/dsapi/BUILD.txt
  
  Index: BUILD.txt
  ===================================================================
  $Id: BUILD.txt,v 1.1 2003/11/14 13:08:05 andya Exp $
  
  Building the Domino Redirector
  ------------------------------
  
  This release currently only builds on Windows using MSVC 6.0. As soon as
  I can I'll test it on Linux and produce a Makefile and I also hope to
  get it to build under CygWin.
  
  Prerequisites
  -------------
  
  You need to be able to build the jk2 code which requires both APR and
  PCRE. You can get a suitable Win32 build of APR from here:
  
    http://apr.apache.org/
    
  and a Win32 version of PCRE can be found here:
  
    http://gnuwin32.sourceforge.net/packages/pcre.htm
    
  To avoid messing around with the paths in the MSVC project place the APR
  and PCRE directories in the same parent directory as jakarta-tomcat-
  connectors. Here's what I have
  
  tomcat\
      apr\
      apr-iconv\
      apr-util\
      jakarta-tomcat-connectors\
      pcre\
  
  By default the project also depends on the Lotus Notes C API which can
  be downloaded here:
  
    http://www-10.lotus.com/ldd/toolkits
    
  If you're using the C API set the environment variable NOTESAPI to the
  directory where you've installed it. You can reconfigure the project not
  to depend on the API. To do that remove references to NOTESAPI from the
  compiler and linker settings and add the preprocessor directive NO_CAPI.
  The only current implication of doing this is that messages from the
  redirector will be displayed using printf() rather than Notes API for
  displaying messages on the server console.
  
  You'll also need to have a suitable (for jk2) JVM installed and
  JAVA_HOME properly set.
  
  Finally there's a header file which we can't currently redistribute with
  the redirector although I'm trying to get IBM to clear it for release.
  It's the header that describes the DSAPI interface. For now you should
  get a copy of the header here:
  
    http://www-12.lotus.com/ldd/doc/domino_notes/5.0/readme.nsf/0/
     528b461a3cdc2a798525677400499305?OpenDocument
  
  and save it as dsapifilter.h in the dsapi directory (join the two parts
  of the above URL back together).
  
  Once you've done all that you should be able to fire up MSVC, open the
  dsapi.dsw and build it. You'll most likely want to build the
  configuration 'Release Static' which will build a standalone
  dsapi_redirector2.dll.
  
  Please let me know if you have any problems.
  
  Andy Armstrong, <an...@tagish.com>
  
  
  

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